# ARCA Hosting — Plataforma Integral de Gestión de Infraestructura
## Documento de Arquitectura (v1.0)

## 1. Visión

ARCA deja de ser un "CRM de hosting" y se concibe como el **núcleo operativo** de la empresa:
CRM + ERP + orquestador de infraestructura + pasarela de facturación electrónica + motor de
automatización. Debe operar en modo **multi-tenant** (varias empresas/marcas sobre la misma
instalación) sin depender de WHMCS, Blesta ni ningún framework PHP.

## 2. Principios de diseño

- **PHP puro 8.3**, arquitectura MVC propia, PSR-4 (autoload), PSR-3 (logging), PSR-7 (mensajes
  HTTP simplificados), PSR-12 (estilo de código).
- **SOLID** aplicado vía interfaces + inyección de dependencias manual (sin contenedor mágico,
  contenedor propio ligero).
- **Composer únicamente para librerías externas** (PHPMailer, Dompdf, Firebase JWT, PHP-CFDI,
  Guzzle si se requiere HTTP client robusto para APIs externas).
- **Todo acceso a datos vía PDO con prepared statements.** Cero SQL concatenado.
- **Multi-tenant desde el modelo de datos**: toda tabla operativa lleva `company_id`. Un
  middleware de "Tenant Context" inyecta el scope en cada consulta.
- **Cola de tareas (jobs) propia**: tabla `jobs` + worker CLI ejecutado por cron, para todo lo
  que no deba bloquear una petición HTTP (envío de correos, aprovisionamiento, timbrado CFDI,
  polling de monitoreo).
- **Sistema de plugins**: carpeta `plugins/`, cada uno con `plugin.json` (manifest) + hooks
  (`before_invoice_created`, `after_client_suspended`, etc.) registrados en un Event Dispatcher
  propio.

## 3. Capas del sistema

```
┌─────────────────────────────────────────────────────────┐
│  Portal Admin (Bootstrap 5)   │  Portal Cliente          │  API REST (JSON)
├─────────────────────────────────────────────────────────┤
│                     Core HTTP (Router / Controller)       │
├─────────────────────────────────────────────────────────┤
│  Servicios de dominio (Application Services)              │
│  - BillingService   - ProvisioningService                 │
│  - DomainService    - MonitoringService                    │
│  - TicketService    - BackupService                        │
│  - TenantService     - PluginManager                       │
├─────────────────────────────────────────────────────────┤
│  Adaptadores de Integración (cada uno tras una interfaz)   │
│  - cPanel/WHM API   - Cloudflare API   - Let's Encrypt      │
│  - ResellerPanel    - Stripe / PayPal / MercadoPago/OpenPay │
│  - PAC CFDI 4.0 (Finkok / SW Sapien / Facturama, etc.)      │
├─────────────────────────────────────────────────────────┤
│  Repositorios (Models) → PDO → MySQL 8                    │
├─────────────────────────────────────────────────────────┤
│  Cola de Jobs (tabla jobs + worker cron)                   │
│  Auditoría (tabla audit_log, write-only, append)           │
└─────────────────────────────────────────────────────────┘
```

## 3.1 Arquitectura interna (Fase 2.5)

Desde la Fase 2.5, toda peticion HTTP atraviesa siempre las mismas capas,
en el mismo orden, sin excepciones:

```
Request → Router → Middleware(s) → Controller → Service → Repository → PDO
                                        ↓
                                   Dispatcher → Listener(s) → AuditService/Logger
```

- **Router** resuelve el Controller via `App::make()` (Container), nunca
  con `new`. Esto es lo que permite que un Controller declare Services en
  su constructor y los reciba ya resueltos.
- **Controller**: valida la forma de la solicitud (CSRF, campos minimos
  presentes) e invoca **un** metodo de **un** Service. No contiene SQL ni
  reglas de negocio. No decide si algo "esta permitido" mas alla de lo que
  ya filtró `PermissionMiddleware` en la ruta.
- **Service**: toda la logica de negocio (validaciones de dominio,
  orquestacion entre varios Repositories, disparo de eventos). Un Service
  puede depender de otros Services (por ejemplo, `UserService` depende de
  `NotificationService`) y de Repositories, nunca al reves.
