# Roadmap de activación SII y facturación electrónica

## Objetivo y estado

Habilitar la emisión de DTE desde Sapira, primero en certificación (`maullin.sii.cl`) y luego en producción (`palena.sii.cl`), manteniendo a `api-factura` como único motor tributario.

**Leyenda:** `[x]` implementado en código; `[~]` parcialmente implementado o pendiente de validación integrada; `[ ]` pendiente.

La validación operacional paso a paso está en la [Guía de pruebas de certificación y facturación](./guia_pruebas_certificacion.md).

## Arquitectura objetivo

```mermaid
flowchart LR
  Usuario[UsuarioSapira] --> Front[front-sapira]
  Front --> BFF["BFF /api/factura"]
  BFF --> Factura[api-factura]
  Factura --> SII["SII maullin o palena"]
  Factura --> Mongo[(MongoDB)]
```

- `api-factura` custodia certificados, CAF, folios, DTE firmados, envíos y estados SII.
- La empresa efectiva se obtiene de `request.user.empresaId` en el JWT de `api-factura`; no debe provenir del body ni de headers controlados por el cliente.
- La provisión de una empresa Sapira se realiza mediante `POST /empresas/provision`, protegido con `x-service-auth` y `SERVICE_AUTH_TOKEN`.
- Las rutas HTTP de `api-factura` no tienen prefijo global: por ejemplo, `POST http://localhost:9005/dte/createDte`. La referencia Swagger está en `/api`.

## Fase 1: motor SII

### [x] Ambiente SII por empresa

- **Implementación:** `CertificationProfile.environment` selecciona `certificacion` o `produccion`; `DteService.getSiiBaseUrl()` resuelve Maullín o Palena.
- **API:** `GET|PATCH /sii/certification-profile`.
- **Verificación:** configurar `environment: "certificacion"` y confirmar que la obtención de token se dirige a Maullín. Probar producción solo con una empresa autorizada.

### [x] Token SII, SetDTE y firma

- **Implementación:** `SiiAuthService` obtiene semilla, firma la solicitud con el certificado de la empresa, obtiene/reutiliza el token y lo persiste con expiración.
- **API:** `GET /sii/auth/token`, `/sii/auth/valid-token`, `/sii/auth/validate-token` y `/sii/auth/regenerate-token`.
- **Envío:** `DteService.getSetDTE()` arma carátula y subtotales con DTEs firmados de la empresa.
- **Verificación:** `GET /sii/auth/valid-token` devuelve un token válido después de cargar un certificado válido.

### [x] Envío y consulta de estado

- **Implementación:** `POST /dte/sendDte` genera `EnvioDTE`, publica en `DTEUpload`, persiste `trackId` y deja `estadoSii: ENVIADO`. `GET /dte/:id/estado` consulta `QueryEstUp` y persiste estado, glosa y fecha.
- **Verificación:** enviar un DTE de certificación, confirmar `trackId` y consultar hasta obtener el estado informado por SII.

### [x] Foliación segura y aislamiento por empresa

- **Implementación:** `FolioService.reserveNextAvailable()` reserva atómicamente el menor folio disponible y lo libera ante error. DTE, CAF y folios se filtran por `empresaId`.
- **API:** `POST /caf/upload`, `GET /caf`, `GET /folios`, `POST /dte/createDte` y `GET /dte`.
- **Verificación:** cargar CAF, emitir un DTE y corroborar que el folio pasa de `available` a `used`; verificar que otra empresa no accede a sus recursos.

### [~] Validación automatizada integrada

- **Hecho:** validación XML/XSD y pruebas unitarias de reserva atómica y selección de ambiente.
- **Pendiente:** pruebas de integración con dobles de SII para semilla, token, `DTEUpload` y `QueryEstUp`, incluidos errores, reintentos y aislamiento entre empresas.
- **Criterio de salida:** la suite cubre éxito y error de autenticación, CAF, foliación, creación, envío y consulta sin depender del SII real.

**Salida:** un DTE de prueba obtiene TrackId y estado reales en maullin.

## Fase 2: Sapira

### [x] Bridge de identidad y provisión

- `Empresa` mantiene solo datos tributarios; `IntegratorLink` registra opcionalmente la referencia externa. `POST /empresas/provision` es idempotente por `(integratorSlug, externalCompanyId)` y evita cambiar el tenant vinculado.
- **Verificación:** provisionar dos veces la misma empresa Sapira y confirmar que retorna el mismo `_id` de `api-factura`.

### [x] Experiencia de configuración

- Selector persistente de empresa y wizard de seis pasos: empresa, datos tributarios, ambiente, certificado, CAF y verificación.
- Formularios para perfil de certificación, PFX/P12, CAF, folios, DTE, envío y consulta.
- **Verificación:** recorrer el onboarding con una empresa de prueba y completar cada paso con resultados reales de API.

### [~] Contrato BFF con `api-factura`

Antes de declarar esta fase terminada se deben conciliar estos contratos:

