Commit Graph
5 Commits
Author SHA1 Message Date
Marc-André Bombeck a3f5f998cf fix(report): end the visit offer on the record's day from the server
The preparation window now carries to, the booked visit's own day on
the record's calendar, and the report offer uses it. Cutting the end in
the reader's zone was wrong for a guardian viewing a managed profile in
another zone.
2026-10-21 16:50:14 +02:00
Marc-André Bombeck 88200a9273 fix(report): cut the visit offer's end day on the record's calendar
The offer took its start from the server's preparation window, cut on
the record's calendar, and its end from the appointment's day in the
browser's zone. In a browser in another zone a late-evening or
early-morning visit moved the end a day against the start. Both ends now
use the record's zone.
2026-10-21 15:07:05 +02:00
Marc-André Bombeck 99fec79177 fix(visits): start the visit preparation and its report at the matching visit
Both surfaces read the start of their window from `preparation` and say
why it starts there: "Since your last visit with <practice> on <date>",
"Since your last <specialty> visit on <date>", "Since your last visit
of the same kind (<kind>) on <date>", or "The last 90 days" with the
reason that no earlier visit matched. The visits tab no longer picks
the last visit of any kind from the past list.

The report panel's appointment offer now sets both dates, the start
from the server and the end on the appointment's day, instead of the
end alone beside whatever start the panel held. Both stay editable.
2026-10-21 12:32:26 +02:00
Marc-André Bombeck ad0d50fa28 feat(visits): record procedures and surgeries with a body site
A visit can be filed as a procedure or surgery (new EncounterKind
PROCEDURE) and carry a body site in the person's own words, encrypted at
rest, plus an optional side (LEFT, RIGHT, BOTH). An existing visit
switches to the new kind by an ordinary edit, keeping its date, reason,
outcome and links.

- migration 0349: enum value, laterality type, two nullable columns
- GET /api/encounters/procedures: the DONE procedures, newest first,
  searched after the decrypt over site, side and reason, with body-site
  choices and a total computed over the whole history
- create and edit accept bodySite and laterality on any kind
- /checkups gains a Procedures tab with a body-site filter; the visit
  form offers the site for a procedure and keeps it in view on any
  visit that carries one
- backup and restore carry both fields; the body site is registered as
  ciphertext and rotates with the key
- MCP get_visits narrows by kind and reads the whole record for
  procedures when no window is named; the Coach visit block names a
  procedure's site
- i18n in all seven locales, OpenAPI regenerated

Refs #1025
2026-09-25 08:11:37 +02:00
Marc-André Bombeck 4d2f706dad feat(doctor-report): a report can mention a visit, and know why it exists
The VISITS leaf ships in the release that made a visit possible, because a
selectable checkbox that produces nothing is worse than no checkbox. Leaf,
collector and PDF renderer land together, and the leaf carries no LEAF_MODULE
entry — like ALLERGIES beside it — because a visit is core and the whole report
is already gated by doctorReport. The absence is commented at the map so a
later reader does not read it as an oversight.

The rows print the date, the practice with its specialty, the kind, the reason,
the outcome and the conditions the visit was filed against. The two encrypted
columns decrypt at render, fail-soft, and never enter the stored selection. A
condition the person has since deleted is not named: the link row survives a
soft delete, and printing a label they withdrew would put it in front of a
doctor.

No FHIR resource type is added. That deferral is already written at the
Encounter model, and the bundle builder now says so at the point a reader would
look for the missing section: FHIR splits the future from the past across
Appointment and Encounter, which is a serialisation question this release does
not answer.

Two properties are free and worth stating: a stored selection never grows
(unknown ids drop) and a clinician share link's sections are frozen write-once,
so no existing report and no already-shared link gains a section.

The panel also offers a booked visit as the report's reason — one query, one
prefilled window end, one dismissible offer that names its own source and never
applies itself. A window control that moves on its own is what makes an export
panel untrustworthy.
2026-08-08 14:38:26 +02:00