- **Repository**: unico lugar con SQL. Recibe `PDO` por constructor
  (inyectado por el Container como singleton, una sola conexion por
  peticion). No conoce reglas de negocio, solo CRUD y consultas.
- **Dispatcher/Events/Listeners**: un Service que crea una entidad
  disparara un evento (`ClientCreated`, `UserCreated`, etc.) en vez de
  llamar directo a la bitacora; `AuditTrailListener` es quien decide
  auditar. Esto permite agregar mas reacciones a "se creo un cliente"
  (notificar, sincronizar con un CRM externo, etc.) sin tocar
  `ClientService`.

### Diagrama de carpetas

```
arca-hosting/
├── api/v1/                    Estructura de la futura API (ver api/v1/README.md)
├── app/
│   ├── Contracts/              Interfaces de integraciones (Hosting, Dns, Ssl, Payment, Cfdi)
│   ├── Controllers/             Controllers del panel web (delgados)
│   │   └── Api/V1/               Controllers de la API REST (solo /ping activo)
│   ├── Core/                    Framework propio (Router, Container, Auth, Tenant, Config, ...)
│   │   ├── Cache/                 CacheInterface + FileCache
│   │   ├── Events/                 DTOs de eventos de dominio
│   │   ├── Listeners/               Reaccionan a eventos (AuditTrailListener)
│   │   └── Middleware/               AuthMiddleware, TenantMiddleware, PermissionMiddleware
│   ├── Integrations/            Adaptadores por proveedor externo (esqueleto, Fases 3-6)
│   ├── Jobs/                    Trabajos ejecutables por el worker de cola
│   ├── Repositories/            Unico acceso a datos (PDO)
│   ├── Services/                 Logica de negocio
│   ├── Views/                    Plantillas PHP + layout Bootstrap 5
│   └── bootstrap.php             Registra bindings del Container y listeners
├── bin/
│   └── queue-worker.php         Worker CLI de la cola (cron, no automatico)
├── config/                    Configuracion por archivo (app, database, security, ...)
├── database/
│   ├── schema.sql               Esquema base (Fase 1)
│   └── migrations/              002 (Fase 2), 003 (Fase 2.5), en orden
├── modules/                   Plugins instalables sin tocar el Core
├── public/
│   ├── index.php                Front controller del panel web
│   └── api.php                  Front controller de la API
├── routes/
│   ├── web.php                  Rutas del panel
│   └── api.php                  Rutas de la API
├── storage/
│   ├── cache/                    Archivos de FileCache
│   ├── logs/                     Logs tecnicos (Logger)
│   └── queue/                    Reservado para una futura cola basada en archivos
└── vendor/autoload.php         Autoload PSR-4 (manual o generado por Composer)
```

### Inyeccion de dependencias: ejemplo real

```php
// ClientController.php — el controlador NUNCA hace "new ClientService()"
final class ClientController extends Controller
{
    public function __construct(
        private readonly ClientService $clientService,
        private readonly ServiceService $serviceService,
    ) {}
    // El Container arma ambos objetos (y sus propios Repositories) al
    // resolver ClientController desde el Router.
}
```



Cada integración se define primero como **interfaz** dentro de `app/Contracts/`, y luego se
implementa en `app/Integrations/{Servicio}/`. Esto permite:
- Cambiar de pasarela de pago sin tocar el core (Strategy Pattern).
- Simular ("fake adapter") en pruebas sin llamar APIs reales.
- Agregar nuevos PACs de CFDI sin romper facturación.

Ejemplos de contratos:
- `HostingProviderInterface` → `provision()`, `suspend()`, `unsuspend()`, `terminate()`,
  `changePassword()`, `getUsage()`. Implementaciones: `CpanelWhmAdapter`,
  `ResellerPanelAdapter`.
- `DnsProviderInterface` → `createZone()`, `addRecord()`, `issueOrRenewCertificate()`.
  Implementación: `CloudflareAdapter` (incluye Cloudflare SSL/proxy),
  `LetsEncryptAdapter` (ACME v2, vía `acme-php-client` o llamada directa al protocolo).
