# Auditoría inicial del proyecto

## Alcance y fecha

- **Fecha de auditoría:** 14 de julio de 2026.
- **Proyecto revisado:** sistema Laravel para control, autorización y seguimiento de pagos.
- **Alcance:** revisión estática y de solo lectura del repositorio, sus archivos rastreados por Git, configuración, rutas, controladores, modelos, servicios, migraciones, vistas, dependencias bloqueadas y logs presentes.
- **Restricciones aplicadas:** no se modificó código funcional, no se instalaron paquetes, no se ejecutaron migraciones y no se modificó ni consultó directamente la base de datos.

Las observaciones sobre el esquema se basan exclusivamente en las migraciones, el archivo SQL y los logs incluidos en el repositorio. No se verificó el estado actual de una base de datos desplegada. Tampoco se consultaron registros externos de vulnerabilidades o versiones disponibles de dependencias.

## Resumen ejecutivo

El repositorio contiene una aplicación Laravel monolítica y renderizada en servidor para registrar solicitudes de pago, someterlas a revisión, autorizarlas, agruparlas en lotes y registrar su pago. Incluye catálogos, usuarios, roles, documentos, reportes y notificaciones por correo y WhatsApp.

La estructura general es pequeña y comprensible, pero se verificaron riesgos que deben atenderse antes de utilizarla con pagos reales. Los más relevantes son la presencia en Git de documentos privados, sesiones y logs; credenciales administrativas de demostración; autorización incompleta sobre solicitudes y documentos; operaciones financieras sin transacciones ni control central de estados; ausencia de pruebas automatizadas; y errores verificables en la integración de notificaciones y Twilio.

No se puede confirmar, sólo con el repositorio, si alguno de estos archivos o secretos fue publicado fuera del entorno local, si las sesiones rastreadas siguen vigentes o si la configuración de producción mitiga algunos riesgos.

## Versiones detectadas

| Componente | Versión o implementación verificada | Fuente |
|---|---|---|
| PHP requerido | `^8.2` | `composer.json` |
| PHP del entorno de auditoría | 8.4.23 | `php -v` |
| Laravel | 12.59.0 bloqueado; restricción `^12.0` | `composer.lock`, `composer.json` |
| Composer del entorno | 2.8.5 | `composer --version` |
| Node.js del entorno | 24.16.0 | `node --version` |
| npm del entorno | 10.8.1 | `npm --version` |
| Frontend | Blade y Bootstrap 5.3.3 cargado desde CDN | vistas Blade |
| Base de datos prevista | MySQL/MariaDB | configuración y README |
| Roles y permisos | `spatie/laravel-permission` 6.25.0 | `composer.lock` |
| Registro de actividad | `spatie/laravel-activitylog` 4.12.3 | `composer.lock` |
| Exportación Excel | `maatwebsite/excel` 3.1.69 | `composer.lock` |
| Twilio | `twilio/sdk` 8.11.6 | `composer.lock` |
| PHPUnit | 11.0.12 | `composer.lock` |

No existe `package.json`, por lo que no se verificó un pipeline Node/Vite ni dependencias frontend administradas por npm. Node y npm corresponden al entorno de auditoría, no a una versión fijada por el proyecto.

## Arquitectura actual

La aplicación sigue una arquitectura monolítica Laravel:

- Las rutas web están centralizadas en `routes/web.php`.
- La interfaz se renderiza con Blade y Bootstrap.
- Los controladores realizan consultas, validación, autorización y parte importante de la lógica de negocio.
- Los modelos Eloquent contienen campos asignables, casts y algunas relaciones.
- Los servicios cubren cambios de estado, notificaciones y Twilio.
- La persistencia se define mediante migraciones Laravel para MySQL.
- La autenticación usa sesiones y el guard `web`.
- Los permisos se administran mediante Spatie Laravel Permission.
- Los documentos se guardan, por defecto, en `storage/app/private`.
- Correo y WhatsApp se envían sincrónicamente desde la petición HTTP.
- La cola predeterminada es `sync`; existen migraciones para trabajos y trabajos fallidos, pero no se encontraron Jobs de aplicación.
- Existe una tarea programada que intenta ejecutar `payments:check-overdue` diariamente a las 09:00.

