archivist: add example config.jsonc (banks, tax notices, invoices) with firstMatch extraction

This commit is contained in:
2026-10-31 11:05:08 +01:00
parent 105a762579
commit c5373da667
+156
View File
@@ -0,0 +1,156 @@
{
// Example configuration for the Archivist pipeline.
// Keys in English; extracted values and rendered file names are in
// French, as they appear in the source documents.
// ==========================================================================
// fields: declaration of every field handled by the rules.
// A missing mandatory field at the end of the pipeline marks the document
// invalid and routes it to pending/ for human review.
// "template" is a regular field: rules select the naming template with it.
// ==========================================================================
"fields": [
{ "name": "emittingCompany", "type": "string", "mandatory": true },
{ "name": "documentType", "type": "string", "mandatory": true },
{ "name": "date", "type": "string", "mandatory": true },
{ "name": "template", "type": "string", "mandatory": false },
{ "name": "bankAccount", "type": "string", "mandatory": false },
{ "name": "address", "type": "string", "mandatory": false },
{ "name": "reference", "type": "string", "mandatory": false }
],
// ==========================================================================
// rules: an ordered tree evaluated against the first-page text
// (firstPageText) and the fields already set or deleted by earlier rules.
//
// Each rule contains four keys:
// when (required): expr-lang expression; the rest of the rule runs only
// if it evaluates to true
// set : list of assignments
// { "field": "x", "value": <fixed value> } constant
// { "field": "x", "eval": "<expression>" } evaluated in the
// same context
// delete: list of field names to unset
// rules : child rules, evaluated in order only if the parent "when"
// matched; nesting is recursive
//
// Built-in helper: firstMatch(regex) returns the first match of the regex
// in the first-page text (first capture group when present).
// ==========================================================================
"rules": [
// --- Generic extraction, runs for every document -------------------------
// Emission date, e.g. "Paris, le 15/01/2026" -> "15/01/2026"
{
"when": "true",
"set": [
{ "field": "date", "eval": "firstMatch("[0-9]{2}/[0-9]{2}/[0-9]{4}")" }
]
},
// --- Bank statements (relevés de compte) ----------------------------------
{
"when": "firstPageText contains "Relevé de compte"",
"set": [
{ "field": "documentType", "value": "Relevé de compte" },
{ "field": "template", "value": "bank_statement" }
],
"rules": [
// Issuing bank
{
"when": "firstPageText contains "BRED"",
"set": [ { "field": "emittingCompany", "value": "BRED" } ]
},
{
"when": "firstPageText contains "Fortunéo"",
"set": [ { "field": "emittingCompany", "value": "Fortunéo" } ]
},
{
"when": "firstPageText contains "Crédit Mutuel"",
"set": [ { "field": "emittingCompany", "value": "Crédit Mutuel" } ]
},
// Personal accounts, matched on the account number printed on page 1
{
"when": "firstPageText contains "12345678901"",
"set": [ { "field": "bankAccount", "value": "Compte Thomas" } ]
},
{
"when": "firstPageText contains "98765432109"",
"set": [ { "field": "bankAccount", "value": "Compte joint" } ]
}
]
},
// --- Taxe d'habitation, one child rule per address ------------------------
{
"when": "firstPageText contains "Taxe d'habitation"",
"set": [
{ "field": "documentType", "value": "Taxe d'habitation" },
{ "field": "emittingCompany", "value": "DGFiP" },
{ "field": "template", "value": "tax_notice_housing" }
],
"rules": [
{
"when": "firstPageText contains "12 rue des Lilas"",
"set": [ { "field": "address", "value": "12 rue des Lilas, Paris" } ]
},
{
"when": "firstPageText contains "34 avenue Jean Jaurès"",
"set": [ { "field": "address", "value": "34 avenue Jean Jaurès, Bordeaux" } ]
}
]
},
// --- Avis d'impôt sur le revenu --------------------------------------------
{
"when": "firstPageText contains "Impôt sur le revenu" && firstPageText contains "avis d'imposition"",
"set": [
{ "field": "documentType", "value": "Avis d'impôt sur le revenu" },
{ "field": "emittingCompany", "value": "DGFiP" },
{ "field": "template", "value": "tax_notice_income" }
]
},
// --- Generic invoices (e-commerce and others) -----------------------------
{
"when": "firstPageText contains "Facture" && firstPageText contains "TVA"",
"set": [
{ "field": "documentType", "value": "Facture" },
{ "field": "template", "value": "invoice" },
// Invoice number, e.g. "Facture n° F-2026-0123" -> "F-2026-0123"
{ "field": "reference", "eval": "firstMatch("[Ff]acture n° ?([A-Za-z0-9-]+)")" }
],
// Fields that do not apply to invoices, in case an earlier rule
// set them
"delete": [ "bankAccount", "address" ],
"rules": [
{
"when": "firstPageText contains "Amazon"",
"set": [ { "field": "emittingCompany", "value": "Amazon" } ]
},
{
"when": "firstPageText contains "LDLC"",
"set": [ { "field": "emittingCompany", "value": "LDLC" } ]
},
{
"when": "firstPageText contains "Cdiscount"",
"set": [ { "field": "emittingCompany", "value": "Cdiscount" } ]
}
]
}
],
// ==========================================================================
// templates: named naming templates, selected by the "template" field.
// The rendered template is the full object path under files/.
// {date} is rendered as yyyy-mm-dd when set (normalized; "/" is not usable
// in a S3 key). A field that no rule has set renders as an empty string.
// If no rule sets "template", the "default" template is used.
// ==========================================================================
"templates": {
"bank_statement": "{emittingCompany}/{date}_{documentType}_{bankAccount}.pdf",
"tax_notice_housing": "Impots/{date}_{documentType}_{address}.pdf",
"tax_notice_income": "Impots/{date}_{documentType}.pdf",
"invoice": "Factures/{date}_{emittingCompany}_{reference}.pdf",
"default": "Divers/{documentType}.pdf"
}
}