fix(audit): corrige errores criticos y mayores, mejora UX/accesibilidad y optimiza rendimiento
- 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:
140
docs/AUDIT_Y_MEJORAS_2026-06-15.md
Normal file
140
docs/AUDIT_Y_MEJORAS_2026-06-15.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Auditoría y Mejoras del Sistema Nexus POS — 15 de junio de 2026
|
||||
|
||||
## Resumen ejecutivo
|
||||
|
||||
Se realizó una revisión completa del sistema Nexus POS enfocada en corregir errores críticos y mayores, eliminar código muerto, cerrar brechas de seguridad menores y estandarizar la experiencia de usuario. También se aplicaron optimizaciones de rendimiento en consultas frecuentes y se mejoró la accesibilidad de los formularios.
|
||||
|
||||
- **Rama/base:** `main`
|
||||
- **Tenant de pruebas:** `tenant_refaccionaria_la_casita` (`tenant_id = 33`)
|
||||
- **Servicio:** `nexus-pos.service` (puerto 5001)
|
||||
- **Estado final:** operativo, tests pasando
|
||||
|
||||
---
|
||||
|
||||
## 1. Problemas críticos corregidos
|
||||
|
||||
| Problema | Solución | Archivos principales |
|
||||
|----------|----------|----------------------|
|
||||
| `@require_auth` sin paréntesis en `tasks_bp` | Se cambió al decorador correcto | `pos/blueprints/tasks_bp.py` |
|
||||
| Permiso inexistente `accounting.read` | Se reemplazó por `accounting.view` | `pos/blueprints/accounting_bp.py` |
|
||||
| `historical_sales.html` no cargaba `api.js` | Se incluyó el helper compartido | `pos/templates/historical_sales.html`, `pos/static/js/api.js` |
|
||||
| `featureProximamente` no estaba disponible en `customers.js` | Se expuso la función en el módulo | `pos/static/js/customers.js` |
|
||||
| `pos_engine` usaba `threading` sin importar y la caja sin `FOR UPDATE` | Se agregó `import threading` y lock pesimista de caja | `pos/services/pos_engine.py` |
|
||||
| Race condition en stock de ventas | Se agregó `SELECT ... FOR UPDATE` sobre `inventory_stock` | `pos/services/pos_engine.py` |
|
||||
|
||||
---
|
||||
|
||||
## 2. Problemas mayores corregidos
|
||||
|
||||
| Problema | Solución | Archivos principales |
|
||||
|----------|----------|----------------------|
|
||||
| N+1 en `complete_layaway` | Se cargan todos los items en una sola consulta | `pos/services/pos_engine.py` |
|
||||
| Race conditions en folios CFDI y números de póliza | Se usó `pg_advisory_xact_lock(hashtext(prefix))` | `pos/services/cfdi_queue.py`, `pos/services/accounting_engine.py` |
|
||||
| N+1 en flotilla (schedules/history) | Se crearon endpoints bulk `/vehicles/schedules` y `/vehicles/history` | `pos/blueprints/fleet_bp.py`, `pos/static/js/fleet.js` |
|
||||
| N+1 en dashboard (ventas recientes) y `global_invoice` | Se consolidaron consultas | `pos/blueprints/dashboard_stats_bp.py`, `pos/services/global_invoice.py` |
|
||||
| `client_secret` de MercadoLibre expuesto en frontend | Se movió el flujo OAuth a backend con endpoint `/connect/init` | `pos/blueprints/marketplace_external_bp.py`, `pos/static/js/marketplace_external.js` |
|
||||
| Botones/filtros sin handler en config, customers y accounting | Se conectaron eventos y handlers faltantes | `pos/static/js/config.js`, `pos/static/js/customers.js`, `pos/static/js/accounting.v9.js`, `pos/templates/*.html` |
|
||||
| Botones/filtros sin handler en invoicing | Se implementaron filtros, export CSV y acciones | `pos/static/js/invoicing.js`, `pos/templates/invoicing.html` |
|
||||
|
||||
---
|
||||
|
||||
## 3. Mejoras de rendimiento
|
||||
|
||||
- **Locks atómicos:** los folios de órdenes de servicio, CFDI y pólizas contables ahora se generan bajo `pg_advisory_xact_lock` para evitar duplicados bajo concurrencia.
|
||||
- **Consultas bulk:** flotilla y dashboard redujeron drásticamente el número de queries al backend.
|
||||
- **Virtual scroll:** se mantiene en tablas grandes (clientes, programas de mantenimiento, historial) para renderizado eficiente.
|
||||
- **Cache busting:** se actualizaron los query strings estáticos a `?v=32` y el Service Worker a `v32` para forzar la actualización de assets en navegadores y PWA.
|
||||
|
||||
---
|
||||
|
||||
## 4. Mejoras de UX y accesibilidad
|
||||
|
||||
- **Formularios accesibles:** se agregaron `aria-label`, `id` y `<label>` explícitos en:
|
||||
- POS: pago mixto, toggle de costo/margen, campos de vehículo del modal de cliente.
|
||||
- Clientes: búsqueda y filtros.
|
||||
- Catálogo: búsqueda y filtro de niveles.
|
||||
- Facturación: búsquedas de facturas, notas de crédito y complementos de pago.
|
||||
- **Estados de carga consistentes:** se añadió `renderLoadingState()` en `pos-utils.js` con estilo en `pos-ui.css`, y se aplicó en:
|
||||
- Clientes (`customers.js`)
|
||||
- Facturación (`invoicing.js`)
|
||||
- Flotilla (`fleet.js`): vehículos, programas, historial y alertas.
|
||||
- **Empty states normalizados:** los errores y listas vacías ahora usan `renderEmptyState()` en lugar de mensajes inline inconsistentes.
|
||||
|
||||
---
|
||||
|
||||
## 5. Limpieza de código
|
||||
|
||||
- Se eliminaron las versiones obsoletas `pos/static/js/accounting.js` y `pos/static/js/accounting.min.js`.
|
||||
- Se consolidó la lógica contable en `pos/static/js/accounting.v9.js`.
|
||||
- Se removieron `console.log`/`console.error` de depuración de `accounting.v9.js`.
|
||||
- Se limpió encabezado comentado de `accounting.v9.js`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Archivos añadidos
|
||||
|
||||
```text
|
||||
pos/migrations/v4.10_fleet_permissions.sql
|
||||
pos/migrations/v4.7_workshop_business.sql
|
||||
pos/migrations/v4.8_workshop_permissions.sql
|
||||
pos/migrations/v4.9_workshop_customers_view.sql
|
||||
pos/static/js/accounting.v9.js
|
||||
pos/static/js/api.js
|
||||
scripts/allocate_existing_customer_payments.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Estadísticas del cambio
|
||||
|
||||
```text
|
||||
54 archivos modificados
|
||||
+2485 / -1300 líneas aproximadas
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Validación
|
||||
|
||||
```bash
|
||||
# Sintaxis de JavaScript
|
||||
node --check pos/static/js/pos-utils.js
|
||||
node --check pos/static/js/customers.js
|
||||
node --check pos/static/js/invoicing.js
|
||||
node --check pos/static/js/fleet.js
|
||||
node --check pos/static/js/accounting.v9.js
|
||||
node --check pos/static/js/pos.js
|
||||
node --check pos/static/js/catalog.js
|
||||
|
||||
# Tests de backend
|
||||
python3 -m pytest pos/tests/test_service_order_integration.py \
|
||||
pos/tests/test_bulk_import.py \
|
||||
pos/tests/test_facturapi_service.py -q
|
||||
# Resultado: 35 passed
|
||||
```
|
||||
|
||||
Servicio `nexus-pos.service` verificado como **activo**.
|
||||
|
||||
---
|
||||
|
||||
## 9. Instrucciones de despliegue
|
||||
|
||||
1. Aplicar migraciones SQL nuevas según el orden numérico:
|
||||
- `v4.7_workshop_business.sql`
|
||||
- `v4.8_workshop_permissions.sql`
|
||||
- `v4.9_workshop_customers_view.sql`
|
||||
- `v4.10_fleet_permissions.sql`
|
||||
2. Reiniciar el servicio para cargar cambios de backend:
|
||||
```bash
|
||||
sudo systemctl restart nexus-pos.service
|
||||
```
|
||||
3. Refrescar la PWA en los navegadores/clientes para que `sw.js` actualice el cache a `v32`.
|
||||
|
||||
---
|
||||
|
||||
## 10. Notas para el equipo
|
||||
|
||||
- Los permisos de flotilla (`fleet.view/create/edit/delete`) ya están sembrados para `owner`/`admin` y `view` para `accountant`/`workshop`.
|
||||
- El Service Worker se sirve correctamente en `/pos/sw.js` desde `static/pwa/sw.js`.
|
||||
- El helper global `api()` fue creado para páginas standalone como `historical_sales.html`.
|
||||
- No se realizaron mutaciones de git no solicitadas; el push a Gitea se hace como parte de esta entrega.
|
||||
Reference in New Issue
Block a user