# Análisis del Proyecto: restApi

**Fecha:** 2026-10-20
**Ruta:** `/serverApps/repos/api/app`
**Alcance:** código propio (105 archivos PHP fuera de `lib/`, 73 DAOs, docs y módulos de integración). Las librerías de terceros (`lib/aws`, JWT, PHPMailer) solo se evalúan como gestión de dependencias.

> **Nota sobre secretos:** este documento **no** transcribe credenciales. La versión anterior de `analisis.md` (commit `6e1aa45`) sí las incluía y quedó en el historial de git. Ver hallazgo S-1.

---

## 0. Resumen ejecutivo

| Dimensión | Nota | Comentario |
|---|---|---|
| Seguridad | 1/10 | Sin autenticación efectiva en los endpoints, SQL por concatenación en todo el acceso a datos, CORS abierto y credenciales expuestas. |
| Arquitectura | 3/10 | Un script PHP por endpoint, con DAO por tabla; sin router, middleware ni capa de servicio. |
| Rendimiento | 4/10 | Aceptable con poca carga; sin caché, sin paginación, `memory_limit=-1` y subconsultas correlacionadas. |
| Mantenimiento | 3/10 | Sin tests, sin Composer, librerías duplicadas, mucho código repetido y comentado. |
| Funcionalidad / lógica | 7/10 | Cubre bien el negocio (clientes, inventario, facturación CO/EC, CRM, flotas). La lógica es difícil de seguir y de probar. |

**Prioridades inmediatas:**
1. Rotar todos los secretos que hayan estado en el repositorio o en `analisis.md`.
2. Poner autenticación real en todos los endpoints.
3. Parametrizar las consultas SQL.

---

## 1. Arquitectura

### 1.1 Visión general
API REST en **PHP procedimental** (sin framework). Cada endpoint es un archivo `.php` que se invoca directamente por URL.

```
Cliente HTTP (CRM, ATW+, apps internas, cron)
        │
        ▼
Script PHP (raíz o subcarpeta)   ← headers CORS, parseo de $_REQUEST/php://input,
        │                           lógica de negocio, armado de respuesta
        ▼
DAO (lib/dao/*.php, 73 clases)   ← SQL concatenado + ADODB
        │
        ▼
Informix vía PDO/ADODB           ← $DBi (Colombia: basdat) y $DBe (Ecuador: dbecuador)
        │
        ▼
Servicios externos: Contifico (EC), ATW+, Azure (CRM/AD), AWS SES, Gotenberg (PDF), SICE
```

### 1.2 Estructura de carpetas

| Carpeta | Propósito |
|---|---|
| raíz | Endpoints heredados: `clientes`, `login`, `autenticacion*`, `ctwfl*` (flota), `operarios`, `proveedores`, `generatePDF*`, `multiorderPDF`, etc. |
| `lib/dao/` | 73 DAOs, uno por tabla o entidad (`facliDAO` tiene 2473 líneas y `famovDAO` 1018). |
| `lib/funcionesGenerales/`, `generic_functions.php` | Utilidades, envío de correo, selección de BD por país. |
| `contifico/` | Facturación electrónica de Ecuador: facturas, notas de crédito, guías de remisión, clientes y productos. |
| `integrationCRM/`, `customer/`, `invoices/`, `articles/` | Integraciones y módulos de dominio. |
| `iproveedor/` | Endpoints `captiva` y `confirming` para clientes y facturas. |
| `integrationATW/`, `sincronize_az/`, `parametricsSICE/` | Integraciones ATW+, Azure y SICE. |
| `corporate_signature/`, `website/`, `uautomundial/`, `pcpk/` | Módulos periféricos, con MySQL en algunos. |
| `docs/` | Documentación reciente (Contifico, PDF multiorden, estados de cuenta): ~840 líneas. |
| `lib/aws`, `lib/php-jwt-master*`, `lib/mailer`, `lib/phpmailer6` | Librerías copiadas a mano. |

