work · Latvian public tenders, medical nutrition and enteral devices · 2026-08 to 2026-09

Latvian tender matcher: the LLM structures text, deterministic code decides compliance

It parses free-text Latvian public-tender requirements into structured constraints and checks them against a product catalogue with deterministic rules. It gives a per-criterion verdict, has a FastAPI review UI and exports an Excel report. 704 tests pass; in production since 2026-09-12.

problemconstraintswhat I builtoutcomestackredacted screenshot

Problem

Tender rows state requirements in free Latvian prose, with decimal commas, operator phrases (ne mazāk kā, no X līdz Y) and inconsistent units. Answering a tender by hand means re-reading the catalogue for every row, and a wrong "compliant" is a safety and bid-integrity risk.

Constraints

What I built

fig 1. The model's only job is to turn prose into structure. Everything that decides a verdict is code.

Outcome

dateresult
2026-08-11First commit and FastAPI UI. The architecture doc rejects n8n and pgvector: pre-filtering cuts 10K products to 5-50 candidates
2026-08-12Gap analysis over 310 tender items found 487 unique unparsed segments
2026-08-20Device matching, row routing, and a durable SHA-256-keyed procurement library
2026-09-12Age-group matching removed live false positives where adult formulas topped paediatric and infant rows. Deployed at 03:20 Riga: 704 tests pass, 9 stored tenders intact
2026-09-12Todo rewritten from measured results: 15 of 23 P1-P3 claims were wrong about location, size or whether to build at all
metricvalue
tests704 passing on dev (3.13.2) and prod (3.12.3), 2026-09-12
gap analysis310 tender items, 487 unparsed segments (2026-08-12)
catalogue43 nutrition variants, 136 device variants
bare-operator fixcovered 16 corpus rows; next target, sugar, has 39 rows
will not build7 backlog items, because each invents a threshold no tender states (2026-09-12)

Stack

Python 3.12FastAPIPydantic 2Jinja2openpyxlPyYAMLpytestAnthropic SDK (extraction only)

Redacted screenshot

fig 2. Synthetic tender rows. Product names are generic; client, supplier and tender IDs are redacted. Row 4.3 shows the 2026-09-12 age-group rule rejecting an adult formula on an infant row.
evidence: brain/projects/medical-procurement-matcher.md · medical-procurement-matcher/context.md · decisions.md · brain/_meta/night-run-2026-09-23-recruiter-view.md