FEST: in-repo flattener bundles slim.json; release builds auto-refresh when stale

Amends decision #8: the producer now lives in tools/fest_flatten.py
(stdlib Python, streaming iterparse over the 115 MB M30 XML) instead of
an out-of-repo server job. It pulls fest251.zip from dmp.no, flattens
8934 active human-use brand entries (name/strength/unit/form/ATC +
modal package size from pakningsinfo), and writes the asset checked in
at app/src/main/assets/fest/slim.json — so autocomplete works offline
out of the box. preReleaseBuild depends on refreshFestData: fast-exits
under 30 days, keeps the old file on download failure (offline release
builds never break). FestRepository: downloaded cache wins over the
bundled asset.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2026-06-10 15:19:49 +02:00
commit 293ca212ec
6 changed files with 260 additions and 15 deletions

View file

@ -1,10 +1,17 @@
# FEST slim dataset — contract
The app does **offline** autocomplete against a slim, pre-flattened JSON file.
The job that produces it lives **outside this repo**: it pulls FEST's open
Rekvirent extract (the M30 SOAP/WCF XML dump from DMP), flattens the
human-use medication entries, and publishes the JSON behind Caddy or into the
Garage bucket. FEST changes slowly; refresh the published file monthly-ish.
The producer is `tools/fest_flatten.py` in this repo: it downloads FEST's open
Rekvirent extract (the M30 XML dump, `fest251.zip` from dmp.no), flattens the
human-use brand entries, and writes `app/src/main/assets/fest/slim.json`,
which is checked in and **bundled in the APK** — autocomplete works out of the
box with zero configuration.
Release builds run the script automatically (`preReleaseBuild`
`refreshFestData`): it regenerates when the bundled file is >30 days old,
fast-exits when fresh, and keeps the old file if the download fails, so an
offline release build never breaks. Manual run:
`python3 tools/fest_flatten.py --out app/src/main/assets/fest/slim.json --force`.
Why FEST and not Felleskatalogen: FEST is the open national dataset;
Felleskatalogen is licensed editorial content with no open API. Why not live
@ -13,11 +20,10 @@ work offline.
## Where the app loads it from
`Innstillinger → FEST-URL` (e.g. `https://<host>/fest/slim.json`). The app
downloads on demand, caches to `filesDir/fest-slim.json`, and reads only the
cache afterwards. A staleness nudge appears after ~45 days (dataset `updated`
field), but old data keeps working — autocomplete is a convenience, never a
gate.
Bundled asset `fest/slim.json` by default. Optionally, `Innstillinger →
FEST-URL` downloads a newer file to `filesDir/fest-slim.json`, which then
wins over the bundle. Old data keeps working — autocomplete is a convenience,
never a gate.
## JSON shape (version 1)