No se encontró `routes/api.php`, una API formal, infraestructura como código, Dockerfile ni configuración de despliegue automatizado. Su inexistencia en el repositorio no permite concluir que no haya infraestructura mantenida en otro lugar.

## Módulos principales

1. **Autenticación:** login y logout mediante sesión.
2. **Dashboard:** conteos y monto pendiente de solicitudes.
3. **Solicitudes de pago:** creación, edición, documentos, revisión, autorización, observación, rechazo, detención, cancelación, reactivación y registro del pago.
4. **Lotes de pago:** agrupación de solicitudes listas para pagar y exportación a Excel.
5. **Proveedores:** datos fiscales y cuentas bancarias.
6. **Cuentas bancarias de empresa:** cuentas autorizadas y cuentas realmente utilizadas.
7. **Catálogos:** proyectos y categorías de gasto.
8. **Usuarios, roles y permisos:** administración mediante Spatie.
9. **Notificaciones:** eventos, plantillas, destinatarios, logs, correo y WhatsApp/Twilio.
10. **Reportes:** consulta y exportación CSV.
11. **Auditoría técnica:** tabla y paquete de activity log presentes, sin uso funcional encontrado en modelos o servicios.

## Flujo funcional verificado

La solicitud se crea con estado predeterminado `borrador`. Para enviarla a revisión, el controlador exige documentos de tipo `invoice_pdf` e `invoice_xml`. Después puede observarse, rechazarse o autorizarse. La autorización asigna una cuenta bancaria empresarial y coloca la solicitud en `lista_para_pagar`. La creación de un lote cambia las solicitudes a `procesando_pago`. Finalmente se registra la cuenta real, método, referencia, fecha y comprobante, y la solicitud pasa a `pagada`.

Los estados y sus transiciones no están centralizados en una máquina de estados. Se verificaron comprobaciones puntuales, pero no una matriz completa que limite cada acción a estados de origen válidos.

## Riesgos clasificados por prioridad

### Críticos

#### 1. Documentos privados, sesiones y logs rastreados por Git

- **Ubicación:** `storage/app/private/payment_requests/**`, `storage/framework/sessions/**`, `storage/logs/laravel.log` y otros artefactos bajo `storage`.
- **Verificado:** Git rastrea 94 archivos bajo `storage`, incluidos PDF, XML, imágenes, sesiones, caché, vistas compiladas y el log de Laravel.
- **Impacto:** posible exposición de información fiscal, bancaria, operativa y de sesión a cualquier persona o sistema con acceso al repositorio.
- **Corrección:** retirar estos artefactos del seguimiento y del historial cuando corresponda, invalidar sesiones, revisar la exposición del repositorio y ampliar `.gitignore`.
- **Prioridad:** antes de liberar.
- **Incertidumbre:** no se verificó si el repositorio fue compartido, si los documentos contienen datos reales ni si las sesiones siguen vigentes.

#### 2. Cuenta administrativa de demostración con contraseña conocida

- **Ubicación:** `database/seeders/DatabaseSeeder.php`, `resources/views/auth/login.blade.php` y `README.md`.
- **Hallazgo histórico corregido:** el seeder, la vista de login y la documentación exponían credenciales administrativas predeterminadas. La corrección eliminó esos valores y exige aprovisionamiento explícito.
- **Impacto:** acceso administrativo inmediato si esos datos llegan a un ambiente accesible y no son sustituidos.
- **Corrección:** eliminar valores precargados, no sembrar credenciales fijas y aprovisionar el primer administrador mediante un mecanismo seguro.
- **Prioridad:** antes de liberar.

#### 3. Autorización incompleta para solicitudes y documentos

- **Ubicación:** `PaymentRequestController::show`, `PaymentRequestController::edit` y `DocumentController::download`.
- **Verificado:** estas operaciones no comprueban un permiso de dominio; sólo quedan dentro del grupo general con middleware `auth`.
- **Impacto:** cualquier usuario autenticado podría intentar consultar solicitudes o descargar documentos por identificador.
- **Corrección:** implementar Policies y autorizar tanto el recurso como el alcance de datos del usuario.
- **Prioridad:** antes de liberar.

#### 4. Operaciones financieras no atómicas y transiciones incompletas

