# Veltrix POS SaaS (Base MVP)

Plataforma POS multiempresa en PHP + PDO + MySQL con arquitectura modular, preparada para escalar por fases.

## Stack base

- PHP 8.1+
- MySQL 8+
- PDO (consultas preparadas)
- Bootstrap 5
- Arquitectura modular MVC

## Funcionalidades implementadas en esta base

### Núcleo SaaS

- Login seguro con `password_hash`/`password_verify`
- Control de sesión con timeout
- Bloqueo temporal por intentos fallidos de login
- CSRF automático en métodos `POST/PUT/DELETE`
- Control de permisos por middleware
- Multiempresa por sesión (`tenant_id`)
- Registro de empresa con creación de usuario administrador
- Logs de actividad
- API interna base (`/api/health`, `/api/me`, `/api/metrics`)

### Módulos POS (Fase 1 + avance Fase 2)

- Dashboard con métricas rápidas
- Usuarios
- Categorías
- Productos
- Inventario (stock + kardex de movimientos)
- Inventario con traslado entre sucursales
- Proveedores
- Compras (entrada automática a inventario)
- Cuentas por pagar (pagos de compra, saldo y estado pendiente/parcial/pagada)
- Clientes
- Caja (apertura/cierre)
- POS (carrito y venta rápida)
- POS con venta de contado y credito (abono inicial)
- Alerta en POS por agotamiento de rango DIAN en numeración activa
- Ventas (listado y anulación)
- Impresión de factura desde historial de ventas
- Facturación completa por venta (nota crédito, nota débito, anulación documental y trazabilidad)
- Impresión de ticket fiscal y descarga de factura (PDF con fallback imprimible)
- Reportes operativos (ventas, utilidad, inventario, caja, clientes, CxC/CxP)
- Reportes de control (utilidad por sucursal, kardex por rango y ventas por método de pago)
- Cuentas por cobrar (saldos, abonos, filtros, antiguedad 0-30/31-60/61-90/91+ y exportación CSV/XLSX/PDF)
- Sucursales (CRUD + asignación de usuarios y cajas por sede)
- POS restringido por sucursal/caja asignada al usuario
- Inventario avanzado con ajustes por sucursal (motivo obligatorio + aprobación/rechazo + auditoría)
- Compras avanzadas (orden de compra + recepción parcial con entrada automática a inventario)
- Configuración de empresa (datos generales, fiscal base, impuestos, métodos de pago, numeraciones y resoluciones DIAN por sucursal)
- Emisión automática de factura de venta con consecutivo por sucursal
- Gestión de permisos por rol (matriz editable por módulo)
- Selector de empresa activa
- Panel superadmin SaaS (planes con límites, estado de empresas, suscripciones y pagos)
- Bloqueo automático de acceso por suscripción vencida/morosa
- Onboarding SaaS con Wompi (checkout + webhook + aprovisionamiento automático de empresa y usuario admin)
- Onboarding SaaS público end-to-end con estado en tiempo real del checkout y acceso inmediato por URL de empresa
- Bandeja superadmin de checkouts no provisionados con reproceso de webhook
- Soporte superadmin (tickets por empresa + historial de atención)
- Automatización diaria de suscripciones (vencida/morosa + bloqueo + avisos de cobro)
- Notificaciones de cobro reales por email/WhatsApp con reintentos automáticos (backoff + límite de intentos)
- SLA de soporte (primera respuesta/resolución), métricas y reportes por empresa/agente

## Estructura

```text
app/
  controllers/
  models/
  views/
  middleware/
  helpers/
  services/
  repositories/
  policies/
  core/
config/
routes/
database/
public/
modules/
storage/
```

## Instalación

1. Configura el virtual host o abre `http://localhost/veltrix/public`.
2. Crea la BD MySQL:
   - nombre recomendado: `veltrix_pos`
3. Ajusta credenciales en `.env`.
   - Para bloqueo automático por mora/vencimiento define `SAAS_MORA_DAYS` (ejemplo: `3`).
4. Importa esquema:

```sql
SOURCE database/sql/schema.sql;
```

5. Ejecuta seeders en orden:

```sql
SOURCE database/seeders/001_roles_permissions.sql;
SOURCE database/seeders/002_plans.sql;
SOURCE database/seeders/004_catalogos_base.sql;
SOURCE database/seeders/005_ciudades_base.sql;
SOURCE database/seeders/003_superadmin.sql;
```

6. Si vienes de una versión previa, aplica migraciones nuevas:

```sql
SOURCE database/migrations/007_add_branch_scope_facturacion.sql;
SOURCE database/migrations/008_facturacion_inventario_compras_avanzado.sql;
SOURCE database/migrations/009_saas_checkout_wompi.sql;
SOURCE database/migrations/010_global_wompi_settings.sql;
SOURCE database/migrations/011_subscription_automation.sql;
SOURCE database/migrations/012_support_tickets.sql;
SOURCE database/migrations/013_notification_retries.sql;
SOURCE database/migrations/014_support_sla.sql;
SOURCE database/migrations/015_harden_superadmin_permissions.sql;
SOURCE database/migrations/016_ai_help_history.sql;
SOURCE database/migrations/017_ai_help_sessions.sql;
SOURCE database/migrations/018_add_dane_city_metadata.sql;
SOURCE database/migrations/019_expand_currency_catalog.sql;
SOURCE database/migrations/020_create_producto_variantes.sql;
SOURCE database/migrations/021_add_cantidad_producto_variantes.sql;
SOURCE database/migrations/022_add_stock_minimo_producto_variantes.sql;
SOURCE database/migrations/023_add_unique_sku_productos.sql;
SOURCE database/migrations/024_add_variant_columns_to_purchase_flows.sql;
SOURCE database/migrations/025_add_variant_columns_to_inventory_flows.sql;
SOURCE database/migrations/026_create_notificacion_vistas.sql;
SOURCE database/migrations/027_subscription_pre_due_notices.sql;
SOURCE database/migrations/028_create_whatsapp_meta_templates.sql;
SOURCE database/migrations/029_expand_whatsapp_template_links.sql;
```

7. Asigna permisos nuevos (si ya tenías la BD en producción/desarrollo):

```sql
SOURCE database/seeders/001_roles_permissions.sql;
```

## Catálogo DANE (País y Ciudad relacionados)

Para que `País` y `Ciudad` salgan desde el catálogo oficial de Colombia (DANE/DIVIPOLA):

1. Aplica la migración DANE:

```sql
SOURCE database/migrations/018_add_dane_city_metadata.sql;
```

2. Importa automáticamente desde API oficial DANE:

```bash
/Applications/XAMPP/xamppfiles/bin/php scripts/import_dane_divipola_api.php --replace
```

3. (Opcional) Si prefieres archivo local CSV DIVIPOLA, usa:

```bash
/Applications/XAMPP/xamppfiles/bin/php scripts/import_dane_divipola.php /ruta/archivo_divipola.csv --replace
```

Notas:
- `--replace` limpia primero las ciudades de Colombia para recargar catálogo limpio.
- Si tu CSV usa otro separador, agrega `--delimiter=';'` o `--delimiter=','`.
- El sistema carga las ciudades en `ciudades` y las relaciona con `paises` (`CO`), para usarlas en dropdown dependiente por país.

## Credenciales iniciales

- Usuario: `admin@veltrix.com`
- Clave: `Admin12345*`

Cambia esta clave inmediatamente en ambiente real.

## Variables de entorno SaaS + Wompi

Configura estas variables en `.env` para habilitar onboarding automático por pago:

```env
SAAS_MORA_DAYS=3
SAAS_PAID_CYCLE_DAYS=30

WOMPI_PUBLIC_KEY=pub_test_...
WOMPI_INTEGRITY_SECRET=test_integrity_...
WOMPI_EVENTS_SECRET=test_events_...
WOMPI_CHECKOUT_URL=https://checkout.wompi.co/p/
WOMPI_CURRENCY=COP

NOTIFY_EMAIL_FROM_NAME=\"Veltrix POS\"
NOTIFY_EMAIL_FROM_ADDRESS=no-reply@tu-dominio.com
NOTIFY_EMAIL_REPLY_TO=soporte@tu-dominio.com
NOTIFY_CHANNEL_EMAIL=true

WHATSAPP_API_URL=https://graph.facebook.com/v20.0
WHATSAPP_PHONE_NUMBER_ID=
WHATSAPP_ACCESS_TOKEN=
WHATSAPP_DEFAULT_COUNTRY_CODE=57
NOTIFY_CHANNEL_WHATSAPP=true

NOTIFY_MAX_ATTEMPTS=3
NOTIFY_RETRY_BACKOFF_MINUTES=5,30,180

AI_ENABLED=false
AI_PROVIDER=openai
AI_OPENAI_API_KEY=
AI_OPENAI_BASE_URL=https://api.openai.com/v1
AI_MODEL=gpt-4o-mini
AI_TEMPERATURE=0.2
AI_MAX_OUTPUT_TOKENS=700
AI_CHAT_IDLE_TIMEOUT_MINUTES=5
AI_CHAT_HISTORY_LIMIT=80
AI_CHAT_CONTEXT_HISTORY_LIMIT=12
```

Luego configura en Dashboard de Wompi tu URL de eventos (webhook):

`https://tu-dominio/veltrix/public/webhooks/wompi`

Variables recomendadas para hardening de producción:

