# ASISMA CRM — Guía para desarrollo

CRM multi-tenant para red de franquiciados ASISMA. Lee `README.md` y `docs/` para
el detalle funcional. Especificación original en `Nuevo CRM/` (solo documentos).

## Restricciones duras

- **PHP 5.5.12 / MySQL 5.6** (WAMP legado). Nada de: type hints escalares, `??`,
  `hash_equals` nativo (hay polyfill en `config/constants.php`), funciones de
  PHP 5.6+. Sintaxis `[]` para arrays sí está disponible.
- **NO tocar** `C:\wamp\www\asisma_ops` (producción). Sus patrones se pueden
  leer como referencia, nunca modificar.
- El warning `php_intl.dll` en CLI se resolvió comentando la extensión en
  `php.ini` (solo CLI; Apache usa `phpForApache.ini`).

## Arquitectura

- MVC propio: `index.php` → `Router` (`config/routes.php`, match exacto de ruta,
  sin parámetros en la URL — se usan query strings) → Controller → vista.
- `Database` (config/database.php): singleton PDO. `insert()/update()` reciben
  arrays asociativos; los placeholders de update se prefijan `update_`.
- Multi-tenant por `franquiciado_id`: usar `$this->getTenantFilter('alias')`
  en controllers. Admin ve todo.
- Autoload: `app/core`, `app/controllers`, `app/models`, `app/middleware`,
  `app/helpers`. El cron NO usa autoload: hace `require` explícito.
- Rutas públicas (`auth => false`): `login`, `authenticate`, `cotizaciones/publica`,
  `api/leads`, `api/whatsapp/webhook`.

## Convenciones

- Todo en español: métodos, variables, mensajes, comentarios.
- Vistas: tema oscuro slate (Tailwind CDN), jQuery + SweetAlert2
  (`background: '#1e293b', color: '#f8fafc'`) + Lucide. jQuery se carga UNA vez
  en `layout/head.php` — no agregar `<script src=...jquery...>` en vistas.
- Tras inyectar DOM dinámico llamar `lucide.createIcons()`.
- Acciones sensibles → `AuditHelper::log()`.
- OJO nombres de columnas: `contactos.correo` (no email), `empresas.sitio_web` +
  `empresas.activa`, `leads.usuario_asignado_id`, `asignaciones_lead.asignado_at`
  (no created_at). El ENUM de `asignaciones_lead.estado` es
  pendiente/aceptado/timeout/rechazado.
- `Controller::input()` sanitiza con htmlspecialchars — para texto que va a
  APIs externas (WhatsApp) leer `$_POST` directo y escapar al renderizar.
- RUT canónico: sin puntos y CON guion (`XXXXXXXX-D`), en el CRM y en lo que se
  inserta en Control Empresas. Siempre pasar por `normalizar_rut()` antes de
  guardar o comparar.

## Piezas clave

- `app/helpers/RotacionHelper.php` — cascada de asignación (usuario a usuario,
  franquiciado a franquiciado, por región+vertical+prioridad). Usado por el cron
  y por `ApiController`.
- `app/helpers/WhatsAppHelper.php` — Evolution API (enviar, media, instancias,
  normalización 569XXXXXXXX). Webhook en `WhatsAppController::webhook()`.
- `app/helpers/IntegracionesHelper.php` — al ganar un lead: provisión Control
  Empresas (`ws_provision.php`, claves `CE_*` en config_sistema; vacías =
  desactivada) + notificación API facturación del franquiciado. Siempre FUERA
  de transacciones.
- `cron/rotacion_leads.php` — timeouts y asignación de leads huérfanos.

## Pruebas

- Lint: `C:\wamp\bin\php\php5.5.12\php.exe -l <archivo>`.
- HTTP local: `Invoke-WebRequest http://127.0.0.1/... -Headers @{Host='asismacrm.duckdns.org'}`.
  Al enviar JSON con tildes desde PowerShell 5.1, pasar el body como bytes UTF-8.
- Datos demo: `database/seeds_demo.sql` (usuarios `demo1234`, ver docs/DEMO.md);
  limpieza con `database/limpiar_demo.sql`.
- BD directa: `mysql.exe -u root -p<pass de .env.php> asisma_crm`.