- **Ubicación:** `PaymentRequestController`, `PaymentBatchController` y `PaymentStatusService`.
- **Verificado:** las actualizaciones de solicitud, documentos, historial, lote y notificaciones no se agrupan en transacciones. Varias acciones no validan el estado de origen.
- **Impacto:** estados parciales, auditoría incompleta o pagos procesados desde estados no previstos.
- **Corrección:** definir una máquina de estados, invariantes por transición, transacciones y bloqueo de concurrencia.
- **Prioridad:** antes de liberar.

#### 5. Token Twilio almacenado sin cifrado

- **Ubicación:** `SettingController::saveTwilio` y modelo `SystemSetting`.
- **Verificado:** el controlador persiste `twilio_auth_token` con `is_encrypted=false`; el modelo no tiene un cast cifrado.
- **Impacto:** una lectura de la base o sus respaldos podría revelar la credencial.
- **Corrección:** utilizar un gestor de secretos o cifrado real con rotación y control de acceso.
- **Prioridad:** antes de liberar.
- **Incertidumbre:** no se consultó la base y no se puede confirmar que exista actualmente un token almacenado.

### Altos

#### 6. Creación concurrente de folios y lotes

- **Ubicación:** `PaymentRequestController::folio` y `PaymentBatchController::store`.
- **Verificado:** los folios se generan con `count() + 1`; la creación de lote no usa transacción ni bloqueo y, sin IDs, selecciona todos los pagos listos.
- **Impacto:** colisiones de folio, errores de clave única, inclusión concurrente de pagos o cambios parciales.
- **Corrección:** consecutivos atómicos, selección explícita, validación, transacción y locks.
- **Prioridad:** antes de liberar.

#### 7. Notificaciones registradas como enviadas aunque el proveedor falle

- **Ubicación:** `PaymentNotificationService::notify` y `sendEmail`.
- **Verificado:** correo y Twilio devuelven `false` ante ciertos fallos, pero el llamador no evalúa el retorno y actualiza el log a `enviado`.
- **Impacto:** trazabilidad falsa de comunicaciones financieras.
- **Corrección:** propagar o evaluar fallos, registrar estados reales y procesar notificaciones mediante colas con reintentos.
- **Prioridad:** antes de liberar.

#### 8. Integración Twilio inconsistente

- **Ubicación:** `NotificationController::testTwilio`, `TwilioService` y `config/services.php`.
- **Verificado:** se llama a un método `sendWhatsApp` no definido; `Log` se usa sin importación; la configuración declara `from`, mientras el servicio busca `whatsapp_from`; los settings guardados en la base no son leídos por el servicio.
- **Impacto:** prueba de Twilio rota, errores al registrar determinadas fallas y configuración administrativa sin efecto verificable.
- **Corrección:** unificar contrato, fuente y nombres de configuración y añadir pruebas de integración.
- **Prioridad:** antes de liberar.

#### 9. Comando programado inexistente

- **Ubicación:** `routes/console.php`.
- **Verificado:** se programa `payments:check-overdue`, pero no se encontró una clase Command ni un registro con ese nombre.
- **Impacto:** el proceso de vencidos no puede ejecutarse tal como está declarado.
- **Corrección:** implementar y probar el comando o retirar temporalmente la programación.
- **Prioridad:** antes de liberar.

#### 10. Usuarios desactivados pueden superar la autenticación

- **Ubicación:** `AuthController::login`.
- **Verificado:** `Auth::attempt` sólo recibe email y contraseña; no incluye `is_active`.
- **Impacto:** desactivar el usuario no garantiza impedir nuevos inicios de sesión.
- **Corrección:** exigir actividad al autenticar e invalidar sesiones existentes al desactivar.
- **Prioridad:** antes de liberar.

#### 11. Login sin limitación de intentos

- **Ubicación:** rutas de login y `AuthController`.
- **Verificado:** no se encontró middleware `throttle` ni RateLimiter específico para login.
- **Impacto:** mayor exposición a fuerza bruta y reutilización de credenciales.
- **Corrección:** rate limiting, alertas y evaluación de MFA para perfiles financieros.
- **Prioridad:** antes de liberar.

#### 12. Carga de archivos insuficientemente validada

