From 320b030bdebf66e27c230cf98e2d3e7f44d0e9c9 Mon Sep 17 00:00:00 2001 From: napnap75 Date: Tue, 3 Nov 2026 23:12:45 +0100 Subject: [PATCH] fix(config): guard the emission-date probes against absent formats The generic emissionDate rule ran unconditionally: on a document whose date is not numeric (e.g. "le 19 janvier 2026"), date(firstMatch(...)) errored on the empty match and routed a correctly classified document to pending/. Each format probe now checks for its own format first, and a frDate fallback handles French natural-language dates. --- archivist/config.jsonc | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/archivist/config.jsonc b/archivist/config.jsonc index a2a1e6c..179eeb5 100644 --- a/archivist/config.jsonc +++ b/archivist/config.jsonc @@ -43,6 +43,10 @@ // the first page, pages[0:3] searches pages 1 to 3 (expr slice // syntax, end exclusive), any list of strings works; omitted = the // whole document. + // frDate(text) parses a French natural-language date ("le 19 janvier + // 2026"; the day is optional and "1er" / abbreviated months are + // accepted) into a native date, for documents whose date is not + // written in a Go layout format. // period(value, unit, shift, layout?) renders a period instead of a // raw date: unit = `month`|`quarter`|`half`|`year`, shift = -1/0/+1 // for the previous / containing / next period (rent receipt: 0, @@ -59,13 +63,25 @@ // --- Generic extraction, runs for every document ------------------------- // Emission date, e.g. "Paris, le 15/01/2026" -> "15/01/2026" (parsed // into a native date; named emissionDate to avoid clashing with the - // expr date() builtin) + // expr date() builtin). + // Every format probe is guarded by its own "when": an unguarded + // date(firstMatch(...)) on a document that does not carry the format + // is a rule error, and a single rule error routes a perfectly + // classifiable document to pending/ (US-15). { - "when": "true", + "when": "firstMatch(`[0-9]{2}/[0-9]{2}/[0-9]{4}`, pages[0]) != ``", "set": [ { "field": "emissionDate", "eval": "date(firstMatch(`[0-9]{2}/[0-9]{2}/[0-9]{4}`, pages[0]), `02/01/2006`)" } ] }, + // Fallback: French natural-language date, e.g. "le 19 janvier 2026", + // when the page carries no numeric date. + { + "when": "firstMatch(`[0-9]{2}/[0-9]{2}/[0-9]{4}`, pages[0]) == `` && firstMatch(`(?:le )?[0-9]{1,2} [A-Za-zÀ-ÿ]{3,} [0-9]{4}`, pages[0]) != ``", + "set": [ + { "field": "emissionDate", "eval": "frDate(firstMatch(`(?:le )?[0-9]{1,2} [A-Za-zÀ-ÿ]{3,} [0-9]{4}`, pages[0]))" } + ] + }, // --- Bank statements (relevés de compte) ---------------------------------- {