UBL 2.1
Où injecter le modèle dans l'UBL ?
L'export Ublime est un seul fichier JSON qui contient à la fois la feuille XSL compilée et la palette — exactement ce qui s'embarque dans l'UBL. À l'empaquetage, ces deux champs deviennent deux pièces jointes UBL distinctes (ublime-xsl et ublime-palette), toujours issues du même export.
Format d'export : `ublime-template.json`
Après compilation dans le studio, l'export pour intégration ressemble à ceci. Pas de fichier séparé pour la palette — c'est voulu.
{
"version": 1,
"xsl": "<xsl:stylesheet version=\"1.0\">…</xsl:stylesheet>",
"palette": {
"colors": [{ "nom": "Indigo", "hex": "#6366f1" }],
"roles": { "titre": 0, "texte": 0, "…": 0 }
}
}
Ce format est distinct du modèle éditable (ublime-modele.json, arbre de blocs pour rouvrir le studio ou tester dans la démo). Seulublime-template.json est prêt à embarquer dans une facture.
Chaîne de transformation
- ①Studio → composition visuelle, puis compilation WASM /
ublime-template::compile - ②Export → un fichier
ublime-template.jsonavec les champs xsl et palette - ③Empaquetage UBL →
ublime_ubl::embed_attachments découpe l'export en deuxAdditionalDocumentReference (Base64), avant les parties - ④Rendu → ré-extraction du XSL depuis l'UBL, revalidation, puis
ublime-render + variables CSS issues de la palette embarquée
Les deux pièces jointes Ublime
L'UBL ne porte pas le JSON d'export tel quel : il le éclateen deux pièces jointes standard, chacune identifiée par soncbc:ID, avec le contenu encodé en Base64.
| cbc:ID | Contenu | mimeCode | Obligatoire |
|---|
| ublime-xsl | Feuille de mise en page Champ `xsl` du fichier d'export | application/xslt+xml | Oui |
| ublime-palette | Palette de couleurs Champ `palette` du même fichier d'export | application/json | Non |
Le logo du gabarit est compilé dans la feuille XSL (data URI validé), pas comme troisième pièce jointe UBL — choix de sûreté documenté dans le projet.
Structure XML (extrait)
Les pièces jointes sont placées au niveau racine Invoice, immédiatement avantcac:AccountingSupplierParty (contrainte de séquence UBL). Le contenu binaire est en Base64 danscbc:EmbeddedDocumentBinaryObject.
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:ID>F-2026-001</cbc:ID>
<cbc:IssueDate>2026-07-27</cbc:IssueDate>
<!-- ① Feuille compilée (OBLIGATOIRE pour le rendu Ublime) -->
<cac:AdditionalDocumentReference>
<cbc:ID>ublime-xsl</cbc:ID>
<cac:Attachment>
<cbc:EmbeddedDocumentBinaryObject
mimeCode="application/xslt+xml"
filename="ublime.xsl">
PHg6c3RsO...Base64DuXSL...==
</cbc:EmbeddedDocumentBinaryObject>
</cac:Attachment>
</cac:AdditionalDocumentReference>
<!-- ② Palette (OPTIONNELLE — couleurs / rôles) -->
<cac:AdditionalDocumentReference>
<cbc:ID>ublime-palette</cbc:ID>
<cac:Attachment>
<cbc:EmbeddedDocumentBinaryObject
mimeCode="application/json"
filename="palette.json">
eyJjb2xvcnMiO...Base64DuJSON...==
</cbc:EmbeddedDocumentBinaryObject>
</cac:Attachment>
</cac:AdditionalDocumentReference>
<cac:AccountingSupplierParty>...</cac:AccountingSupplierParty>
<!-- … reste de la facture EN16931 … -->
</Invoice>
Intégration serveur (POC)
Le binaire ublime-server expose trois endpoints utiles :
POST /api/compile — blocs JSON → XSL + rapport champs obligatoires manquantsPOST /api/package — UBL de référence + surcharges émetteur + XSL (+ palette) → UBL scellé avec pièces jointesPOST /api/render — UBL → ré-extraction XSL, validation, HTML + variables CSS palette
En pur client (studio / démo WASM), la compilation et le rendu suivent la même logique sans passer par HTTP — seule la source du XSL change (calculé en mémoire vs extrait de l'UBL).
Comment garantir l'intégrité ?
L'intégrité couvre deux niveaux : le template embarqué (personne ne substitue une feuille dangereuse) et le dossier de facture (preuve qu'un UBL n'a pas été altéré en transit).
1Export en un seul fichier
Le template exporté regroupe délibérément XSL et palette dans un même JSON (`ublime-template.json`). Deux fichiers séparés ouvriraient le mode d'échec « j'ai embarqué la feuille et oublié la palette », qui produirait silencieusement des factures sans couleurs.
2Identification par `cbc:ID`, pas par position
L'extraction cherche un `AdditionalDocumentReference` dont le `cbc:ID` vaut `ublime-xsl` ou `ublime-palette`. L'ordre des pièces jointes dans l'UBL ne change pas ce qui est interprété comme feuille ou palette.
3Vérifier-avant-rendu
À chaque rendu (`/api/render` ou preview), le XSL est ré-extrait depuis l'UBL, puis repasse `ublime_xsl::validate`. Un document trafiqué avec une feuille malveillante est rejeté — on ne rend jamais depuis un XSL « en cache » hors UBL.
4Liste blanche Ublime-XSL
Seuls HTML/XSL sûrs sont autorisés : pas de `style=` inline, pas de `<script>`, pas de XPath arbitraire injecté par l'auteur du template. La compilation revalide la feuille produite (défense en profondeur).
5Palette validée à l'empaquetage
Lors du scellement (`/api/package`), une palette invalide fait échouer la requête. Au rendu, une palette absente ou illisible est tolérée (couleurs par défaut) — la facture doit pouvoir s'afficher même si la pièce jointe palette manque.
6Échappement XML et Base64
Les données métier de la facture sont échappées à la construction UBL. Les pièces jointes template/palette sont encodées en Base64 dans `EmbeddedDocumentBinaryObject`.
7Scellement de dossier (`ublime-evidence`)
Pour un flux de preuve complet, la crate `ublime-evidence` peut sceller un dossier (UBL original, HTML rendu, échanges PA) avec manifeste signé. Les pièces jointes Ublime dans l'UBL sont alors couvertes par le sceau du document.
Checklist intégrateur
- ✓Exporter un seul
ublime-template.json contenantxsl et palette. - ✓À l'empaquetage, mapper
.xsl →ublime-xsl et .palette →ublime-palette — ne jamais injecter le JSON d'export brut. - ✓Utiliser les identifiants exacts (sensibles à la casse).
- ✓Placer les
AdditionalDocumentReference avantAccountingSupplierParty. - ✓Au rendu, toujours ré-extraire le XSL depuis l'UBL reçu et le revalider.
- ✓Pour la preuve légale / PA, compléter avec le scellement
ublime-evidence sur le dossier complet.