### 1.3 Observaciones de arquitectura
- **Sin punto de entrada único.** No hay front controller, router ni middleware, así que cada archivo repite CORS, locale, conexión y manejo de errores.
- **Acoplamiento al entorno:** rutas absolutas como `/var/www/html/adodb5/...` y hosts como `sice_cloud` (en una conexión de `lib/param.inc.php`) están fijos en el código.
- **Dos conexiones globales** (`$DBi`, `$DBe`) que se crean en cada request, incluso cuando el endpoint solo usa una. El país se elige con `?country=ec` y un prefijo de BD concatenado en los DAOs (`'dbecuador:'`).
- **Los DAOs mezclan datos y reglas de negocio** (formateo, decisiones, `die()` en errores). Los endpoints también contienen lógica; no hay capa de servicio.
- **Dependencias inconsistentes:** dos PHPMailer (`lib/mailer`, `lib/phpmailer6`) y tres copias de JWT (`lib/jwt-master`, `lib/php-jwt-master`, `lib/php-jwt-master2`).
- **Tres frentes de configuración:** constantes en `lib/param.inc.php`, valores fijos en endpoints (p. ej. correos de soporte) y claves incrustadas en archivos sueltos.

---

## 2. Seguridad

### S-1 · CRÍTICO — Credenciales en texto plano
- `lib/param.inc.php` (excluido del repositorio por `.gitignore`, bien) contiene **en claro** la contraseña de Informix, el Basic Auth de ATW+, tokens de Contifico (producción **y** comentados de pruebas) y el client secret de Azure AD.
- Archivos que **sí están versionados** y tienen secretos incrustados: `generatePDF.php` y `multiorderPDF.php` (Basic Auth de ATW+), `lib/funcionesGenerales/envioCorreo.php` (contraseñas SMTP y un Basic Auth, en 6 puntos) y `website/connMysql.php` / `website/carnetsTucamion.php` (contraseñas MySQL).
- `login.php`/`autenticacion.php` incluyen código comentado con contraseñas.
- El `analisis.md` anterior las copiaba literalmente; están en el historial de git (665 commits) y en el remoto si se hizo push.
- Los usuarios de BD son compartidos: todas las apps y endpoints usan la misma cuenta.

**Acción:** rotar todo (Informix, MySQL, SMTP, Contifico, Azure AD, ATW+ y AWS si aplica), pasar a variables de entorno o AWS Secrets Manager, y purgar el historial (`git filter-repo`) si el remoto no es estrictamente privado.

### S-2 · CRÍTICO — SQL Injection generalizado
Los 73 DAOs arman SQL concatenando valores, y los endpoints pasan `$_REQUEST` casi directo (461 accesos a `$_REQUEST/$_GET/$_POST` fuera de `lib/`). Solo se encontró **1** uso de consultas parametrizadas en todo el código propio.

```php
// sertokDAO.php: incluso el SQL del token concatena el valor
"... where toktok = '" . $toktok . "' and tokusu = '" . $tokusu . "'"

// validateDAO.php::getUpdate: tabla, columna y valores vienen concatenados
" UPDATE ".$tabla." SET ".$campo."='".$valor."' WHERE ".$llave." = '".$valor_llave."'"
```
`ValidateDAO::getUpdate` es especialmente peligroso porque permite construir un `UPDATE` sobre tabla y columna arbitrarias.

### S-3 · CRÍTICO — Autenticación ausente o ineficaz
- `SertokDAO::validateToken()` existe (cabeceras `App-Token`/`App-User`, vigencia por fecha), pero **ninguno de los endpoints revisados lo llama activo**: en `clientes.php` las líneas están comentadas. Es decir, los endpoints están **abiertos sin credenciales**.
- `autenticacion.php` reenvía un token por GET a otra URL (`ctw.automundial.co/.../autenticacion2.php`, ruta de desarrollo) y no devuelve ni valida el resultado; `autenticacion2.php` tiene la validación comentada.
- `login.php`:
  - La condición `!isset(username) && !isset(password)` está **invertida**, así que la rama de login solo se ejecuta cuando ambos faltan y luego lee propiedades inexistentes. En la práctica el login no funciona como se espera.
  - El JWT se firma con una clave fija (`AutomPlus`) escrita en el código y expira a los 30 días.
  - Usa como credenciales del login las de la propia BD (`$DBi->Connect(SERVER,$user,$pass,...)`).
- Los endpoints de Contifico, facturación y correo (`create_document*.php`, `generatePDF*.php`, `enviarCorreo.php`, `test-email.php`) se disparan por URL sin autenticar. Quien conozca la ruta puede emitir facturas o enviar correos.
- No hay rate limiting ni protección contra fuerza bruta.

