mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
The intake import built its replay key from the row's optional `zaehler` field. That reads as a per-row counter — the documented example showed one — but nothing required it to be unique and nothing checked. A reported export carried the dose quantity there instead: 1 tablet, on all 28 rows. Every entry queued under the same key, one dose reached the ledger, and the other 27 came back reported as duplicates of a dose they had nothing to do with. The key is the instant now, and `zaehler` is out of the contract rather than accepted-and-ignored. Nothing is lost by dropping it: the live-row unique on `(user_id, medication_id, scheduled_for, source)` already makes an imported dose unique per instant, so a re-import of a file first imported under the old key still dedups. The telling is the other half. Two different facts were counted as one number: entries of a submission that collide with each other, and doses the ledger already holds. They are separate reasons now, grouped with a count, and the dialog renders them through the same classifier and the same outcome line as the CSV and JSON import cards — so an import that wrote nothing can no longer answer in success tone. That rule shipped for the settings import panel and this surface was not part of it; the guard now lists every import surface by path, so a fourth one has to be added deliberately. `skippedInvalid` is gone: it was hardcoded to zero on every path and reported a capability the importer never had. Alongside it, the other half of the environment report — a scheduled job that fails every run has to say so. `recordError()` increments one unnamed counter, so the admin status page could show a number and not which queue produced it, and the module's own screen showed a zero day count with nothing to distinguish "nothing stored yet" from "every run failed". pg-boss has held the answer the whole time: a job that exhausts its retries keeps its queue name, its error and its timestamp. The admin status now names the failing queues with counts and the last error, the environment overview reports its own account's failed runs, and neither needed a change at any of the thirty `recordError()` call sites — a visibility fix that has to be remembered per call site is the same failure one level up. Refs #650, #646