feat(recibos): OCR capture for zona federal (ZOFEMAT Tijuana)
Adds the ZONA FEDERAL TIJUANA parser to the statement intake, measured against 8 pages of real "Zona Federal Marítimo Terrestre" receipts — the federal maritime-zone occupancy fee the municipality bills on beachfront lots. Provider read on 8/8, amount on 8/8 (each verified against the paper), concession clave on 6/8, period on 8/8, deadline on 2/8. Four things the corpus forced: - Tijuana bills predial and zona federal from the same treasury: same header, same Paseo del Centenario address, same ATB-541201 RFC. Every predial discriminator matches a zona federal page too, so whichever rule is asked first wins it. The only words exclusive to this layout are "Marítimo Terrestre", so its brand rule is asked ahead of all three predial ones — and its structural rule, anchored on the stub's "Derechos de ocupación", ahead of theirs. - FEDERAL_ZONE.accountNumber is an amount, not a reference. It holds DATMEX.zfed, whose 77 values include 246.06, 2369.09, 22653.94 and a negative -1679, while the concession claves these receipts are keyed by appear nowhere in the database. Matching on that column could never hit — and because every row already has a value, the `[field]: null` guards on learnAccountRefs and on the review blank-service fill would never fire either, so every page would return to the queue every bimester forever. The clave moves to meterNumber, joining gas and Tijuana predial, and the first confirm teaches the match. - The payable figure is not the printed subtotal. The municipality rounds to whole pesos and prints the difference on its own "Ajuste Ley Hacienda Mpal" line (-$0.05 against a 591.05 subtotal, $0.21 against 2,872.79). The "Total a pagar" box carrying the rounded figure sits on a grey fill and OCR'd on 1 of 8 pages; the SubTotal row read on 8 of 8. So the amount is the rounded subtotal, cross-checked against the printed box wherever it survives — where it did, it agreed. - The clave is 2 digits, a letter and 3 digits (12-T -012), not the cadastral shape, and the letter is kept as printed: toDigits maps D to 0, which turns a real 14-D -014 into 140014. It is printed twice, which rescued a page whose heading was struck through by the office's own highlighter — the failure mode behind both missing claves. Deriving the deadline from the bimester is deliberately not attempted: it is the 17th of the month after the bimester closes on a current bill, but four of these eight are late (a $1,000 Multa) and print a recalculated date, so a derived date would be wrong on exactly the pages a human most wants to see. Re-ran the earlier corpora (25 pages: predial Tijuana/Rosarito/Ensenada, CFE, CESPT, Telnor) through detection to confirm the new rules steal nothing — all 25 still read as their original provider, including the five Tijuana predial pages that share the RFC. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -256,6 +256,54 @@ single-movement form.
|
||||
> `statement-parser.spec.ts` and `tesseract.provider.spec.ts`; every fixture in
|
||||
> them is a verbatim OCR excerpt from a real receipt.
|
||||
|
||||
> **EXTENDED — zona federal, 2026-08-01.** A third corpus (one document, 8
|
||||
> pages of Tijuana "Zona Federal Marítimo Terrestre" receipts — the federal
|
||||
> maritime-zone occupancy fee billed on beachfront lots) added the
|
||||
> `ZONA FEDERAL TIJUANA` parser. Provider read on 8/8, amount on 8/8 (all
|
||||
> eight verified against the paper), concession clave on 6/8, period on 8/8,
|
||||
> payment deadline on 2/8. Nothing auto-matched, and nothing could have — see
|
||||
> point 2.
|
||||
>
|
||||
> **Four things this corpus proved:**
|
||||
>
|
||||
> 1. **Tijuana bills predial and zona federal from the same treasury.** Same
|
||||
> "Ayuntamiento de Tijuana" header, same Paseo del Centenario address, same
|
||||
> `ATB-541201` RFC — every discriminator the predial parser uses matches a
|
||||
> zona federal page too, so whichever rule is asked first wins. The words
|
||||
> only this layout prints are `Marítimo Terrestre`, so its brand rule is
|
||||
> asked ahead of all three predial ones.
|
||||
> 2. **`FEDERAL_ZONE.accountNumber` is an amount, not a reference.** It holds
|
||||
> `DATMEX.zfed`, whose 77 values include `246.06`, `2369.09`, `22653.94` and
|
||||
> a negative `-1679`; the concession claves the receipts are keyed by
|
||||
> (`12-T -012`, `14-D -014`) appear nowhere in the database. Matching on that
|
||||
> column could never hit — and because every row already has a value, the
|
||||
> `[field]: null` guards on learning and on the blank-service fill would
|
||||
> never fire either, so every page would return to review every bimester
|
||||
> forever. The clave moves to `meterNumber`, joining gas and Tijuana predial,
|
||||
> and the first confirm teaches the match. This is the same trap as
|
||||
> `policies.total` and `PROPERTY_TAX.accountNumber`: a legacy column whose
|
||||
> name promises an identifier and whose contents are something else.
|
||||
> 3. **The payable figure is not the printed subtotal.** The municipality rounds
|
||||
> to whole pesos and prints the difference as its own `Ajuste Ley Hacienda
|
||||
> Mpal` line — `-$0.05` against a 591.05 subtotal, `$0.21` against 2,872.79.
|
||||
> The "Total a pagar" box that carries the rounded figure sits on a grey fill
|
||||
> and OCR'd on 1 of 8 pages; the SubTotal row read on 8 of 8. So the amount
|
||||
> is the rounded subtotal, cross-checked against the printed box wherever it
|
||||
> survives (it agreed).
|
||||
> 4. **The office's own highlighter is an OCR failure mode.** Both pages that
|
||||
> lost their clave lost it to a marker stroke drawn across the `Clave:` line
|
||||
> — not to scan quality, which was otherwise fine. The clave is printed twice
|
||||
> (receipt and stub), which rescued a third page whose heading was struck
|
||||
> but whose stub was not; where both copies are struck, the page reports no
|
||||
> clave and goes to review rather than guessing.
|
||||
>
|
||||
> **Not attempted:** deriving the payment deadline from the bimester. It is the
|
||||
> 17th of the month after the bimester closes on a current bill, but four of
|
||||
> these eight are late — they carry a $1,000 `Multa` — and print a
|
||||
> recalculated deadline a month out. A derived date would be wrong on exactly
|
||||
> the pages a human most wants to look at, so an unreadable deadline stays
|
||||
> null.
|
||||
|
||||
### Motivation (from the meeting)
|
||||
|
||||
Each utility company (CFE, water, phone, gas...) sends 300+ individual
|
||||
|
||||
Reference in New Issue
Block a user