Auditoria previa a retirar claves foraneas - 2026-10-10

Conclusion: NO se aprueba todavia retirar las 79 restricciones de la base instalada.
No se ha conectado a la base ni ejecutado ALTER TABLE, TRUNCATE o DELETE.
No se han modificado las migraciones; mantienen las restricciones hasta validar
la sustitucion completa de su comportamiento.

Inventario local
- Las 79 restricciones del listado del usuario tienen definicion en migraciones.
- Ninguna de esas definiciones declara ON DELETE/ON UPDATE CASCADE o SET NULL.
  Por defecto MySQL restringe referencias invalidas y borrados/actualizaciones
  de padres referenciados. Quitar las FK elimina esa proteccion, no solo cascadas.
- No se encontraron belongsTo/hasMany/hasOne ni foreignKey en los modelos PHP
  revisados. No hay una sustitucion global de las FK en el ORM.
- 72 restricciones tienen referencias textuales de sus tablas o modelos en
  controladores/servicios; esto indica donde revisar, NO demuestra integridad.
- 7 restricciones no tuvieron referencias textuales fuera de modelos:
  caja_arqueo_detalle, documento_reversion_item_v2, inventario_fisico_personal_v2
  (2 relaciones), pago_qr_aplicacion, postventa_devolucion_detalle,
  proveedor_saldo_favor_aplicacion. Puede existir SQL dinamico o codigo externo.
- Hay validaciones existentes en variantes/atributos, ubicacion padre, movimientos
  de stock, pedidos, metas, cobros QR y rendiciones. No equivalen a las garantias
  de MySQL ante borrados manuales, escrituras externas o carreras concurrentes.

Correcciones realizadas
1. ProductoUbicacionV2Service: redistribuir rechaza variantes inexistentes,
   inactivas, de otra empresa o de otro producto antes de modificar stock.
2. InventarioFisicoV2Service: crear valida que cada ubicacion indicada exista,
   este activa y pertenezca a la empresa y sucursal del inventario. Las zonas
   sin ubicacion siguen permitidas; los errores hacen rollback.
3. InventarioFisicoV2Service: contar valida empresa, pertenencia de zona,
   variante del producto y ubicacion vigente antes de guardar el conteo.
4. GestionrepartosController: antes de reemplazar detalles de rendicion,
   bloquea el borrado si reparto_cobranza_abono referencia cualquiera de ellos.
   Conserva los abonos historicos; no los elimina para permitir el reemplazo.
5. Productov2Controller: corrige lectura de getPost('zonas'). La expresion
   anterior intentaba invocar una propiedad getPost como funcion.

Validacion realizada
- Sintaxis PHP 8.3: 412 archivos de facturacionv7/app, cero errores.
- integridad_sin_fk_v2_test.php: 19 casos aislados, correctos. Incluyen referencias
  ausentes, empresa/producto/sucursal equivocados, variantes/ubicaciones inactivas,
  ubicacion eliminada, zona ajena y operaciones validas.
- rendicion_integridad_sin_fk_test.php: 2 casos aislados, correctos. Bloquea detalles
  con abonos y permite reemplazarlos cuando no hay referencias.
- Estas pruebas usan dobles de modelos/adaptadores: NO validan MySQL, Phalcon real,
  concurrencia ni todos los flujos de la aplicacion.
- No hay COMERCIAL_V2_TEST_DSN configurado para ejecutar integracion MySQL.

Evidencia pendiente antes de aprobar la eliminacion
1. Ejecutar diagnostico_claves_foraneas_v2.sql en la base actual. El primer SELECT
   devuelve las reglas reales; la segunda consulta genera SELECT de huerfanos.
   Ejecutar esos SELECT generados y conservar sus resultados. No borran datos.
2. Usar la base MySQL de pruebas confirmada por el usuario o una copia del esquema
   ACTUAL y datos representativos; contrastar
   el comportamiento con FK y sin FK: altas, ediciones, anulaciones, borrados,
   QR, caja, inventarios, variantes, compras, postventa, canjes, metas y repartos.
3. Probar operaciones concurrentes y todos los escritores externos. Las comprobaciones
   de existencia en PHP no impiden por si solas que otro proceso borre un padre.
