# Mapeo Derafu → api-a-conta-fact

DTEengine usa la librería `Derafu` (de LibreDTE) para construir, firmar y validar XMLs DTE. En `api-a-conta-fact` decidimos **no instalar Derafu** (decisión documentada en `PLAN_MIGRACION.md` §2). Este documento explica qué reemplaza cada componente.

## Por qué no Derafu

1. **Licencia AGPL** de LibreDTE (de quien proviene Derafu) — riesgo legal para producto comercial cerrado.
2. **Dependencias modernas** — Derafu apunta a PHP/Laravel modernos. Aunque hoy `api-a-conta-fact` corre PHP 8.2 (compatible), Laravel 9 tiene incompatibilidades con varios paquetes Derafu transitivos.
3. **Reducción de superficie** — usar herramientas nativas de PHP nos obliga a entender el formato exacto del SII en vez de delegar.

## Tabla de reemplazos

| Paquete Derafu | Función en DTEengine | Cómo lo reemplazamos | Archivo |
|---|---|---|---|
| `Derafu\Xml\Service\XmlEncoder` | Array → XML string | **String concatenation manual** | `DteXmlBuilder`, `EnvelopeService` |
| `Derafu\Xml\Service\XmlDecoder` | XML → array | `DOMDocument` + `SimpleXMLElement` | `CafService::parsearCaf` |
| `Derafu\Xml\XmlDocument` | Wrapper de `DOMDocument` | `DOMDocument` nativo | varios |
| `Derafu\Xml\Service\XmlService` | Canonicalización C14N | `DOMDocument::C14N(false, false)` | `TedBuilder` |
| `Derafu\Xml\Service\XmlValidator` | Validación XSD local | **No tenemos equivalente** ⚠️ | gap pendiente |
| `Derafu\Certificate\Service\CertificateLoader` | Carga PFX | `openssl_pkcs12_read()` + workaround OpenSSL 3 legacy | `CertificateService` |
| `Derafu\Certificate\Contract\CertificateInterface` | Abstracción cert | `array` con `private_key`/`certificate`/`metadata` | DTOs en motor |
| `Derafu\Signature\Service\SignatureGenerator` | Firma XML enveloped | `robrichards/xmlseclibs` (`XMLSecurityDSig`) | `XmlSignatureService` |
| `Derafu\Signature\Service\SignatureValidator` | Validar firma propia | **No tenemos equivalente** ⚠️ | gap pendiente |
| `Derafu\Signature\Service\SignatureService` | Wrapper firma | `XmlSignatureService` propio | motor |

## Equivalencia funcional verificada

| Función | Cómo verificamos paridad |
|---|---|
| Canonicalización C14N | Comparación byte-a-byte de `<DD>` antes de firmar vs fixtures DTEngine |
| Firma TED (SHA1withRSA) | Verificación de `<FRMT>` con `openssl_verify` usando RSAPK del CAF |
| Firma XML DTE (RSA-SHA1 enveloped) | `XMLSecurityDSig::verify()` sobre XML firmado |
| Encoding ISO-8859-1 | Conversión explícita UTF-8 → ISO-8859-1 en `DteXmlBuilder::escIso()` |

## Gaps reales vs Derafu (lo que perdemos)

### 🔴 Validación XSD local

Derafu valida el XML contra los XSDs oficiales del SII (`EnvioDTE_v10.xsd`, `EnvioBOLETA.xsd`, `DTE_v10.xsd`) **antes** de enviarlo. Si falla, no se envía — ahorra trackids quemados.

Nosotros enviamos directo. Si el SII rechaza por schema, descubrimos el problema en la respuesta.

**Mitigación temporal:** comparar contra `DTEengine/fuente-verdad/certificacion/*.xml` con diff estructural antes de enviar.

**Solución futura:** instalar solo `derafu/xml` (paquete pequeño y permisivamente licenciado individual) **o** implementar validación XSD con `DOMDocument::schemaValidate()` + descargar XSDs oficiales del SII.

### 🔴 Auto-validación de firma

Derafu re-verifica la firma que acaba de generar. Nosotros no.

**Mitigación:** después de firmar, hacer `XMLSecurityDSig::verify()` sobre el resultado en modo dev.

### 🟡 String concatenation frágil

Construir XML con concatenación es propenso a errores con:
- Caracteres especiales (ñ, tildes, &, <, >, ")
- Whitespace inconsistente
- Atributos en orden distinto

**Mitigación actual:**
- `escIso()` en `DteXmlBuilder` convierte UTF-8 → ISO-8859-1 + `htmlspecialchars`.
- TED se canonicaliza con `DOMDocument::C14N()` antes de firmar (no string).

**Pendiente:** asegurar que `EnvelopeService` use la misma `escIso()` que `DteXmlBuilder` (hoy `DteEmissionService::buildEnvio()` usa `htmlspecialchars` sin conversión UTF→ISO — bug latente cuando emisor/firmante tiene tildes).

## Decisión de fallback

Si en certificación SII rechazamos por estructura/firma 2-3 veces sin poder resolverlo con diagnóstico contra DTEengine, evaluar instalar **solo** `derafu/xml` (no LibreDTE completo, no Derafu\Signature) como reemplazo de la capa de construcción/canonicalización. Es el paquete con menor superficie y sin licencia AGPL transitiva problemática.