- `PaymentGatewayInterface` → `charge()`, `createSubscription()`, `refund()`, `webhookVerify()`.
  Implementaciones: `StripeAdapter`, `PaypalAdapter`, `MercadoPagoAdapter`, `OpenPayAdapter`.
- `CfdiProviderInterface` → `stamp()` (timbrar), `cancel()`, `getPdf()`, `getXml()`.
  Implementación contra un PAC certificado por el SAT (el PAC concreto se decide en Fase 5;
  no se puede timbrar CFDI sin un PAC autorizado — el sistema no genera timbre fiscal por sí
  mismo, solo prepara el XML y delega el timbrado).

## 5. Monitoreo de servidores

Worker cron independiente (`bin/monitor-worker.php`) que cada N minutos:
1. Lee la tabla `servers`.
2. Hace ping/HTTP check de disponibilidad.
3. Si el servidor expone agente propio o SNMP/API de WHM, consulta CPU/RAM/disco.
4. Inserta en `server_metrics` (serie de tiempo ligera) y dispara alertas (`notifications`)
   si se cruzan umbrales configurables.

## 6. Multi-tenant

- Tabla `companies` (empresas/marcas). Cada usuario admin pertenece a una o más `companies`
  vía `company_user`.
- Cada tabla operativa (`clients`, `invoices`, `domains`, `services`, `tickets`, `servers`)
  lleva `company_id NOT NULL`.
- Un `TenantScope` (trait aplicado a los Models) agrega automáticamente
  `WHERE company_id = :tenant` a cada query, tomando el tenant activo desde la sesión/JWT.
- Los superadmins pueden cambiar de tenant ("impersonar" una empresa) desde el panel.

## 7. API REST

- Prefijo `/api/v1/`. Autenticación por API Key (tabla `api_keys`, hash + scopes) o JWT
  (para el portal de clientes SPA si se decide desacoplar el frontend a futuro).
- Recursos: `/clients`, `/invoices`, `/domains`, `/services`, `/tickets`, `/servers`.
- Rate limiting propio basado en tabla `api_rate_limits` (o Redis si se habilita más adelante).

## 8. Fases de desarrollo (roadmap completo)

| Fase | Alcance | Estado |
|---|---|---|
| **0** | Arquitectura, esquema BD completo, estructura de carpetas | ✅ Este documento |
| **1** | Core MVC, Auth (2FA-ready, CSRF, hash, intentos, bitácora), módulo Clientes | ✅ Entregado |
| **2** | Multi-tenant (companies + selector), Roles/Permisos granulares, módulo Servicios | ✅ Entregado |
| **2.5** | Fortalecimiento del Core: Services, Repositories, DI Container, Eventos, Colas, Config, Logger, Soft delete, UUID, esqueletos de API/Plugins/Integraciones | ✅ Entregado hoy |
| **3** | Dominios + adaptador Cloudflare + Let's Encrypt | Pendiente |
| **4** | Hosting + adaptador cPanel/WHM + ResellerPanel + Monitoreo de servidores | Pendiente |
| **5** | Facturación (cotizaciones, facturas, pagos) + CFDI 4.0 + PAC | Pendiente |
| **6** | Pasarelas de pago: Stripe, PayPal, MercadoPago, OpenPay + pagos recurrentes | Pendiente |
| **7** | Worker de cola en produccion, notificaciones automáticas reales, respaldos | Pendiente |
| **8** | Tickets de soporte, Portal de clientes | Pendiente |
| **9** | Endpoints reales de la API REST + autenticacion por api_keys | Pendiente |
| **10** | Reportes, dashboards avanzados, auditoría fina, documentación final (manuales, diagramas UML/ER) | Pendiente |

Cada fase se entrega con: SQL de migración, código completo (sin fragmentos "TODO"),
y actualización de este documento.

## 9. Notas de seguridad importantes

- Las credenciales de integraciones (API keys de cPanel, Cloudflare, pasarelas de pago) se
  guardan cifradas con `sodium_crypto_secretbox` (libsodium), nunca en texto plano ni en
  variables de entorno versionadas.
- El timbrado CFDI requiere un Proveedor Autorizado de Certificación (PAC) — el sistema no
  puede emitir CFDI válidos ante el SAT sin ese contrato externo; esto se documentará y
  configurará en la Fase 5 según el PAC que ARCA contrate.
