fix(audit): corrige errores criticos y mayores, mejora UX/accesibilidad y optimiza rendimiento
Some checks failed
CI / lint-and-test (3.11) (push) Has been cancelled
CI / lint-and-test (3.13) (push) Has been cancelled

- Arregla @require_auth, permisos, race conditions, locks de caja/stock
- Elimina N+1 en layaway, flotilla, dashboard y global_invoice
- Asegura folios atomicos para CFDI, ordenes de servicio y polizas
- Protege client_secret de MercadoLibre en backend
- Conecta botones/filtros de config, customers, accounting e invoicing
- Mejora accesibilidad (labels/aria-label) y estados de carga/vacio
- Limpia accounting.js obsoleto y consolida accounting.v9.js
- Actualiza cache busting a v32 y Service Worker a v32
- Documenta todo en docs/AUDIT_Y_MEJORAS_2026-06-15.md

Tests: 35 passed
This commit is contained in:
2026-06-29 23:54:58 +00:00
parent 59a4893e84
commit 2bdeb2973a
61 changed files with 2879 additions and 706 deletions

View File

@@ -11,6 +11,7 @@ Tax: 16% IVA per item (from item.tax_rate field).
from datetime import datetime, timedelta
from decimal import Decimal, ROUND_HALF_UP
import threading
from flask import g
from services.audit import log_action
from services.inventory_engine import (
@@ -223,9 +224,9 @@ def process_sale(conn, sale_data):
if not items:
raise ValueError("No items in sale")
# Validate register is open
# Validate register is open and lock it to prevent concurrent close/sale races
if register_id:
cur.execute("SELECT status FROM cash_registers WHERE id = %s", (register_id,))
cur.execute("SELECT status FROM cash_registers WHERE id = %s FOR UPDATE", (register_id,))
reg = cur.fetchone()
if not reg or reg[0] != 'open':
raise ValueError("Cash register is not open")
@@ -249,6 +250,17 @@ def process_sale(conn, sale_data):
# Batch stock check
stock_map = get_stock_bulk(conn, branch_id)
# Lock per-branch stock rows and refresh stock map to prevent overselling
# on concurrent sales of the same items.
if branch_id:
cur.execute("""
SELECT inventory_id, stock
FROM inventory_stock
WHERE branch_id = %s AND inventory_id = ANY(%s)
FOR UPDATE
""", (branch_id, inv_ids))
stock_map = {r[0]: r[1] for r in cur.fetchall()}
# Validate and enrich items
enriched_items = []
for item in items: