Commit Graph
7 Commits
Author SHA1 Message Date
Marc-André Bombeck ccca056f64 feat: let the record's module map filter its own navigation
The other half of the switched-payload change, found by the integration
test that asserted the door was gone and got the door. `isNavDestinationVisible`
short-circuited on `sharedRecord`, so a switched session skipped the module
filter entirely and every destination the grant's scope allowed was offered.

That was right while the map was the actor's: a delegate's own preferences
must not hide a domain the record granted. The map is the record's now, so
the objection is gone and the line is what makes a guardian's toggle visible
inside the profile it was set for. Scope decides which doors the grant opens;
the map decides which of them the record uses at all.

The read-only profile summary needs its marker checked against `!sharedRecord`
rather than reached through the removed short-circuit, and the case that
pinned the old reading is turned round with the reason written out.

Refs #939
2026-09-10 01:09:50 +02:00
Marc-André Bombeck eefc151617 feat(vaccinations): add the immunization log route, nav entry and shared-record family
- register /vaccinations in the clinical nav spine, module-gated on
  vaccinations (default-on) and part of the shared record
- join /vaccinations to the profile shared-record route family so a scoped
  profile grant can present the page it is allowed to read
- add the page shell: authenticated, module-gated, with the standard
  module-off redirect the medications surface uses
- add the nav label and the surface title/subtitle/empty copy in six locales
2026-08-08 20:24:42 +02:00
Marc-André Bombeck ed1438230c feat(encounters): visits and the address book become reachable
/checkups gains a second section rather than a nav entry. The page already
owns the right sentence — when do I have to do what, where — and is
deliberately not module gated, which is the same reason a visit carries no
module key of its own: what a visit may point AT follows the modules that own
those things, so the gate sits on the three link pickers and blanks the block
rather than rendering an empty one.

A visit saves with a date and nothing else. No required practitioner, no
required kind, no required link, and the only thing that can disable Save is a
date that will not parse. The status is derived from the date on a new visit
and only becomes a field on an existing one, because somebody booking an
appointment should not also have to tell the app that it is in the future.

The address book is record content, not configuration, so it sits under
/checkups rather than in Settings — and it inherits that page's route-family
classification with it. Deleting an entry says in one sentence that the old
visits stay, because a person deleting a doctor has every reason to fear
otherwise.

Two defects closed on the way:

- /checkups carried sharedRecord: true and appeared in neither route family,
  so a scoped grant could not present it at all. It was invisible while a
  whole-record grant admitted every path; the visits section makes it load
  bearing, and the page is now listed under both domains whose content it
  shows. Deduplicated, or a grant holding both would offer the page twice.
- the address-book search read the name only, so looking a practice up by the
  name on the door returned nothing and read as "not in the book".

The practitioner search description in the OpenAPI module moved with it.
2026-08-08 13:21:43 +02:00
Marc-André Bombeck a33cde3034 test(02-12): cover defensive record presentation
- reject inconsistent access levels before chrome can elevate them\n- fall back to the caller record for malformed payloads
2026-08-06 05:06:36 +02:00
Marc-André Bombeck 34073cf8dc test(02-12): cover scoped navigation presentation
- prove profile uses a read-only shared route\n- cover scoped navigation independent of actor module flags\n- require action, access, and kind in record button names
2026-08-06 05:00:33 +02:00
Marc-André Bombeck 908897cc6b test: cover shared record modes 2026-08-06 04:17:58 +02:00
Marc-André Bombeck cb15100341 test: cover scoped record navigation 2026-08-06 04:13:54 +02:00