mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
fix(settings): English addresses for the health record and checkups pages
Two Settings pages had German words in their address in every language: /settings/gesundheitsakte and /settings/layout/vorsorge. They are /settings/health-record and /settings/layout/checkups now, and the old addresses (and the older /settings/sharing and /settings/vorsorge) redirect permanently, so bookmarks and links in old reports keep working; the report range a since-last-visit link carries in its query passes through. The in-app links, the tour, the command palette, the anchor forwards and the e2e specs use the new addresses, and the two message groups follow the new slugs.
This commit is contained in:
1 parent
3b79c81379
commit
f17819f1c2
34 files changed
+110
-78
No files matched your search
@@ -8,7 +8,7 @@
|
||||
* record the delegate may only read, 200 inside the one it manages.
|
||||
*
|
||||
* The UI half proves something narrower, and the file says so rather than
|
||||
* implying the route's boundary twice. `/settings/gesundheitsakte` is a
|
||||
* implying the route's boundary twice. `/settings/health-record` is a
|
||||
* PERSONAL destination: inside SOMEBODY ELSE's record the shell answers it with
|
||||
* the "not part of shared access" panel at every adult grant level — READ,
|
||||
* WRITE and MANAGE alike — so the export card is never rendered for a delegate
|
||||
@@ -149,7 +149,7 @@ async function leaveRecord(page: Page): Promise<void> {
|
||||
* card was never offered.
|
||||
*/
|
||||
async function openGesundheitsakte(page: Page): Promise<void> {
|
||||
await page.goto("/settings/gesundheitsakte", {
|
||||
await page.goto("/settings/health-record", {
|
||||
waitUntil: "domcontentloaded",
|
||||
});
|
||||
await expect(
|
||||
|
||||
@@ -247,7 +247,7 @@ async function openReportPanel(page: Page): Promise<void> {
|
||||
response.request().method() === "GET" &&
|
||||
new URL(response.url()).pathname === "/api/share-links",
|
||||
);
|
||||
await page.goto("/settings/gesundheitsakte", {
|
||||
await page.goto("/settings/health-record", {
|
||||
waitUntil: "domcontentloaded",
|
||||
});
|
||||
await boundaryHydrated;
|
||||
|
||||
@@ -92,7 +92,7 @@ const DYNAMIC_ROUTES: Record<string, Resolver> = {
|
||||
"labs",
|
||||
"illness",
|
||||
"documents",
|
||||
"vorsorge",
|
||||
"checkups",
|
||||
].map((group) => `/settings/layout/${group}`),
|
||||
"/settings/modules/[module]": async () =>
|
||||
MODULE_SETTINGS_PAGE_IDS.map((module) => `/settings/modules/${module}`),
|
||||
|
||||
@@ -53,7 +53,7 @@ const SETTINGS_ROUTES = [
|
||||
"/settings/sources",
|
||||
"/settings/environment",
|
||||
"/settings/export",
|
||||
"/settings/gesundheitsakte",
|
||||
"/settings/health-record",
|
||||
"/settings/privacy",
|
||||
"/settings/api",
|
||||
"/settings/mcp",
|
||||
@@ -76,7 +76,7 @@ const LAYOUT_CHILD_ROUTES = [
|
||||
"/settings/layout/medications",
|
||||
"/settings/layout/labs",
|
||||
"/settings/layout/illness",
|
||||
"/settings/layout/vorsorge",
|
||||
"/settings/layout/checkups",
|
||||
"/settings/modules/medications",
|
||||
"/settings/modules/mood",
|
||||
"/settings/modules/labs",
|
||||
|
||||
@@ -14,7 +14,7 @@ import { STORAGE_STATE_PATH } from "./setup/global-setup";
|
||||
* 2. The import surfaces (v1.15.7, issue #281) render: the Apple Health
|
||||
* and generic-JSON cards.
|
||||
* 3. The full health-record export panel lives on its own top-level
|
||||
* `/settings/gesundheitsakte` section (v1.18.0 S5) — including the
|
||||
* `/settings/health-record` section (v1.18.0 S5) — including the
|
||||
* "included data" disclosure, which a first run opens and which stays
|
||||
* operable in both directions.
|
||||
* 4. The scope picker mounts twice on that page (the export panel and the
|
||||
@@ -45,7 +45,7 @@ async function openGesundheitsakte(page: Page): Promise<void> {
|
||||
response.request().method() === "GET" &&
|
||||
new URL(response.url()).pathname === "/api/share-links",
|
||||
);
|
||||
await page.goto("/settings/gesundheitsakte", {
|
||||
await page.goto("/settings/health-record", {
|
||||
waitUntil: "domcontentloaded",
|
||||
});
|
||||
await boundaryHydrated;
|
||||
@@ -57,7 +57,7 @@ test.describe("Settings → Export & Import", () => {
|
||||
test("renders all export surfaces with stable testids", async ({ page }) => {
|
||||
await page.goto("/settings/export", { waitUntil: "domcontentloaded" });
|
||||
// v1.18.0 — the full health-record export moved to its own
|
||||
// `/settings/gesundheitsakte` section. The Export & Import page keeps
|
||||
// `/settings/health-record` section. The Export & Import page keeps
|
||||
// the four CSV/backup tiles with the `export-card-*` shape.
|
||||
for (const id of [
|
||||
"export-card-measurements-csv",
|
||||
@@ -250,7 +250,7 @@ test.describe("Settings → Export & Import", () => {
|
||||
page,
|
||||
}) => {
|
||||
// The disclosure that fronts the scope picker on
|
||||
// `/settings/gesundheitsakte`. An account with no saved selection is a
|
||||
// `/settings/health-record`. An account with no saved selection is a
|
||||
// first run, and a first run opens it: that is the only place the standard
|
||||
// template is applied, and a template hidden behind a closed disclosure
|
||||
// would be opt-out wearing a hat.
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Krankheitstagebuch",
|
||||
"description": "Listenansicht und Reihenfolge der Episoden."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Vorsorge",
|
||||
"description": "Listenansicht und Reihenfolge der Erinnerungen."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Alles außer Reihenfolge und Ansicht findest du auf der Seite des Moduls unter Module."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Gesundheitsakte",
|
||||
"subtitle": "Exportiere eine vollständige, arzttaugliche Gesundheitsakte."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Illness journal",
|
||||
"description": "List view and episode order."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Checkups",
|
||||
"description": "List view and reminder order."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Everything beyond order and view lives on the module's page under Modules."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Health record",
|
||||
"subtitle": "Export a complete, clinician-ready health record."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Diario de enfermedades",
|
||||
"description": "Vista de lista y orden de episodios."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Revisiones",
|
||||
"description": "Vista de lista y orden de recordatorios."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Todo lo demás está en la página del módulo, en Módulos."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Historial médico",
|
||||
"subtitle": "Exporta un historial de salud completo, listo para el médico."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Journal des maladies",
|
||||
"description": "Vue en liste et ordre des épisodes."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Examens",
|
||||
"description": "Vue en liste et ordre des rappels."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Tout le reste se trouve sur la page du module, dans Modules."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Dossier médical",
|
||||
"subtitle": "Exportez un dossier de santé complet, prêt pour le médecin."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Diario delle malattie",
|
||||
"description": "Vista elenco e ordine degli episodi."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Controlli",
|
||||
"description": "Vista elenco e ordine dei promemoria."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Tutto il resto è nella pagina del modulo, in Moduli."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Cartella clinica",
|
||||
"subtitle": "Esporta una cartella clinica completa, pronta per il medico."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "아픈 날 일지",
|
||||
"description": "목록 보기와 에피소드 순서."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "건강검진",
|
||||
"description": "목록 보기와 알림 순서."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "순서와 보기 외의 설정은 모듈의 페이지에 있습니다."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "건강 기록",
|
||||
"subtitle": "임상의에게 바로 건넬 수 있는 완전한 건강 기록을 내보내요."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Ziektedagboek",
|
||||
"description": "Lijstweergave en volgorde van episodes."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Preventieve controles",
|
||||
"description": "Lijstweergave en volgorde van herinneringen."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Al het andere staat op de pagina van de module onder Modules."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Gezondheidsdossier",
|
||||
"subtitle": "Exporteer een volledig gezondheidsdossier dat klaar is voor je zorgverlener."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Dziennik chorób",
|
||||
"description": "Widok listy i kolejność epizodów."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Badania kontrolne",
|
||||
"description": "Widok listy i kolejność przypomnień."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Wszystko poza kolejnością i widokiem jest na stronie modułu w Modułach."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Dokumentacja zdrowotna",
|
||||
"subtitle": "Eksportuj kompletną dokumentację zdrowotną gotową dla lekarza."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Diário de doenças",
|
||||
"description": "Visualização em lista e ordem dos episódios."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Check-ups",
|
||||
"description": "Visualização em lista e ordem dos lembretes."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Tudo além da ordem e da visualização fica na página do módulo, em Módulos."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Registro de saúde",
|
||||
"subtitle": "Exporte um registro de saúde completo, pronto para o clínico."
|
||||
},
|
||||
|
||||
+2
-2
@@ -5627,7 +5627,7 @@
|
||||
"title": "Дневник болезней",
|
||||
"description": "Вид списка и порядок эпизодов."
|
||||
},
|
||||
"vorsorge": {
|
||||
"checkups": {
|
||||
"title": "Профилактика",
|
||||
"description": "Вид списка и порядок напоминаний."
|
||||
},
|
||||
@@ -6052,7 +6052,7 @@
|
||||
"moduleSettingsDescription": "Всё, кроме порядка и вида, настраивается на странице модуля в разделе «Модули»."
|
||||
}
|
||||
},
|
||||
"gesundheitsakte": {
|
||||
"health-record": {
|
||||
"title": "Медицинская карта",
|
||||
"subtitle": "Экспортируйте полную медицинскую карту, готовую для врача."
|
||||
},
|
||||
|
||||
+14
-2
@@ -230,7 +230,19 @@ const nextConfig: NextConfig = {
|
||||
},
|
||||
{
|
||||
source: "/settings/vorsorge",
|
||||
destination: "/settings/layout/vorsorge",
|
||||
destination: "/settings/layout/checkups",
|
||||
permanent: true,
|
||||
},
|
||||
// The health record and checkups pages had German addresses in every
|
||||
// language; the English ones replace them, and the old ones redirect.
|
||||
{
|
||||
source: "/settings/gesundheitsakte",
|
||||
destination: "/settings/health-record",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/settings/layout/vorsorge",
|
||||
destination: "/settings/layout/checkups",
|
||||
permanent: true,
|
||||
},
|
||||
// v1.25.7 — clinician share links fold into the Gesundheitsakte section
|
||||
@@ -238,7 +250,7 @@ const nextConfig: NextConfig = {
|
||||
// to the anchor there.
|
||||
{
|
||||
source: "/settings/sharing",
|
||||
destination: "/settings/gesundheitsakte#sharing",
|
||||
destination: "/settings/health-record#sharing",
|
||||
permanent: true,
|
||||
},
|
||||
// v1.22.0 — the preventive-care surface moved from the German slug
|
||||
|
||||
@@ -215,7 +215,7 @@ describe("the customise shortcut is withheld inside somebody else's record", ()
|
||||
export function Page() {
|
||||
const { inSharedRecord } = useRecordCapabilities();
|
||||
const wrench = !inSharedRecord ? (
|
||||
<Link href="/settings/layout/vorsorge">Customise</Link>
|
||||
<Link href="/settings/layout/checkups">Customise</Link>
|
||||
) : null;
|
||||
return wrench;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ const HISTORICAL_SETTINGS_PATHS: readonly string[] = [
|
||||
"/settings/api",
|
||||
"/settings/mcp",
|
||||
"/settings/gesundheitsakte",
|
||||
"/settings/health-record",
|
||||
"/settings/sharing",
|
||||
"/settings/export",
|
||||
"/settings/advanced",
|
||||
@@ -72,6 +73,7 @@ const HISTORICAL_SETTINGS_PATHS: readonly string[] = [
|
||||
"/settings/layout/illness",
|
||||
"/settings/layout/documents",
|
||||
"/settings/layout/vorsorge",
|
||||
"/settings/layout/checkups",
|
||||
];
|
||||
|
||||
interface Redirect {
|
||||
@@ -151,6 +153,22 @@ describe("historical Settings addresses", () => {
|
||||
expect(unlisted).toEqual([]);
|
||||
});
|
||||
|
||||
it("sends the old German addresses to their English ones", async () => {
|
||||
const redirects = await settingsRedirects();
|
||||
expect(resolve("/settings/gesundheitsakte", redirects)).toBe(
|
||||
"/settings/health-record",
|
||||
);
|
||||
expect(resolve("/settings/sharing", redirects)).toBe(
|
||||
"/settings/health-record",
|
||||
);
|
||||
expect(resolve("/settings/layout/vorsorge", redirects)).toBe(
|
||||
"/settings/layout/checkups",
|
||||
);
|
||||
expect(resolve("/settings/vorsorge", redirects)).toBe(
|
||||
"/settings/layout/checkups",
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps the v1.44 moves addressable", async () => {
|
||||
const redirects = await settingsRedirects();
|
||||
expect(resolve("/settings/layout/mood", redirects)).toBe(
|
||||
|
||||
@@ -321,7 +321,7 @@ export function SinceLastVisit({
|
||||
className="min-h-11 sm:min-h-9"
|
||||
>
|
||||
<Link
|
||||
href={`/settings/gesundheitsakte?reportFrom=${fromDay}&reportTo=${nextDay < today ? nextDay : today}`}
|
||||
href={`/settings/health-record?reportFrom=${fromDay}&reportTo=${nextDay < today ? nextDay : today}`}
|
||||
data-slot="since-last-visit-report"
|
||||
>
|
||||
<FileText className="size-4" aria-hidden="true" />
|
||||
|
||||
@@ -200,7 +200,7 @@ export function VorsorgeSection({
|
||||
className="min-h-11 min-w-11 sm:min-h-9 sm:min-w-9"
|
||||
>
|
||||
<Link
|
||||
href="/settings/layout/vorsorge"
|
||||
href="/settings/layout/checkups"
|
||||
aria-label={t("measurementReminders.customize")}
|
||||
title={t("measurementReminders.customize")}
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@ import { renderToStaticMarkup } from "react-dom/server";
|
||||
|
||||
vi.mock("next/navigation", () => ({
|
||||
useRouter: () => ({ push: vi.fn(), replace: vi.fn() }),
|
||||
usePathname: () => "/settings/gesundheitsakte",
|
||||
usePathname: () => "/settings/health-record",
|
||||
}));
|
||||
|
||||
vi.mock("@tanstack/react-query", () => ({
|
||||
@@ -43,19 +43,19 @@ describe("<GesundheitsakteSection> — SSR smoke", () => {
|
||||
// v1.18.6 — the visible heading (with the historic id) comes from
|
||||
// the shared frame the route wraps the section in.
|
||||
const html = render(
|
||||
<SettingsSectionFrame slug="gesundheitsakte">
|
||||
<SettingsSectionFrame slug="health-record">
|
||||
<GesundheitsakteSection />
|
||||
</SettingsSectionFrame>,
|
||||
);
|
||||
expect(html).toContain('id="settings-section-gesundheitsakte-title"');
|
||||
expect(html).toContain('id="settings-section-health-record-title"');
|
||||
expect(html).toContain('data-testid="health-record-export-panel"');
|
||||
// Raw key never leaks past i18n.
|
||||
expect(html).not.toContain("settings.sections.gesundheitsakte.");
|
||||
expect(html).not.toContain("settings.sections.health-record.");
|
||||
});
|
||||
|
||||
it("German locale resolves without leaking the raw key", () => {
|
||||
const html = render(<GesundheitsakteSection />, "de");
|
||||
expect(html).toContain('data-testid="health-record-export-panel"');
|
||||
expect(html).not.toContain("settings.sections.gesundheitsakte.");
|
||||
expect(html).not.toContain("settings.sections.health-record.");
|
||||
});
|
||||
});
|
||||
@@ -38,7 +38,7 @@ describe("layout-groups registry", () => {
|
||||
"labs",
|
||||
"illness",
|
||||
"documents",
|
||||
"vorsorge",
|
||||
"checkups",
|
||||
]);
|
||||
// generateStaticParams() shape.
|
||||
expect(LAYOUT_GROUP_IDS.map((module) => ({ module }))).toEqual([
|
||||
@@ -48,13 +48,13 @@ describe("layout-groups registry", () => {
|
||||
{ module: "labs" },
|
||||
{ module: "illness" },
|
||||
{ module: "documents" },
|
||||
{ module: "vorsorge" },
|
||||
{ module: "checkups" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("guards unknown segments", () => {
|
||||
expect(isLayoutGroupId("medications")).toBe(true);
|
||||
expect(isLayoutGroupId("vorsorge")).toBe(true);
|
||||
expect(isLayoutGroupId("checkups")).toBe(true);
|
||||
expect(isLayoutGroupId("nope")).toBe(false);
|
||||
expect(isLayoutGroupId("")).toBe(false);
|
||||
});
|
||||
@@ -68,10 +68,10 @@ describe("layout-groups registry", () => {
|
||||
expect(gate("mood")).toBe("not-a-group");
|
||||
expect(gate("labs")).toBe("labs");
|
||||
expect(gate("illness")).toBe("illness");
|
||||
// dashboard / insights / vorsorge are never gated.
|
||||
// dashboard / insights / checkups are never gated.
|
||||
expect(gate("dashboard")).toBeUndefined();
|
||||
expect(gate("insights")).toBeUndefined();
|
||||
expect(gate("vorsorge")).toBeUndefined();
|
||||
expect(gate("checkups")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("maps every id to a distinct section body and the canonical i18n keys", () => {
|
||||
|
||||
@@ -56,7 +56,7 @@ describe("<LayoutSection> hub", () => {
|
||||
"medications",
|
||||
"labs",
|
||||
"illness",
|
||||
"vorsorge",
|
||||
"checkups",
|
||||
]) {
|
||||
expect(html).toContain(`href="/settings/layout/${id}"`);
|
||||
}
|
||||
@@ -66,12 +66,12 @@ describe("<LayoutSection> hub", () => {
|
||||
const html = render({ medications: false, labs: false });
|
||||
expect(html).not.toContain('href="/settings/layout/medications"');
|
||||
expect(html).not.toContain('href="/settings/layout/labs"');
|
||||
// Other modules unaffected; Vorsorge is never gated.
|
||||
// Other modules unaffected; checkups are never gated.
|
||||
expect(html).toContain('href="/settings/layout/illness"');
|
||||
expect(html).toContain('href="/settings/layout/vorsorge"');
|
||||
expect(html).toContain('href="/settings/layout/checkups"');
|
||||
});
|
||||
|
||||
it("always lists dashboard, insights, and vorsorge (no module gate)", () => {
|
||||
it("always lists dashboard, insights, and checkups (no module gate)", () => {
|
||||
const html = render({
|
||||
medications: false,
|
||||
mood: false,
|
||||
@@ -80,7 +80,7 @@ describe("<LayoutSection> hub", () => {
|
||||
});
|
||||
expect(html).toContain('href="/settings/layout/dashboard"');
|
||||
expect(html).toContain('href="/settings/layout/insights"');
|
||||
expect(html).toContain('href="/settings/layout/vorsorge"');
|
||||
expect(html).toContain('href="/settings/layout/checkups"');
|
||||
// v1.44 — mood is tag management and left Arrangement for Modules.
|
||||
expect(html).not.toContain('href="/settings/layout/mood"');
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ const LAYOUT_CHILD_SLUGS = new Set([
|
||||
"mood",
|
||||
"labs",
|
||||
"illness",
|
||||
"vorsorge",
|
||||
"checkups",
|
||||
]);
|
||||
|
||||
export function SettingsSectionFrame({
|
||||
|
||||
@@ -120,7 +120,7 @@ describe("SETTINGS_SECTION_SLUGS", () => {
|
||||
// 301-redirects to `/settings/notifications`.
|
||||
// v1.18.0 — `modules` ("Was du trackst") sits right after `account` as
|
||||
// the single front door for enabling/disabling secondary domains.
|
||||
// v1.18.0 — `gesundheitsakte` (the full health-record export) lifts
|
||||
// v1.18.0 — `health-record` (the full health-record export) lifts
|
||||
// out of Export & Import into its own top-level entry, before `export`;
|
||||
// `coach` gathers the Coach preference cards out of the AI section and
|
||||
// sits right after `ai`.
|
||||
@@ -133,7 +133,7 @@ describe("SETTINGS_SECTION_SLUGS", () => {
|
||||
// first-class sections, right after `mood` (the three were standalone
|
||||
// `ModuleSettingsFrame` pages).
|
||||
// v1.18.7 — `sharing` (clinician share links) sits directly after
|
||||
// `gesundheitsakte`, before `export`: minting a read-only link to the
|
||||
// `health-record`, before `export`: minting a read-only link to the
|
||||
// health record belongs next to the health-record export.
|
||||
expect([...SETTINGS_SECTION_SLUGS]).toEqual([
|
||||
"account",
|
||||
@@ -164,7 +164,7 @@ describe("SETTINGS_SECTION_SLUGS", () => {
|
||||
"coach",
|
||||
"api",
|
||||
"mcp",
|
||||
"gesundheitsakte",
|
||||
"health-record",
|
||||
"export",
|
||||
"advanced",
|
||||
// v1.23 — "Data & Privacy" assembles the export / deletion / retention /
|
||||
@@ -246,7 +246,7 @@ describe("<SettingsShell>", () => {
|
||||
api: "connections",
|
||||
mcp: "connections",
|
||||
export: "data",
|
||||
gesundheitsakte: "data",
|
||||
"health-record": "data",
|
||||
privacy: "data",
|
||||
advanced: "data",
|
||||
about: "system",
|
||||
@@ -397,16 +397,16 @@ describe("<SettingsShell>", () => {
|
||||
// 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"',
|
||||
'href="/settings/health-record"',
|
||||
);
|
||||
expect(renderShell({ active: "account", modules: {} })).toContain(
|
||||
'href="/settings/gesundheitsakte"',
|
||||
'href="/settings/health-record"',
|
||||
);
|
||||
const optedOut = renderShell({
|
||||
active: "account",
|
||||
modules: { doctorReport: false },
|
||||
});
|
||||
expect(optedOut).toContain('href="/settings/gesundheitsakte"');
|
||||
expect(optedOut).toContain('href="/settings/health-record"');
|
||||
});
|
||||
|
||||
describe("inside somebody else's record", () => {
|
||||
@@ -507,7 +507,7 @@ describe("<SettingsShell>", () => {
|
||||
// form so we don't accidentally match a parser that double-escapes.
|
||||
expect(html).toContain("API & tokens");
|
||||
// v1.18.0 — the health record is its own top-level entry.
|
||||
expect(html).toContain('href="/settings/gesundheitsakte"');
|
||||
expect(html).toContain('href="/settings/health-record"');
|
||||
expect(html).toContain("Health record");
|
||||
// v1.4.16: the consolidated Export section is a top-level
|
||||
// entry in the sidebar; the link must be present in both locales.
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* "Freigabe" section) folds in here as a labelled "Sharing" group below the
|
||||
* export panel: a time-boxed read-only link is a sharing face of the SAME
|
||||
* health record. `/settings/sharing` 301-redirects to
|
||||
* `/settings/gesundheitsakte#sharing`. The backing model, the
|
||||
* `/settings/health-record#sharing`. The backing model, the
|
||||
* `/api/share-links` routes, and the public `/c/[token]` view are unchanged.
|
||||
*/
|
||||
|
||||
|
||||
@@ -99,9 +99,10 @@ export const LAYOUT_GROUPS: ReadonlyArray<LayoutGroup> = [
|
||||
Body: DocumentsSection,
|
||||
},
|
||||
{
|
||||
id: "vorsorge",
|
||||
titleKey: "settings.sections.layout.vorsorge.title",
|
||||
descriptionKey: "settings.sections.layout.vorsorge.description",
|
||||
// The address read `vorsorge` in every language; that one redirects.
|
||||
id: "checkups",
|
||||
titleKey: "settings.sections.layout.checkups.title",
|
||||
descriptionKey: "settings.sections.layout.checkups.description",
|
||||
Body: VorsorgeSection,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -41,7 +41,7 @@ export const SETTINGS_ANCHOR_FORWARDS: Readonly<
|
||||
"/settings/layout/medications": {
|
||||
"injection-sites": "/settings/modules/medications#injection-sites",
|
||||
},
|
||||
"/settings/layout/vorsorge": {
|
||||
"/settings/layout/checkups": {
|
||||
"screening-hints": "/settings/anamnesis#screening-hints",
|
||||
"vorsorge-reminders": "/settings/notifications#vorsorge-reminders",
|
||||
},
|
||||
|
||||
@@ -110,7 +110,7 @@ const LOADERS: Record<
|
||||
import("@/components/settings/api-section").then((m) => m.ApiSection),
|
||||
mcp: () =>
|
||||
import("@/components/settings/mcp-section").then((m) => m.McpSection),
|
||||
gesundheitsakte: () =>
|
||||
"health-record": () =>
|
||||
import("@/components/settings/gesundheitsakte-section").then(
|
||||
(m) => m.GesundheitsakteSection,
|
||||
),
|
||||
@@ -152,7 +152,7 @@ const SECTIONS: Record<SettingsSectionSlug, ComponentType<SectionProps>> = {
|
||||
}),
|
||||
api: dynamic(LOADERS.api, { loading: () => <SectionLoading /> }),
|
||||
mcp: dynamic(LOADERS.mcp, { loading: () => <SectionLoading /> }),
|
||||
gesundheitsakte: dynamic(LOADERS.gesundheitsakte, {
|
||||
"health-record": dynamic(LOADERS["health-record"], {
|
||||
loading: () => <SectionLoading />,
|
||||
}),
|
||||
export: dynamic(LOADERS.export, { loading: () => <SectionLoading /> }),
|
||||
|
||||
@@ -256,8 +256,8 @@ export const SETTINGS_SECTIONS: readonly SettingsSection[] = [
|
||||
// Not module-gated: the health record is a flagship export, and its only
|
||||
// entry point must not vanish behind the `doctorReport` opt-out.
|
||||
{
|
||||
slug: "gesundheitsakte",
|
||||
titleKey: "settings.sections.gesundheitsakte.title",
|
||||
slug: "health-record",
|
||||
titleKey: "settings.sections.health-record.title",
|
||||
icon: FileHeart,
|
||||
group: "data",
|
||||
},
|
||||
|
||||
@@ -171,17 +171,17 @@ export const SETTINGS_CARDS: ReadonlyArray<SettingsCardEntry> = [
|
||||
{ section: "integrations", anchor: "webhook", titleKey: "settings.webhook" },
|
||||
// ── Health record ──
|
||||
{
|
||||
section: "gesundheitsakte",
|
||||
section: "health-record",
|
||||
anchor: "health-record",
|
||||
titleKey: "settings.healthRecord.title",
|
||||
},
|
||||
{
|
||||
section: "gesundheitsakte",
|
||||
section: "health-record",
|
||||
anchor: "share-link-create",
|
||||
titleKey: "settings.sharing.createTitle",
|
||||
},
|
||||
{
|
||||
section: "gesundheitsakte",
|
||||
section: "health-record",
|
||||
anchor: "share-links-active",
|
||||
titleKey: "settings.sharing.activeTitle",
|
||||
},
|
||||
@@ -459,7 +459,7 @@ export const SETTINGS_LAYOUT_PAGES: ReadonlyArray<{
|
||||
titleKey: "settings.sections.layout.documents.title",
|
||||
module: "inboundDocuments",
|
||||
},
|
||||
{ slug: "vorsorge", titleKey: "settings.sections.layout.vorsorge.title" },
|
||||
{ slug: "checkups", titleKey: "settings.sections.layout.checkups.title" },
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -177,7 +177,7 @@ const ALL_STOPS: readonly TourStop[] = [
|
||||
id: "export",
|
||||
targetId: "export-hero",
|
||||
placement: "bottom",
|
||||
route: "/settings/gesundheitsakte",
|
||||
route: "/settings/health-record",
|
||||
titleKey: "onboarding.tour.steps.export.title",
|
||||
bodyKey: "onboarding.tour.steps.export.body",
|
||||
},
|
||||
|
||||
@@ -94,7 +94,7 @@ export const SETTINGS_DESTINATION_INVENTORY = {
|
||||
coach: MANAGED_GUARDIAN,
|
||||
api: PERSONAL,
|
||||
mcp: PERSONAL,
|
||||
gesundheitsakte: PERSONAL,
|
||||
"health-record": PERSONAL,
|
||||
export: PERSONAL,
|
||||
advanced: PERSONAL,
|
||||
privacy: PERSONAL,
|
||||
|
||||
@@ -44,9 +44,10 @@
|
||||
// canonical editors; reminder TYPES now live centrally in `notifications`,
|
||||
// each row gated on its module. `/settings/reminders` 301-redirects to
|
||||
// `/settings/notifications` (next.config.ts).
|
||||
// v1.18.0 — per-submodule settings split. `gesundheitsakte` (the full
|
||||
// v1.18.0 — per-submodule settings split. `health-record` (the full
|
||||
// health-record export, always available) lifts out of Export & Import into
|
||||
// its own top-level entry.
|
||||
// its own top-level entry. Its address was the German `gesundheitsakte` in
|
||||
// every language; that one redirects (next.config.ts).
|
||||
export const SETTINGS_SECTION_SLUGS = [
|
||||
"account",
|
||||
// v1.23 — `security` is the dedicated account-security home: second-factor
|
||||
@@ -75,7 +76,7 @@ export const SETTINGS_SECTION_SLUGS = [
|
||||
// `insights`, `medications`, `mood`, `labs`, `illness`, `vorsorge`) and
|
||||
// `sharing` left this list. Their URLs are owned by permanent redirects
|
||||
// in `next.config.ts` (`/settings/<module>` → `/settings/layout/<module>`,
|
||||
// `/settings/sharing` → `/settings/gesundheitsakte#sharing`), so the
|
||||
// `/settings/sharing` → `/settings/health-record#sharing`), so the
|
||||
// dynamic route could never serve them — prerendering eight unreachable
|
||||
// pages and keeping eight dead component wirings. The redirects, the
|
||||
// section components, and the layout-hub subpages are unchanged.
|
||||
@@ -106,7 +107,7 @@ export const SETTINGS_SECTION_SLUGS = [
|
||||
// assistant (Claude.ai / ChatGPT). Sits next to `api` (both are programmatic
|
||||
// access surfaces). Not nav-gated — the card carries its own enable toggle.
|
||||
"mcp",
|
||||
"gesundheitsakte",
|
||||
"health-record",
|
||||
"export",
|
||||
"advanced",
|
||||
// v1.23 — "Data & Privacy": a single surface that assembles the already-
|
||||
|
||||
Reference in new issue
Block a user