Deportes Campeón — Punto de venta
Contexto
Sistema de punto de venta para el cliente personal Deportes Campeón (negocio de artículos deportivos). Cliente personal de Sergio, no facturado vía Electrosystems.
Estado real: activo en uso pero sin movimiento reciente de desarrollo. Hay requerimientos pendientes que Sergio quiere reanudar.
Tareas pendientes
- (2026-05-27) #263 Mensaje enviado al cliente con el diagnóstico del bug de folios duplicados (Variante A — cercana, menciona ambos casos folio 371 ene 20 + folio 2561 may 15, ambos limpios + fix aplicado). Confirmado por Sergio en sesión multi-proyecto 2026-05-27.
- #093 📅 2026-06-08 — Recopilar / revisar la lista de requerimientos pendientes del cliente (no documentados aquí todavía — Sergio los irá dictando o pegará referencias).
- #094 📅 2026-06-12 — Reanudar trabajo activo en el proyecto.
- Resuelto 2026-05-15: bug de folios duplicados — diagnóstico, fix, tests, deploy y verificación. UNIQUE aplicado en prod (batch 13). Ver bitácora del día.
En progreso
(Nada activo. Proyecto en pausa de facto.)
Notas técnicas
Stack
- Laravel + Inertia + Vue (composer + package.json detectados; sin
ANTIGRAVITY.mdque confirme versiones). - Asume Laravel Sail si sigue la convención del resto de proyectos PHP de Sergio. Verificar con
composer.jsonydocker-compose.ymlcuando se reanude.
Pendiente de documentar aquí
- Versión de Laravel/PHP en uso.
- Cuál es el setup de despliegue actual.
- Lista concreta de requerimientos pendientes del cliente.
Bug — duplicidad de folio (2026-05-14)
Reporte del cliente:
Buenas tardes Sergio. En relación a la foto, si te fijas en la operación con folio 371 que aparece ahí, se presenta una duplicidad de la operación, pero con el mismo folio. Anteriormente nos había sucedido que se presentara una duplicidad, es decir una operación a la misma hora, misma mercancía etc., pero con folio diferente. Lo arreglo atribuimos a que dábamos un doble click en el mouse al aplicar la venta y no nos dábamos cuenta que lo marcabamos 2 veces. Pero cuando esto pasaba, eran dos folios distintos. Nos parece muy extraño que el sistema esté generando las duplicidades con el mismo folio. Podrías revisarlo por favor.
Evidencia: deportescampeon-assets/2026-05-14-falla-folio-371-duplicado.jpeg
- Fila 20 y 21 del listado, ambas con:
- Fecha: 20 ene 2026 08:23 p.m.
- Usuario: el mismo (cajera de tienda — no nombrar en código).
- Artículo:
7501499411016 ESPINILLERA FUTBOLINFANTIL ADX REBEL AZUL REY - 0912CL UNIFORME FUTBOL CL TODOS EQUIPOS ADULTO. - Folio: 371 (idéntico).
- Monto: $724.00.
Hipótesis a verificar mañana (orden de probabilidad):
-
Listado duplica visualmente un único registro (problema de query, no de datos):
- Posible JOIN sin
DISTINCTque multiplica filas (p. ej.ventas⋈venta_detallecuando la venta tiene 2 líneas). - El monto y artículo iguales sugieren UNA línea de detalle, pero podría haber un segundo registro relacionado (descuento, comisión, etc.) que duplica el row.
- Test:
SELECT COUNT(*) FROM ventas WHERE folio = 371en prod. Si devuelve 1 → bug de UI/listado. Si devuelve 2 → bug de datos.
- Posible JOIN sin
-
Race condition al generar folio (si la BD permite duplicados):
- El siguiente folio se calcula como
MAX(folio)+1sin lock/UNIQUE constraint → doble click en la cajera dispara dos INSERTs simultáneos que leen el mismo MAX. - Test: ver
migrationsySHOW CREATE TABLE ventaspara confirmar sifoliotieneUNIQUE. Ver cómo se asignafolioen el código (controller/service del POST de venta).
- El siguiente folio se calcula como
-
Cambio reciente al constraint o al generador de folio introducido en algún commit posterior al fix histórico del doble-click.
- Test:
git log -psobre archivos de venta/folio.
- Test:
Plan para mañana (no destructivo en prod):
- Read-only en BD de producción: verificar si hay 1 o 2 rows con folio 371; revisar schema de la columna; revisar últimos 20-50 folios para detectar otros casos.
- Revisar código de creación de venta y generación de folio.
- Confirmar diagnóstico con Sergio antes de cualquier fix.
- Si hipótesis 2: agregar
UNIQUEaventas.folio+ envolver el insert en transacción conSELECT ... FOR UPDATEo usar contador atómico (UPDATE counters SET val=val+1). - Si hipótesis 1: arreglar el query del listado con
DISTINCTo GROUP BY correcto.
Bitácora
2026-05-15
- Pidió Sergio: investigar y arreglar el bug de folios duplicados reportado el 2026-05-14. Implementar + tests + commit (sin deploy). Acceso autorizado por SSH alias
deportescampeon(root, dir/opt/deportescampeon, BDdeportescampeon). - Diagnóstico (read-only en código + BD prod):
- Causa raíz:
SalesController::storecalculabafiscal_folio = MAX+1sin lock y la columna sólo tenía unKEY (branch_id, fiscal_folio), noUNIQUE. Doble click → dos POSTs simultáneos que leen el mismo MAX → ambos hacen INSERT con el mismo folio. - Por qué antes (con doble-click) sí salían folios distintos: antes el “folio” era el
idauto-increment de Laravel (atómico). La migración2025_12_29_235330_add_fiscal_folio_to_sales_table.phpintrodujofiscal_foliocalculado en código → cambió el comportamiento. - Línea de tiempo del caso de la foto: 2026-01-20 19:23:04 INSERT duplicado (
id=106269+id=106270, folio 371, sucursal 6). 19:33 captura del cliente. 19:38:12 alguien soft-deleteaid=106270. El cliente nos reenvió la foto el 2026-05-14 porque al revisar histórico se dio cuenta que los folios eran idénticos. - Alcance: 1 solo caso en 4.5 meses; ya estaba limpio en BD (soft-deleted). Cero pares duplicados activos al 2026-05-15.
- Por qué del doble click: el botón “Finalizar” en
Sales/Create.vueno usaba:disabled="form.processing", así que la cajera podía disparar 2 POSTs antes de que el primero respondiera.
- Causa raíz:
- Hice (2 commits a
master, sin push):7aefde6(infra): la suite de tests estaba rota desde la upgrade a Laravel 11 (CreatesApplicationtrait removido peroTestCaselo seguía usando,phpunit.xmlconDB_DATABASE=testingapuntando a archivo inexistente,UserFactoryconemail_verified_atque no existe enusers, migraciones de variables creando con Eloquent un modelo que usaLogsActivityantes de que existaactivity_log). Mínimo necesario para correr tests.b4ab0f2(fix): migración que limpia el row 106270 (y sus sale_products / payments) + reemplaza el KEY por UNIQUE;SalesController::storecon retry loop catchandoUniqueConstraintViolationException(tope 5), MAX ahora cuenta soft-deleted para no reutilizar folios emitidos;Sales/Create.vuedeshabilita el botón cuandoform.processing; 3 tests nuevos (test_fiscal_folio_is_sequential_per_branch,test_fiscal_folio_unique_constraint_blocks_direct_duplicate,test_store_retries_when_folio_collides_and_assigns_next_folio). Los 3 pasan; el suite tiene 5/8 verdes enSalesTest— los 3 que fallan son pre-existentes (mismatchidvsproduct_iden payload de tests viejos, Inertia view que no carga).
- Falta:
- Deploy a producción (revisión +
git push+migrate+ recompilar assets). - Responderle al cliente con el diagnóstico.
- Aprovechar la apertura del proyecto para recopilar requerimientos pendientes.
- Deploy a producción (revisión +
2026-05-14
- Pidió Sergio: apuntar para mañana 2026-05-15 el reporte del cliente sobre duplicidad de venta con MISMO folio (folio 371). Pasó foto y mensaje literal.
- Hice:
- Vi la foto: confirmé visualmente que filas 20 y 21 tienen folio 371 idénticos, mismo timestamp, mismo artículo, mismo monto.
- Copié la evidencia a
projects/deportescampeon-assets/2026-05-14-falla-folio-371-duplicado.jpeg(la ruta original enC:\Users\sevao\Downloads\es volátil). - Documenté reporte literal del cliente + 3 hipótesis a verificar (UI duplica vs race condition vs cambio reciente) + plan de mañana read-only en prod.
- Falta: ejecutar el diagnóstico mañana. Sergio confirma si quiere ver los pasos antes de ejecutarlos.
2026-05-08
- Pidió Sergio: registrar el proyecto.
- Hice: archivo creado con cliente y status. Stack inferido por archivos detectados (composer.json + package.json + .git).
- Falta: todo — el proyecto necesita ser revisitado y los requerimientos pendientes documentados.