4. Verificar que no queden huerfanos tras las pruebas. Definir expresamente que
   borrados se bloquean y cuales eliminan detalles o conservan historial.
5. Solo despues, cambiar migraciones y generar una migracion de retirada aprobada.

Archivos de soporte
- auditoria_referencias_fk_v2.csv: inventario por restriccion, columnas, migracion
  y archivos de codigo referentes. Generado por tools/auditar_referencias_fk.ps1.
- diagnostico_claves_foraneas_v2.sql: consultas de solo lectura para la base actual.
- quitar_claves_foraneas_vhuancayo_v2.sql: borrador pendiente; no ejecutar aun.

Continuacion de revision - 2026-10-10
- Captura del usuario: el generador devuelve 79 consultas. No son resultados de
  conteos de huerfanos. La captura anterior mostraba NO ACTION para 25 relaciones;
  no se ha recibido aun el resumen de reglas de las 79.
- PostventaSaldoV2Service: ejecutarReembolso exige una postventa aceptada de la
  empresa; antes ignoraba el resultado de bloquearPostventa. El JOIN del reembolso
  ahora exige tambien coincidencia de empresa. Evita ejecutar un egreso si la
  postventa esta cancelada, ausente o pertenece a otra empresa.
- CompraIncidenciaService: resolver exige que el detalle original exista y sea de
  la recepcion indicada. Se elimina la sustitucion silenciosa de precio por costo
  cuando no existia el detalle. Esto impide ajustar Kardex sobre una referencia rota.
- CajaMovimientoService: turnoAbiertoUsuario comprueba empresa de caja fisica y
  sucursal; registrarCobranza recibe el turno del llamador. No se ha demostrado
  equivalencia global de las FK para escrituras concurrentes o externas.
- Nuevas pruebas aisladas: 4 escenarios de reembolso y 3 de validacion de incidencia
  (el escenario valido de incidencia se detiene antes de Kardex). Total: 28 casos.
  Los dos servicios modificados pasaron tambien PHP lint.
- contar_huerfanos_79_fk_v2.sql ejecuta 79 COUNT en un SELECT con UNION ALL, basado
  en nombres del listado y columnas de migraciones locales. No borra ni altera
  tablas. Cada fila debe devolver huerfanos=0; si existe una discrepancia de esquema,
  usar las consultas generadas desde information_schema del diagnostico original.
- Sigue pendiente la integracion MySQL. No se han eliminado claves ni cambiado
  migraciones. Estos cambios estan solo en el workspace, no desplegados al servidor.

Revision de cobranza de reparto - 2026-10-10
- El usuario confirma que las 79 relaciones devuelven cero huerfanos. Es evidencia
  de integridad actual, no de equivalencia del codigo sin restricciones.
- CobranzaRepartoService.registrarAbono recibia IDs de jornada, rendicion y detalle
  desde el llamador sin comprobarlos dentro del propio servicio. Ahora exige una
  transaccion activa y verifica con JOIN/FOR UPDATE que detalle, rendicion, jornada
  y entrega existen, estan relacionados y pertenecen a la empresa antes de
  guardar MontoCobrado o descontar deuda. El unico llamador encontrado,
  GestionrepartosController.validar_rendicionAction, ya abre una transaccion.
- Nueva prueba aislada: 7 casos (detalle, rendicion, jornada, entrega o empresa
  incorrectos; ausencia de transaccion; registro valido). Pasan sin modificar deuda
  cuando las referencias son invalidas. Total acumulado: 35 casos aislados.
- Pedidos/servicios de autorizacion y caja: inspeccion de referencias y borrados;
  no se encontraron nuevos borrados fisicos en los controladores de pedidos/caja
  revisados. Esto no certifica caminos dinamicos ni SQL externo.
- Sigue pendiente prueba integral MySQL; las FK permanecen y no se han alterado
  las migraciones.

Revision de solicitudes de precio en pedidos - 2026-10-10
- PedidoPrecioAutorizacionV2Service.solicitar invalidaba autorizaciones e insertaba
  un historial sin comprobar dentro del servicio que el pedido existiera en la
  empresa. Ahora bloquea la cabecera mediante SELECT FOR UPDATE antes de escribir.
