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>
57 lines
2.1 KiB
Markdown
57 lines
2.1 KiB
Markdown
# FEST slim dataset — contract
|
|
|
|
The app does **offline** autocomplete against a slim, pre-flattened JSON file.
|
|
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
|
|
lookups: M30 is a bulk XML dump, not a per-keystroke API — and the phone must
|
|
work offline.
|
|
|
|
## Where the app loads it from
|
|
|
|
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)
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"updated": "2026-06-01",
|
|
"entries": [
|
|
{
|
|
"name": "Paracet",
|
|
"strength": "500 mg",
|
|
"unit": "tablett",
|
|
"form": "tablett",
|
|
"atc": "N02BE01",
|
|
"packageSize": 20.0
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
- `name` — preparation name (varenavn), required.
|
|
- `strength` — display string, may be empty.
|
|
- `unit` — what one dose counts ("tablett", "ml", "dose"), required.
|
|
- `form` — FEST's form text, free-form (not this app's MedForm enum; the
|
|
editor maps it heuristically and lets the user override).
|
|
- `atc` — ATC code, optional.
|
|
- `packageSize` — units per package for the most common package, optional.
|
|
|
|
Unknown extra keys are ignored (`ignoreUnknownKeys`), so the producer can add
|
|
fields without breaking older app versions. Bump `version` only for breaking
|
|
changes.
|