```env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://tu-dominio/veltrix/public

SESSION_SECURE_COOKIE=true
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=Lax

FORCE_HTTPS=true
SECURITY_HEADERS_ENABLED=true
SECURITY_X_FRAME_OPTIONS=SAMEORIGIN
SECURITY_X_CONTENT_TYPE_OPTIONS=nosniff
SECURITY_REFERRER_POLICY=strict-origin-when-cross-origin
SECURITY_PERMISSIONS_POLICY=geolocation=(), microphone=(), camera=()
SECURITY_X_PERMITTED_CROSS_DOMAIN_POLICIES=none
SECURITY_CROSS_ORIGIN_OPENER_POLICY=same-origin-allow-popups
SECURITY_CROSS_ORIGIN_RESOURCE_POLICY=same-site

HSTS_ENABLED=true
HSTS_MAX_AGE=31536000
HSTS_INCLUDE_SUBDOMAINS=true
HSTS_PRELOAD=false
```

También puedes guardar/actualizar estas 3 llaves directamente desde `Superadmin`:

- `WOMPI_PUBLIC_KEY`
- `WOMPI_INTEGRITY_SECRET`
- `WOMPI_EVENTS_SECRET`
- Incluye botón para `Probar conexión Wompi` y botones para `Limpiar llave` por campo.

## Seguridad incluida

- PDO preparado para evitar SQL Injection
- Escape HTML con helper `e()` para prevenir XSS básico
- CSRF token por formulario
- Session timeout configurable
- Cookie de sesión endurecida (`Secure`, `HttpOnly`, `SameSite`)
- Redirección opcional forzada a HTTPS (`FORCE_HTTPS`)
- Headers globales de seguridad (`X-Frame-Options`, `nosniff`, `Referrer-Policy`, etc.)
- Permisos por middleware
- Logs de actividad por usuario/empresa

## QA y backups operativos

- Prueba rápida de flujos críticos:

```bash
/Applications/XAMPP/xamppfiles/bin/php scripts/qa_critical_flows.php
```

- QA de producción y seguridad operativa:

```bash
/Applications/XAMPP/xamppfiles/bin/php scripts/qa_production_security.php
```

- Rotar clave inicial de `admin@veltrix.com`:

```bash
/Applications/XAMPP/xamppfiles/bin/php scripts/rotate_default_admin_password.php
```

- Automatización diaria de suscripciones (manual):

```bash
/Applications/XAMPP/xamppfiles/bin/php scripts/subscription_daily_automation.php
```

- Reintento manual de avisos de cobro pendientes/fallidos:

```bash
/Applications/XAMPP/xamppfiles/bin/php scripts/subscription_notice_retry.php 200
```

- Backup manual de base de datos:

```bash
./scripts/backup_db.sh
```

- Ejemplo de programación automática (cron cada 6 horas):

```cron
0 */6 * * * /Applications/XAMPP/xamppfiles/htdocs/veltrix/scripts/backup_db.sh >> /Applications/XAMPP/xamppfiles/htdocs/veltrix/storage/logs/backup.log 2>&1
```

- Ejemplo de cron para automatización SaaS diaria (2:00 AM):

```cron
0 2 * * * /Applications/XAMPP/xamppfiles/bin/php /Applications/XAMPP/xamppfiles/htdocs/veltrix/scripts/subscription_daily_automation.php >> /Applications/XAMPP/xamppfiles/htdocs/veltrix/storage/logs/subscription_automation.log 2>&1
```

- Ejemplo de cron para reintento de avisos cada 15 minutos:

```cron
*/15 * * * * /Applications/XAMPP/xamppfiles/bin/php /Applications/XAMPP/xamppfiles/htdocs/veltrix/scripts/subscription_notice_retry.php 200 >> /Applications/XAMPP/xamppfiles/htdocs/veltrix/storage/logs/subscription_notice_retry.log 2>&1
```

## Próximas fases sugeridas

1. Reportes avanzados + cierres con arqueo detallado
2. Suscripciones automáticas + pasarelas de pago
3. Facturación electrónica DIAN como módulo desacoplado
4. Multi-sucursal avanzada con inventario por sede
5. Integraciones API externas y app móvil

## Rutas clave

- `/login`
- `/registro-empresa`
- `/{slug}` (acceso corto por empresa, por ejemplo `/hunolabs`)
- `/empresa/{slug}`
- `/suscripcion/resultado`
- `/suscripcion/estado` (GET, polling de estado checkout)
- `/dashboard`
- `/pos`
- `/caja`
- `/ventas`
- `/reportes`
- `/sucursales`
- `/configuracion`
- `/cuentas-cobrar`
- `/cuentas-cobrar/exportar`
- `/cuentas-cobrar/exportar-xlsx`
- `/cuentas-cobrar/exportar-pdf`
- `/usuarios`
- `/inventario`
- `/compras`
- `/proveedores`
- `/productos`
- `/clientes`
- `/superadmin`
- `/webhooks/wompi` (POST, webhook Wompi)
- `/webhooks/bold` (POST, webhook Bold)
- `/webhooks/credibanco` (POST, webhook Credibanco Datáfono)

## Notas

- Esta entrega deja una base sólida para continuar el desarrollo por bloques (Operación, Administración, SaaS).
- El diseño privilegia extensibilidad y separación de responsabilidades.