- Rechaza cabeceras ausentes/de otra empresa, pedidos atendidos, anulados, en
  proceso de caja o con comprobante asociado. Conserva los estados editables
  BORRADOR, PENDIENTE_CAJA y PENDIENTE_AUTORIZACION.
- El historial conserva el estado anterior real; antes siempre escribia BORRADOR.
- Nueva prueba aislada: 9 escenarios de existencia, pertenencia, estados y
  comprobante. Todos correctos; PHP lint del servicio correcto. Total acumulado:
  44 escenarios aislados. No equivale a prueba completa en MySQL.
- La solicitud de autorizacion de stock tiene un camino independiente, sin
  transaccion propia en solicitar; pendiente en esa etapa, corregida posteriormente.
- Las restricciones de la base y migraciones siguen intactas.

Ampliacion del alcance completo solicitada por el usuario - 2026-10-10
- El usuario aclara que TODOS los contribuyentes de la base actual siguen en
  pruebas. No se exige otra copia para ensayar, pero aun falta conexion a MySQL
  desde este entorno. No se han ejecutado escrituras en esa base.
- PedidoStockAutorizacionV2Service.solicitar ahora valida/bloquea la cabecera y
  agrupa invalidacion, alta de autorizacion y cambio de estado en una transaccion.
  Respeta una transaccion del llamador sin anidarla ni cerrarla. Captura el ID
  inmediatamente despues del INSERT, antes de actualizar pedido.
- DocumentoTransformacionService.reservarCanje/confirmarCanje exigen transaccion;
  confirmarCanje valida empresa y sucursal del documento destino. Ambos llamadores
  locales identificados ya abren una transaccion.
- Nuevos tests: 12 escenarios de solicitud de stock y transacciones; 6 escenarios
  de contexto de canje (se detienen antes de confirmar origenes o emitir CPE).
  Total acumulado: 62 escenarios aislados; no equivalen a flujos completos MySQL.
- Se amplio lectura a caja operativa/conciliacion, QR, recepcion/documento proveedor,
  notas de credito proveedor, precios/grupos, metas, traslado/incidencias, entrega
  de repartos, canjes y sus llamadores. La matriz contiene las 79 FK en 59 tablas.
- Persisten escenarios concurrentes pendientes: autorizacion de stock al resolver
  (camino distinto de solicitar), cabeceras verificadas antes de begin, acumulados
  de incidencias y padres modificables desde SQL externo. No se declara equivalencia
  integral ni se autoriza el borrador de retirada por esta revision estatica.
- plan_validacion_integral_sin_fk.txt detalla flujos validos, errores, reintentos y
  concurrencia en 11 grupos funcionales. No se han marcado como ejecutados.
- tools/validar_integridad_sin_fk.ps1 permite repetir lint y los 8 archivos de prueba.
- archivos_modificados_revision_fk.csv enumera codigo, pruebas, SQL, documentacion
  y herramientas cambiadas a lo largo de la revision, con hashes actuales.
- Las migraciones se mantienen intactas hasta cerrar validacion; quitar FK ahora
  todavia permitiria escrituras no cubiertas por los controles agregados.

Resolucion de autorizaciones de stock - 2026-10-10
- PedidoStockAutorizacionV2Service.resolverConSesion ahora resuelve la solicitud y
  actualiza pedido dentro de una transaccion propia o de la del llamador.
- Bloquea solicitud y cabecera con FOR UPDATE, filtra empresa y valida que la
  cabecera siga editable y sin CPE. Evita reactivar pedidos ANULADO/ATENDIDO o
  resolver solicitudes sin un pedido valido. Comprueba una sola fila afectada.
- Conserva la invalidacion de solicitudes vencidas: si la transaccion es propia,
  confirma la invalidacion antes de devolver el error; no cambia pedido.
- Nueva prueba: 12 casos aislados de resolucion, rechazo, vencimiento, estados
  finales, solicitud previamente resuelta y otra autorizacion pendiente.