- **Ubicación:** `PaymentRequestController::storeDocs` y `storeFile`.
- **Verificado:** factura PDF, XML y documento de soporte no aparecen en las reglas de validación de creación/actualización. El comprobante limita extensiones, pero no define tamaño máximo.
- **Impacto:** carga de archivos no previstos y consumo no limitado de almacenamiento.
- **Corrección:** Form Requests con tipo, MIME, tamaño, cantidad, validación segura de XML y análisis antimalware.
- **Prioridad:** antes de liberar.

#### 13. Cuenta del proveedor no se valida contra el proveedor seleccionado

- **Ubicación:** `PaymentRequestController::validated`.
- **Verificado:** sólo se exige que `supplier_bank_account_id` exista; no que pertenezca a `supplier_id` ni que esté activa.
- **Impacto:** una solicitud podría asociar la cuenta de otro proveedor.
- **Corrección:** regla de existencia condicionada y comprobación transaccional de pertenencia/actividad.
- **Prioridad:** antes de liberar.

#### 14. Logs con información sensible

- **Ubicación:** `storage/logs/laravel.log` y `TwilioService`.
- **Verificado:** el log incluye host, nombre de base, SQL, identificadores de usuario, variables Twilio y stack traces. El servicio registra teléfono y datos completos al fallar.
- **Impacto:** exposición de datos personales, configuración y contexto financiero.
- **Corrección:** redacción estructurada, exclusión de payloads sensibles, retención limitada y almacenamiento cifrado.
- **Prioridad:** antes de liberar.

#### 15. Auditoría funcional no implementada

- **Ubicación:** dependencia y configuración de `spatie/laravel-activitylog`.
- **Verificado:** existen paquete, configuración, migración y tabla declarada, pero no se encontró uso de `LogsActivity` ni llamadas a `activity()`.
- **Impacto:** cambios administrativos y financieros no tienen una bitácora completa mediante este mecanismo.
- **Corrección:** definir eventos auditables, actor, valores anteriores/nuevos y política de conservación.
- **Prioridad:** antes de liberar pagos reales.

#### 16. Exportación CSV susceptible a fórmulas

- **Ubicación:** `ReportController::export`.
- **Verificado:** valores de modelos se escriben directamente con `fputcsv` sin neutralizar prefijos interpretables como fórmula por aplicaciones de hoja de cálculo.
- **Impacto:** ejecución de fórmulas al abrir un archivo con datos manipulados.
- **Corrección:** neutralizar `=`, `+`, `-` y `@` al inicio de celdas no confiables.
- **Prioridad:** antes de liberar.

#### 17. Ausencia de pruebas automatizadas

- **Ubicación:** repositorio completo.
- **Verificado:** PHPUnit está bloqueado como dependencia, pero no se encontraron archivos de prueba.
- **Impacto:** no hay protección automatizada para permisos, estados, concurrencia, documentos, lotes o notificaciones.
- **Corrección:** construir una suite mínima de pruebas unitarias y Feature para los procesos críticos.
- **Prioridad:** antes de liberar.

#### 18. Estado de base desplegada no garantizado por el proceso observado

- **Ubicación:** `storage/logs/laravel.log` y migraciones Twilio.
- **Verificado:** el log contiene errores por columnas Twilio inexistentes en el momento de ejecutar código que ya las utilizaba. Actualmente el repositorio sí contiene una migración que las agrega.
- **Impacto:** evidencia de que al menos un entorno tuvo código y esquema desalineados.
- **Corrección:** validación bloqueante de migraciones y estrategia de despliegue compatible con cambios de esquema.
- **Prioridad:** antes de liberar.
- **Incertidumbre:** no se verificó si el entorno actual conserva esa divergencia.

### Medios

#### 19. Validación y autorización mezcladas en controladores

- **Verificado:** no existe `app/Http/Requests`; los controladores llaman directamente a `validate()` y `can()`/`abort_unless()`.
- **Impacto:** reglas dispersas y difíciles de probar o reutilizar.
- **Corrección:** Form Requests por operación, especialmente pagos, usuarios, roles, notificaciones y archivos.

#### 20. Controladores con responsabilidades múltiples

- **Ubicación principal:** `PaymentRequestController`, `PaymentBatchController` y `NotificationController`.
- **Verificado:** combinan consulta, autorización, validación, persistencia, archivos, estados, folios y notificaciones.
- **Impacto:** mayor riesgo de regresiones y dificultad de prueba.
- **Corrección:** casos de uso o Actions transaccionales y controladores delgados.