### S-4 · ALTO — CORS abierto
`Access-Control-Allow-Origin: *` aparece en **89** archivos. Combinado con la falta de autenticación, cualquier sitio web puede consumir la API desde el navegador de un usuario interno.

### S-5 · ALTO — Validación de entrada inexistente
- Los parámetros se usan tal cual en SQL, rutas, URLs de curl y correos.
- `generic_functions.php` (`eliminar_simbolos`, `validar_*`) es superficial y no sustituye el escape.
- `clientes.php` tiene variables inexistentes (`$_QUEST`, `$data` sin definir): código que no se ejecuta como se pretende.
- `autenticacion.php` concatena el token en la URL del curl sin `urlencode`.

### S-6 · MEDIO — Manejo de errores y depuración
- `error_reporting(0)` en 44 archivos: los fallos desaparecen sin dejar registro.
- `$DBi->debug = true` en 36 sitios: ADODB imprime las consultas completas en la respuesta HTTP, lo que filtra el esquema.
- `die($this->conn->ErrorMsg())` devuelve mensajes de la BD al cliente.
- Los `echo "-Starting process"` en `contifico/create_document.php` mezclan texto con respuestas `application/json`.

### S-7 · MEDIO — Archivos y red
- `generatePDF*.php` y `multiorderPDF.php` escriben en disco y borran con `unlink` (incluido el borrado masivo de la carpeta en `multiorderPDF.php:50`); el nombre de archivo puede venir del request y no se normaliza.
- Hay URLs `http://` sin TLS en el código (8 fuera de comentarios). No se encontró que se desactive la verificación SSL de curl.
- La carpeta `log/` está en la raíz web: sus archivos (por ejemplo `EndpointArticles*.txt`, volcados de peticiones) pueden ser legibles por URL si el servidor no lo impide.

### S-8 · BAJO
- Sin cabeceras de seguridad (HSTS, `X-Content-Type-Options`, etc.).
- Sin protección de `docs/` ni de scripts de prueba (`test-email.php`, `invoices/testDate.php`, `invoices/debug_curl.txt`) en producción.

---

## 3. Rendimiento

| Hallazgo | Detalle | Impacto |
|---|---|---|
| `memory_limit = -1` | 90 archivos | Un request grande puede agotar la memoria del servidor. |
| Subconsultas correlacionadas | `crm_clientesDAO.php`: varios `SELECT COUNT(*)` dentro de `CASE WHEN` por fila | Costo que crece con el número de clientes. |
| `LIKE '%texto%'` | Búsquedas por nombre | Escaneo completo de tabla; no usa índices. |
| Sin paginación | Los listados devuelven todo el resultado | Respuestas enormes y timeouts. |
| Sin caché | Sin Cache-Control/ETag ni Redis | Catálogos y listas se recalculan en cada llamada. |
| Conexiones por request | `$DBi` y `$DBe` siempre | Latencia innecesaria; el timeout PDO está en 500000. |
| Transacciones sin manejo de error | `begin work` / `commit work` manuales | Riesgo de bloqueos si falla algo en medio. |
| Trabajo pesado dentro del request | PDF (Gotenberg), SES y Contifico de forma síncrona | El cliente espera todo; sin cola ni reintentos. |
| Logs | `log/` pesa **231 GB** (775 archivos) y no hay rotación | Riesgo real de llenar el disco. |

---

## 4. Mantenimiento

