The blood type, organ donor and advance directive selects had no empty
option, and the save left out an empty select, so a value once chosen
could be changed but never removed. Each select now offers "Not
recorded", and a select the person changed rides the save, as null when
it was cleared; an untouched one stays out of the request.
Twelve routes answer a capped list with meta.truncated / meta.limit on
the envelope, and the web client read only data, so no surface said a
list had stopped short. apiGetList / apiPostList are now the one client
reader of the cap and ListCapNotice the one line that shows it; every
capped list on the web reads its cap and shows the notice under the list,
the paged readers (side effects, illness episodes) stop on the route's
answer instead of a full-page guess, and the ECG list moves its five
readers onto one hook. The record activity feed sent its cap twice, in
data and on the envelope; it rides the envelope alone now. A guard
derives the capped routes from the tree and binds each to a client that
reads its cap.
The stored language is the wording the read route offers the account;
a request naming another wording, or a takenAt more than five minutes
ahead, is refused. Latest, offerDue, the Coach block and the doctor
report all read the newest entry whose answers open.
The old one-word alcohol pattern gives way to an AUDIT-C entry in the
Coach block, and the alcohol section lists it with a remove action.
The TOTP enable, the source-priority reset, the biomarker and record add
actions, and the about-me, profile-facts, emergency and condition saves
move into SettingsCardActions, right-aligned and last in the card. The
emergency Save waits for a change like its neighbours, an empty list
leaves its add action to the empty state, and the source ladder keeps
its up/down buttons side by side on a phone.
The free-text self-context note and the free-text allergy line are
personal medical context, so they join conditions, allergies and family
history in Settings -> Anamnese. The note is its own card (same AI-surface
gate as the inclusion card); the allergy line sits directly under the
structured AllergyManager in the same card, labelled as a free-text
supplement so the two inputs never read as duplicates. The account
section drops the old panel. Store, API and query keys are unchanged;
the scoped Clear (note only, allergies untouched) carries over with its
tests. Orphaned strings removed, new labels in all six languages.
Refs #159
The lifestyle-context tile carried a Save button per fact kind. Collapse
them into one footer Save that writes only the dirty kinds, firing the
existing bitemporal call per kind (POST a first value, PATCH a revision)
and settling them together so a single conflict cannot take the healthy
writes down with it. A kind that 409s keeps its draft on screen and names
itself, instead of vanishing behind one green toast. The per-kind Remove
stays.
The three entries stacked two full-width buttons under the value — a
disabled grey Save above a red-outlined "Remove smoking status" — so each
one read as a slab of controls with the same weight as the field it
belonged to, and scanning them ran the two labels together.
Each entry now ends in one right-aligned action row: the quiet destructive
first, the primary Save last, both at the mobile tap-target floor. The
remove control drops the field name from its visible label, which the
Label directly above already carries, and keeps the full phrase as its
accessible name and in the dialog it opens — so three of them side by side
stay distinguishable to a screen reader. Six languages.
Follows the card action-row convention: primary bottom right, secondary
beside it, nothing after the row.