#### 21. No existen Policies ni Gates de dominio

- **Verificado:** se encontraron aliases de middleware de Spatie y comprobaciones manuales, pero no clases Policy ni definiciones Gate.
- **Impacto:** autorización repetida e inconsistente.
- **Corrección:** Policies para solicitudes, documentos, lotes, proveedores, cuentas y administración.

#### 22. Relaciones Eloquent incompletas

- **Verificado:** faltan relaciones declaradas para responsables de solicitudes, historial, documentos, lotes y logs de notificación.
- **Impacto:** consultas y reglas de dominio menos claras.
- **Corrección:** declarar relaciones y nombres convencionales.

#### 23. Migración Twilio condicionada por `hasColumn`

- **Ubicación:** `2026_05_15_171554_add_twilio_fields_to_notification_templates_table.php`.
- **Verificado:** la migración produce acciones distintas según el esquema previo.
- **Impacto:** menor reproducibilidad y posibilidad de ocultar drift.
- **Corrección:** migraciones deterministas y reconciliaciones explícitas.

#### 24. Configuración local no apta para múltiples instancias

- **Verificado:** filesystem, sesiones y caché usan disco local por defecto; la cola usa `sync`.
- **Impacto:** sesiones inconsistentes, pérdida de documentos en instancias efímeras y peticiones bloqueadas por correo/Twilio.
- **Corrección:** almacenamiento compartido/objeto, sesiones y caché compartidas, cola externa y workers.

### Bajos

#### 25. Código no referenciado y convenciones inconsistentes

- **Verificado:** `CatalogController` no aparece en rutas; `PaymentBatch::hasManyItems()` no sigue el nombre convencional `items`; varios archivos PHP y Blade concentran gran cantidad de código en una línea.
- **Impacto:** revisión y mantenimiento más difíciles.
- **Corrección:** confirmar uso antes de retirar, aplicar formato consistente y normalizar nombres.

#### 26. Dependencia de Bootstrap desde CDN

- **Verificado:** Bootstrap 5.3.3 se carga desde jsDelivr en vistas.
- **Impacto:** dependencia operativa de un tercero y mayor dificultad para una CSP estricta.
- **Corrección:** servir assets versionados localmente o configurar SRI y CSP.

## Deuda técnica

- Falta una capa explícita de casos de uso para operaciones financieras.
- No existen Form Requests.
- No existen Policies.
- No existe máquina de estados centralizada.
- Las transiciones no siempre pasan por `PaymentStatusService`; por ejemplo, el lote cambia el estado directamente.
- Varias relaciones Eloquent relevantes no están declaradas.
- Activitylog está instalado y migrado, pero no integrado.
- Notificaciones y proveedores externos se ejecutan de forma síncrona.
- No existe suite de pruebas.
- No existe configuración de análisis estático o pipeline de calidad visible.
- Código y vistas tienen formato compacto e inconsistente.
- Hay artefactos generados y datos de ejecución rastreados por Git.
- `CatalogController` no tiene rutas detectadas y puede ser código muerto; debe confirmarse antes de eliminarlo.

## Problemas para producción

Además de los riesgos críticos y altos, se verificaron los siguientes impedimentos operativos:

- Filesystem, sesiones y caché locales no son adecuados para múltiples instancias o almacenamiento efímero.
- La cola síncrona mantiene correo y Twilio dentro del tiempo de respuesta HTTP.
- El mailer predeterminado es `log`, por lo que un ambiente sin configuración explícita no enviaría correo real y podría registrar su contenido.
- El scheduler referencia un comando inexistente.
- No se encontró configuración para S3, Redis, SQS, SES, workers o un scheduler de infraestructura.
- No se encontró Dockerfile, infraestructura como código, CI/CD ni estrategia documentada de rollback.
- No se encontró una política de backup, retención, cifrado o recuperación.
- No se encontró configuración específica de cookies seguras para producción; `SESSION_SECURE_COOKIE` depende del ambiente.
- El health check `/up` está configurado, pero no se verificó que pruebe base de datos, cola, almacenamiento o servicios externos.

No se puede afirmar que la infraestructura externa no exista; solamente no está representada en el repositorio revisado.