- **Sin pruebas automatizadas** (solo scripts manuales como `test-email.php` y `testDate.php`).
- **Sin Composer:** 2728 archivos de `lib/aws` (50 MB) están versionados a mano, además de JWT y PHPMailer duplicados. Es difícil aplicar parches de seguridad.
- **Código repetido:** la cabecera de cada endpoint (CORS, locale, includes, parseo) se copia 30+ veces, y existen pares `generatePDF.php`/`generatePDFv2.php`, `saldosInventario.php`/`saldosInventarioMod.php`, `autenticacion.php`/`autenticacion2.php`.
- **Código muerto y comentarios:** bloques enteros comentados (URLs de pruebas, credenciales antiguas, `validateToken`). Esto confunde sobre qué está activo.
- **Etiquetas PHP cortas** (`<?` en varios archivos, incluido `contifico/create_document.php`): depende de `short_open_tag`; rompe en otras configuraciones.
- **Estilo heredado:** constructores PHP4 (`function SertokDAO(...)`), `var`, sin namespaces ni autoload, nombres crípticos de tablas y columnas (`clicod`, `famov`, `ivsal`).
- **Codificación:** `param.inc.php` y otros archivos tienen texto en Latin-1, lo que genera caracteres rotos.
- **Sin versionado de API** ni contrato (sin OpenAPI).
- **Git:** historial lleno de merges automáticos entre ramas locales y remoto; la rama `master` va 7 commits por delante de `origin`.
- **Documentación:** buena y reciente en `docs/` (Contifico, PDF, estados de cuenta), pero el `README.md` se limita a dos `mkdir` y no explica dependencias, configuración ni despliegue.

---

## 5. Funcionalidad y lógica

### 5.1 Dominios cubiertos
- **Clientes/CRM:** consulta y sincronización de clientes, direcciones, listas de precios, tiquetes y recibos hacia el CRM.
- **Inventario:** artículos, saldos, costos y consumos.
- **Facturación Colombia (SICE) y Ecuador (Contifico):** facturas, notas de crédito, devoluciones y guías de remisión.
- **Estados de cuenta:** generación de PDF con correo vía SES.
- **Flotas (ATW+):** vehículos, inspecciones, llaves, localizaciones, historial.
- **Proveedores/Confirming:** facturas pendientes y pagadas.

### 5.2 Riesgos de lógica detectados
1. **`login.php`:** condición invertida (ver S-3); el flujo de login no es confiable.
2. **`clientes.php`:** variables inexistentes (`$_QUEST`, `$data->last_name`), y `$clicod`/`$clinom` pueden quedar sin definir según los parámetros.
3. **Países:** el país se decide con un `if` sobre `?country=ec` y el prefijo de BD se concatena, sin lista blanca.
4. **Facturación Contifico:** el documento se identifica con `?movdoc=DOC-LOCAL`, con `explode` sin validar que existan ambas partes. Local `810`→`001`, `820`→`002`, otros → `---`: valores fijos en el código.
5. **Idempotencia:** `create_document.php` no evita facturar dos veces el mismo documento si se reintenta la llamada (según lo revisado).
6. **Correos de soporte** (`$email_tec`, `$email_copy`) fijos en el código y apuntando a una cuenta personal.
7. **Errores de integración:** se registran en archivo mensual y se envía un correo, pero la respuesta al cliente no siempre refleja el fallo.

---

## 6. Buenas prácticas observadas

- Separación DAO/endpoint y organización por dominio.
- `lib/param.inc.php` y `lib/conexion*.php` están en `.gitignore`: la intención de no versionar configuración es correcta.
- Función central `render()`/`render_error()` con catálogo de errores en `error_http.php`.
- Registro en archivo con rotación mensual por nombre en los módulos de Contifico y estados de cuenta, más aviso por correo en errores.
- Documentación reciente y detallada de los módulos nuevos (`docs/`).
- Uso de HTTPS en las integraciones principales.
- Uso de `LOCK_EX` en `statement_process.php` al escribir logs.
- Soporte multipaís centralizado en `seleccionPaisDB.php`.

## 7. Malas prácticas

| Práctica | Alcance | Severidad |
|---|---|---|
| Endpoints sin autenticación | Prácticamente todos | Crítica |
| SQL por concatenación | 73 DAOs | Crítica |
| Credenciales en código/documentos versionados | Varios archivos + historial | Crítica |
| `ValidateDAO::getUpdate` con tabla/columna dinámica | 1 DAO, reutilizable | Crítica |
| CORS `*` | 89 archivos | Alta |
| `memory_limit = -1` | 90 archivos | Alta |
| `error_reporting(0)` | 44 archivos | Media |
| `debug = true` en ADODB | 36 sitios | Media |
| Librerías copiadas y duplicadas | `lib/` | Media |
| Código comentado/duplicado (`v2`, `Mod`) | Raíz | Media |
| Logs sin rotación (231 GB) | `log/` | Media |
| Short tags, constructores PHP4 | Varios | Baja |
| Sin paginación | DAOs | Baja |

