v1.5.6 settled the medication detail page into a pure history view, but the create/edit plan still funnelled every dose through the same flat shape, the injection-site picker only surfaced for GLP-1, and the today-tile on the dashboard and the Erfassen sheet still expanded daily schedules through a legacy walker that silently skipped bi-weekly, rolling, RRULE, and one-time cadences. This release reworks the medication editor and its detail surface, gives route of administration a first-class column so any injection can carry a site, adds a one-time-injection shape, and flips the today-tile onto the canonical recurrence engine the reminder worker already uses — so what the tile shows matches what the worker mints. It also restores the multi-language request snippets on the API-tokens row, adds a profile-photo upload to Account, and finishes an admin-surface polish pass.
Added
- Route of administration — a new
deliveryFormcolumn (ORAL|INJECTION|OTHER) decoupled fromtreatmentClass. The injection-site picker now surfaces for anyINJECTIONdose rather than only GLP-1, and the editor carries the route through create, update, and the detail snapshot. Migration0088adds the enum and backfillsORALonto every existing row via a constant column default (a single non-blocking metadata operation). - One-time injection — a one-off dose modelled as
oneShot = true+deliveryForm = INJECTION, with its own editor path that drops the recurring-schedule step. - Profile-photo upload on Account — Settings → Account gains an avatar card backed by the v1.5.5 upload endpoint (server-side magic-byte sniff, 2 MiB stream-level cap, 2048² dimension cap, per-user rate limit, owner-scoped read).
- Admin global mood-log toggle — the admin Services section can suspend mood-log reminders site-wide alongside the existing Web-Push and API toggles.
- Host-metrics memory detail — the admin host-metrics memory tooltip now reads
used / total GiBalongside the percentage.
Changed
- Medication editor + detail surface overhaul — the editor uses the available desktop width while keeping the mobile sheet, restores the edit fields the modal-wizard rework had dropped, and aligns the detail surface with the new route-of-administration and one-time shapes.
- Measurement note cap raised 25 → 200 characters — a 25-character note could not hold a meaningful clinical aside; the cap lifts to 200 through a single
MEASUREMENT_NOTES_MAX_LENGTHconstant the client char-counters import. The DB column was already unbounded. - Dashboard range colors route through semantic tokens — the dashboard date-range chips read the shared
success/warning/info/destructivetokens (with their light-mode contrast overrides) instead of hard-coded hues, and the range inputs gain bound-clamping. - Admin surface tidy — every sidebar section gets a distinct icon, the shared
helpfulRateColourhelper and ausePublicVersionhook are consolidated into_shared, and the orphanedstatus-overviewroute is removed. - API-tokens row restores multi-language request snippets — the per-token row again offers copyable cURL / JavaScript / Python examples.
Fixed
- Today-tile diverged from the reminder worker for non-daily cadences —
/api/medications/intake?scope=todayand/api/dashboard/summaryprojected daily schedules through a legacy walker that read onlydaysOfWeek+windowStart, silently skippingintervalWeeks > 1, rolling, RRULE, and one-time cadences. Both routes now gate every "does this schedule emit today?" decision through the canonical recurrence engine (the same path the worker uses), anchoring the projected instant towindowStartso it stays byte-identical to the worker's row and dedupes against the existing unique index. The rolling-cadence baseline fetch mirrors the worker's per-medicationtakenAtquery, so projector and worker resolve the same next-due instant.
Tests
- 5635 → 5628 unit; 1 skipped. The today-tile read-flip carries new coverage on the intake and dashboard-summary projections; the orphaned status-overview route and its test are gone.