## Plan de corrección

### Etapa 0 — Contención

1. Determinar si el repositorio y su historial fueron compartidos.
2. Invalidar las sesiones rastreadas y revisar si hay secretos o datos reales expuestos.
3. Retirar documentos, sesiones, logs, cachés y vistas compiladas del seguimiento e historial.
4. Eliminar credenciales demostrativas del flujo productivo y rotar cualquier credencial comprometida.

### Etapa 1 — Seguridad e integridad financiera

1. Implementar Policies y autorización por recurso.
2. Definir máquina de estados y transiciones permitidas.
3. Introducir transacciones, locks y generación atómica de folios/lotes.
4. Validar pertenencia y actividad de cuentas bancarias.
5. Endurecer carga y descarga de documentos.
6. Corregir autenticación de usuarios inactivos y rate limiting.
7. Proteger asignación de roles y permisos críticos.
8. Implementar auditoría consistente de cambios.

### Etapa 2 — Notificaciones y tareas de fondo

1. Corregir el contrato y configuración de Twilio.
2. Asegurar que los logs de notificación reflejen el resultado real.
3. Implementar colas, reintentos y manejo de fallos.
4. Implementar o retirar `payments:check-overdue`.
5. Evitar datos sensibles en logs.

### Etapa 3 — Pruebas de liberación

1. Autenticación, usuarios inactivos y rate limiting.
2. Autorización por recurso y rol.
3. Todas las transiciones del pago.
4. Concurrencia de folios y lotes.
5. Rollback de operaciones parciales.
6. Archivos privados y validación de cargas.
7. Correo, Twilio, colas y reintentos mediante fakes.
8. CSV/Excel y neutralización de fórmulas.
9. Migración desde una base vacía.

### Etapa 4 — Preparación de infraestructura

1. Almacenamiento privado compartido u objeto, con cifrado y ciclo de vida.
2. Sesiones y caché compartidas.
3. Cola externa y workers supervisados.
4. Gestión externa de secretos.
5. Centralización, redacción y retención de logs.
6. Scheduler, backups, health checks y estrategia de rollback.
7. CI/CD e infraestructura reproducible.

### Etapa 5 — Mantenibilidad

1. Extraer Form Requests y casos de uso.
2. Completar relaciones Eloquent.
3. Normalizar formato, nombres y convenciones.
4. Confirmar y retirar código muerto o dependencias sin uso.
5. Definir un pipeline frontend o una política segura para assets CDN.

## Elementos pendientes de confirmar

Los siguientes puntos no pueden determinarse directamente con el contenido revisado:

- Si los PDF, XML, imágenes, sesiones y logs rastreados contienen datos reales o fueron sólo datos de prueba.
- Si el repositorio fue publicado, compartido o respaldado en sistemas externos.
- Si las sesiones rastreadas siguen siendo válidas.
- Si existen secretos reales en la base de datos o en archivos `.env` no versionados.
- El esquema y estado de migraciones de desarrollo, staging y producción.
- Si el comando programado existe en infraestructura o código no incluido en el repositorio.
- La arquitectura real de AWS, si se mantiene fuera de este proyecto.
- Configuración productiva de HTTPS, proxies confiables, cookies, headers y CSP.
- Configuración real de correo, Twilio, almacenamiento, colas y scheduler.
- Políticas de backup, recuperación, retención, cifrado y rotación de secretos.
- Volumen esperado de usuarios, documentos, pagos y concurrencia.
- Reglas de negocio definitivas para cada transición y separación de funciones.
- Si se requiere cumplimiento específico fiscal, contractual, de privacidad o financiero.
- Vulnerabilidades publicadas o versiones más recientes de dependencias; no se ejecutó `composer audit` ni se consultaron fuentes externas.
- Compatibilidad de todas las dependencias con PHP 8.4 en producción; el requisito declarado comienza en PHP 8.2.

## Conclusión

El repositorio representa una base funcional reconocible, pero los riesgos verificados de confidencialidad, autorización, concurrencia, trazabilidad y despliegue impiden recomendar su uso productivo con pagos reales en el estado auditado. La primera liberación debería condicionarse al cierre de los riesgos críticos y altos, acompañado de pruebas automatizadas de los flujos financieros principales.