---

## 8. Opciones de mejora

### Fase 0 — Esta semana (contención)
1. **Rotar todas las credenciales** y sacarlas del código a variables de entorno (`getenv`) o AWS Secrets Manager. Revocar las claves AWS y los tokens de Contifico anteriores.
2. **Confirmar la visibilidad del remoto** (`origin`). Si no es privado, purgar el historial y tratar todo como comprometido.
3. **Bloquear acceso web** a `log/`, `docs/`, `invoices/debug_curl.txt` y scripts de prueba (reglas de Apache/Nginx).
4. **Restringir por red/IP** los endpoints de facturación y correo mientras llega la autenticación.
5. **Rotación de logs** (`logrotate`) y limpieza de los 231 GB; sacar `log/` de la raíz web.
6. **Eliminar `ValidateDAO::getUpdate` dinámico** o limitarlo con lista blanca de tabla/columna.

### Fase 1 — 2 a 4 semanas (seguridad base)
7. **Un único archivo `bootstrap.php`** incluido por todos los endpoints, que se encargue de CORS con lista blanca de orígenes, validación de token (JWT con `exp`, clave en entorno, algoritmo explícito), y manejo de errores/logs.
8. **Corregir `login.php`** (condición, no usar credenciales de BD como credenciales de usuario) y activar `validateToken` o JWT en todos los endpoints.
9. **Consultas parametrizadas** empezando por `sertokDAO`, `facliDAO`, `famovDAO` y los endpoints más expuestos:
   ```php
   $rs = $this->conn->Execute(
     "SELECT tokid, toktok FROM sertok WHERE toktok = ? AND tokusu = ?",
     [$toktok, $tokusu]
   );
   ```
10. **Validación de entrada** con una función/librería común (tipos, longitudes, listas blancas como `country in (co, ec)`).
11. **Desactivar** `debug = true`, `display_errors` y `error_reporting(0)`; registrar errores con `error_log` o Monolog.

### Fase 2 — 1 a 3 meses (calidad)
12. **Composer:** gestionar AWS SDK, PHPMailer, firebase/php-jwt y ADODB; borrar las copias manuales.
13. **Front controller + router** (Slim o similar) y una capa de servicios para sacar la lógica de los endpoints.
14. **Pruebas:** empezar con integración sobre autenticación, clientes, facturación Contifico y estados de cuenta; después unitarias de los servicios.
15. **Paginación y filtros** en listados; reemplazar `CASE WHEN (SELECT COUNT...)` por `JOIN`/`EXISTS` o vistas.
16. **Idempotencia** en la facturación (tabla de control por documento) y **cola de trabajos** para PDF/correo/Contifico con reintentos.
17. **Configuración por entorno** (`.env`), sin rutas absolutas ni hosts en el código; documentar despliegue en el `README`.
18. **Eliminar duplicados y código muerto** (`generatePDF`/`v2`, `autenticacion2`, `saldosInventarioMod`) tras confirmar quién los usa.

### Fase 3 — Largo plazo
19. Migrar a un framework moderno (Laravel/Slim) y PHP 8 con tipado, namespaces y autoload.
20. Versionado `/v1/` y especificación **OpenAPI**.
21. Caché (Redis) para catálogos y consultas costosas.
22. Observabilidad: logs centralizados (CloudWatch/Sentry), métricas y alertas.
23. Pipeline CI/CD con análisis estático (PHPStan/Psalm), `composer audit` y detección de secretos (gitleaks).

---

## 9. Conclusión

El sistema cubre un dominio de negocio amplio y tiene documentación reciente útil, pero hoy expone datos y operaciones críticas (clientes, inventario, facturación en dos países) sin autenticación efectiva, con inyección SQL generalizada y con secretos comprometidos. Antes de cualquier mejora de arquitectura o rendimiento, deben rotarse las credenciales, protegerse los endpoints y parametrizarse las consultas.

> **Límites de este análisis:** se revisó el código estáticamente. No se probaron los endpoints ni se consultó la base de datos, la configuración del servidor web ni el remoto de git. Por tanto, la exposición real de `log/`, la visibilidad de `origin` y el uso efectivo de cada script en producción son puntos por confirmar.