- Total acumulado: 74 casos en 9 archivos de pruebas. La revision pendiente de
  resolver stock mencionada antes queda reforzada localmente; su concurrencia
  real y vigencia del contexto del pedido siguen pendientes de prueba MySQL.
- Archivos de esta etapa: servicio PedidoStockAutorizacionV2Service.php,
  prueba nueva pedido_stock_resolucion_integridad_test.php, runner de validacion,
  este informe y manifiesto de archivos.

Revision final de cobertura y aprobacion de precio - 2026-10-10
- Se vuelve a comprobar el camino resolverConSesion de precio. Se consultaba la
  cabecera y el contexto antes de abrir la transaccion; podia sobrescribir un
  pedido anulado/atendido entre la consulta y la escritura.
- PedidoPrecioAutorizacionV2Service ahora bloquea solicitud, cabecera y detalles;
  exige estado editable y ausencia de CPE; relee vigencia/hash/nivel y vuelve a
  evaluar el contexto de precio bajo bloqueo antes de resolver. Comprueba una
  fila afectada y conserva el estado anterior real en el historial.
- Nuevos tests: 12 escenarios con motor de precios simulado, incluidos edicion
  tardia, vencimiento/resolucion concurrentes simulados, empresa equivocada,
  cabecera ausente, anulada/atendida/en caja/emitida, aprobacion/rechazo y otra
  solicitud pendiente. No son una prueba concurrente real de InnoDB.
- Total acumulado: 86 escenarios aislados en 10 archivos de prueba.
- Se amplia busqueda de las siete FK sin referencias operativas a la carpeta app
  alternativa; tampoco se identifican ahi caminos de escritura verificables.
- La revision de cobertura NO autoriza la retirada global. Siguen pendientes
  flujos completos MySQL, escritores externos, equivalencia del borrado de padres
  y pruebas reales de concurrencia en caja, QR, inventarios, incidencias y metas.
- Se ha solicitado ubicacion/host/puerto del MySQL de pruebas para avanzar en esa
  validacion sin solicitar contrasenas en el chat. No hay conexion disponible aun.
- Archivos cambiados en esta etapa: PedidoPrecioAutorizacionV2Service.php,
  pedido_precio_resolucion_integridad_test.php (nuevo), runner, este informe,
  plan de validacion y manifiesto.

Evidencia del hosting recibida el 2026-10-10:
Adjunto 4c6c928f-b056-4705-bca8-623089828a32/Texto pegado.txt.
Verificados 79 nombres de FK y 158 valores NO ACTION: DELETE_RULE y UPDATE_RULE
en las 79 restricciones. No hay propagacion CASCADE ni SET NULL en este listado.
El adjunto no contiene resultados de information_schema.TRIGGERS; esa comprobacion
sigue pendiente. No se retiraron claves ni se modifico la base del hosting.
La base es compartida; tipo_envio_sunat diferencia pruebas/produccion segun usuario.


Revision adicional de codigo del 2026-10-11, a peticion del usuario sin acceso hosting.
Detalle: docs/revision_final_codigo_fk_20261011.txt.
Corregidos PedidoCompatibilidadService.php (cabecera/ID/detalle y rollback Throwable)
y ProductoPrecioV2Service.php (referencia variante activa de empresa/producto).
Validacion: lint 412 PHP sin errores y 97 escenarios aislados en 12 archivos de prueba.
No son pruebas MySQL/Phalcon reales. Se mantienen siete enlaces sin ruta localizada
y ventanas de concurrencia; no se aprueba el DROP global como cambio sin reservas.
No se modifico la base del hosting ni se quitaron restricciones.


Cierre de las siete referencias, 2026-10-11:
Busqueda ampliada sin respetar ignores, por tablas y clases en fuentes locales.
Todas solo aparecen en esquema; dos tienen modelos sin escritores localizados.
La revision estatica de estos siete puntos queda cerrada: no hay flujo localizado
que corregir. Detalle y limites en cierre_siete_referencias_fk_20261011.txt.
SQL solicitado entregado: 79 DROP FOREIGN KEY cotejados contra inventario, sin
borrado de datos/indices/columnas. No ejecutado. No certifica integracion remota.