1. `[ ]` El BFF usa rutas `/companies` y `/companies/:id/onboarding`, mientras el controlador real expone `/empresas`; adaptar a un contrato único.
2. `[x]` El BFF usa OAuth2 `client_credentials` de corta duración y `api-factura` autoriza llamadas de servicio por scopes.
3. `[x]` `GET /api/factura/dte/:id/estado` reenvía identidad de empresa.
4. `[ ]` Retirar o corregir `POST /dte/addInvoice`: su contrato de archivo no coincide con `sendDTE`, que espera `dteId` o `dteIds`.

**Salida:** un usuario autenticado completa el onboarding y opera el flujo de certificación sin exponer la API SII al navegador.

## Fase 3: certificación formal

### [ ] Ejecutar el set de pruebas

1. Configurar datos del contribuyente y tipos de DTE autorizados.
2. Crear payloads reproducibles por caso y registrar XML, TrackId, estado y evidencia SII.
3. Ejecutar los casos aplicables de ventas y compras: afectos, exentos, notas de crédito y notas de débito.

### [ ] Volumen, intercambio y evidencia

1. Automatizar simulaciones de 10, 50 y 100 documentos según exija SII.
2. Implementar recepción de DTE, acuse de recibo y aceptación/rechazo.
3. Generar muestras impresas con PDF417 y validar su contenido contra el XML.
4. Preparar declaración del representante legal y paquete de evidencias.

## Fase 4: producción

### [ ] Habilitación controlada

1. Confirmar autorización formal de la empresa.
2. Cambiar solo su perfil a `environment: "produccion"` y validar token contra Palena.
3. Cargar CAF de producción sin mezclarlo con folios de certificación.
4. Ejecutar una emisión controlada y cuadrar resultado SII con el registro local.

### [ ] Resiliencia y operación

1. Implementar reintentos idempotentes para autenticación, envío y consulta, con backoff y trazabilidad.
2. Definir contingencia cuando SII no responda: cola, reintento y comunicación operacional.
3. Implementar cuadratura diaria de DTE, folios, estados SII y XML.
4. Mantener respaldos, retención, custodia cifrada y auditoría de accesos.
5. Alertar vencimiento de certificado, agotamiento de CAF, errores de envío y DTE pendientes.

### [ ] Hardening de certificados digitales (custodia y upload PFX)

**Estado actual (2026-03):** los certificados se procesan con OpenSSL y se persisten en **filesystem local** (`certificates/{RUT}/`); **no** se usa Azure Blob Storage en el código vigente, aunque la dependencia esté instalada.

**Objetivo:** custodia apta para producción multi-tenant.

1. `[ ]` **Fase A — Hardening mínimo:** eliminar `shell.exec`, sanitizar filenames, rollback en error, endurecer cifrado, tests de upload.
2. `[ ]` **Fase B — Key Vault:** importar PFX a Azure Key Vault; Mongo solo metadata (`thumbprint`, versión); firma vía KV; eliminar PEM/PFX en disco del pod.
3. `[ ]` **Fase C — Operación:** auditoría de subidas, rotación, alertas de vencimiento integradas.

**Documentos de referencia:**

- [Auditoría QA/seguridad — certificados digitales](../../../../../../api-factura/docs/auditoria-certificados-digitales.md)
- [Plan de implementación Key Vault + Blob](../../../../../../api-factura/docs/plan-custodia-keyvault-blob.md) ← **ejecutar por sprints**

**Nota Blob vs Key Vault:** Blob Storage (cifrado con CMK) es adecuado para CAF/XML/PDF; el **material de firma** (clave privada) debe vivir en **Key Vault** o HSM, no en blob en claro.

## Checklist de salida SII

- Certificado tributario vigente y firmante autorizado.
- CAF válido y folios disponibles.
- DTE validado, timbrado y firmado.
- Envío recibido por SII y seguimiento por TrackId.
- Conservación de XML y estados por empresa.

## Matriz de control

| Ítem | API o componente | Estado | Cómo verificar |
| --- | --- | --- | --- |
| Perfil y ambiente | `PATCH /sii/certification-profile` | [x] | Paso 3 de la guía |
| Certificado | `POST /certificates/upload` | [x] | Paso 4 |
| CAF y folios | `POST /caf/upload`, `GET /folios` | [x] | Paso 5 |
| Token SII | `GET /sii/auth/valid-token` | [x] | Paso 6 |
| DTE firmado | `POST /dte/createDte` | [x] | Paso 7 |
| Envío y TrackId | `POST /dte/sendDte` | [x] | Paso 8 |
| Estado SII | `GET /dte/:id/estado` | [x] | Paso 9 |
| Bridge BFF | `front-sapira` → `api-factura` | [~] | Apéndice B de la guía |
| Set formal SII | Casos de certificación | [ ] | Apéndice C de la guía |
| Producción | Palena y operación | [ ] | Fase 4 |
