fix(settings): keep the health-record entry reachable regardless of the doctorReport opt-out

The health-record section (PDF + FHIR R4 export) was the only entry-point
gated on the doctorReport module's nav toggle, so flipping that opt-out in
the Modules hub made the whole section vanish from Settings with no
in-context way back. Drop the nav gate: the entry-point now always shows.
The doctorReport module still governs the data layer — the server-side
/api/export/health-record route stays the hard enforcement (403
module.disabled over Bearer when opted out). Assert the entry shows for a
default, empty, and opted-out modules map.
This commit is contained in:
Marc-André Bombeck committed 2026-06-19 00:03:22 +02:00
1 parent 6f866ff1c6
commit dae7138fc6
3 files changed
+28 -14

No files matched your search

@@ -239,17 +239,23 @@ describe("<SettingsShell>", () => {
expect(disabled).not.toContain('href="/settings/coach"');
});
it("module-gates the Health-record entry off `user.modules.doctorReport` (B3)", () => {
// Fail-open default: doctorReport undefined → entry shown.
it("always surfaces the Health-record entry, regardless of `doctorReport` (v1.18.6.1)", () => {
// The health-record (PDF / FHIR) entry is a flagship export capability
// and is no longer nav-gated: a default/unset modules map shows it, and
// even an explicit `doctorReport: false` keeps the Settings entry-point
// reachable. The server-side `/api/export/health-record` route remains
// the hard enforcement of the opt-out.
expect(renderShell({ active: "account" })).toContain(
'href="/settings/gesundheitsakte"',
);
// Explicitly disabled → entry hidden.
const disabled = renderShell({
expect(renderShell({ active: "account", modules: {} })).toContain(
'href="/settings/gesundheitsakte"',
);
const optedOut = renderShell({
active: "account",
modules: { doctorReport: false },
});
expect(disabled).not.toContain('href="/settings/gesundheitsakte"');
expect(optedOut).toContain('href="/settings/gesundheitsakte"');
});
it("falls back to `account` when the pathname doesn't match a known slug", () => {
@@ -10,10 +10,12 @@
* the generic CSV / JSON data-out paths. Export & Import now keeps only
* the generic data export/import surfaces.
*
* Module-gated on `doctorReport` (v1.18.0 B3): the nav entry hides when the
* module is off (see `SETTINGS_SECTIONS` in `settings-shell.tsx`), and the
* server-side `/api/export/health-record` route refuses with a 403
* `module.disabled` envelope — so a disabled doctor-report surface cannot be
* The `doctorReport` module governs the data layer, not the Settings
* entry-point: as of v1.18.6.1 the nav entry always shows (the health record
* is a flagship export capability and should never silently vanish from
* Settings). The server-side `/api/export/health-record` route is the hard
* enforcement — it refuses with a 403 `module.disabled` envelope when the
* account has opted out, so a disabled doctor-report surface cannot be
* reached over a Bearer token either.
*/
+11 -5
View File
@@ -177,15 +177,21 @@ export const SETTINGS_SECTIONS: readonly SettingsSection[] = [
},
{ slug: "api", titleKey: "settings.sections.api.title", icon: KeyRound },
// v1.18.0 (S5) — the full health record (PDF + FHIR R4 + zip package)
// earns its own home, lifted out of Export & Import. Gated on the
// `doctorReport` module: when the user turns the doctor-report surface off,
// the entry hides (the server-side `/api/export/health-record` gate is the
// hard enforcement; this hides the entry-point to match).
// earns its own home, lifted out of Export & Import.
//
// v1.18.6.1 — the nav entry is NOT module-gated. The health record is a
// flagship export capability; gating its only entry-point on the
// `doctorReport` opt-out meant a stray toggle in the Modules hub made the
// whole section vanish with no in-context way back. The entry now always
// shows. The `doctorReport` module still governs the data layer: the
// server-side `/api/export/health-record` route remains the hard
// enforcement (403 `module.disabled` over Bearer when the account opts
// out), and the Modules hub keeps the toggle for anyone who wants the
// surface gone elsewhere — but the Settings entry-point stays reachable.
{
slug: "gesundheitsakte",
titleKey: "settings.sections.gesundheitsakte.title",
icon: FileHeart,
moduleGate: "doctorReport",
},
{
slug: "export",