From e991fdf65dfbb65f29761a701312fca4f0e9ac21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Fri, 11 Sep 2026 10:54:14 +0200 Subject: [PATCH] fix(onboarding): a guardian is not told their own modules are leaving MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The confirm screen derived "Out of the navigation: …" from the acting account's module map and rendered it in every arm. In the "someone I look after" arm the completion never touches that account: it applies the derivation to the managed record, or, when none was created, to nothing at all. So a parent answering for a child was told Workouts, Cycle and Documents were leaving their own navigation when nothing was going to move. The arm now derives the list from an empty map, which makes it empty, and the sentence disappears with it. --- .../__tests__/confirm-screen.test.tsx | 19 +++++++++++++++++++ src/components/onboarding/confirm-screen.tsx | 13 ++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/components/onboarding/__tests__/confirm-screen.test.tsx b/src/components/onboarding/__tests__/confirm-screen.test.tsx index 274a05b74..1b77b9c6c 100644 --- a/src/components/onboarding/__tests__/confirm-screen.test.tsx +++ b/src/components/onboarding/__tests__/confirm-screen.test.tsx @@ -89,6 +89,25 @@ describe(" — modules leaving the navigation (C4)", () => { }); expect(html).not.toContain('data-slot="onboarding-confirm-modules-off"'); }); + + it("says nothing to a guardian, whose own record the answers never touch", () => { + // These answers describe the record being set up for somebody else. The + // completion applies the derivation to THAT record and stamps the + // guardian's own without deriving, so no module of the guardian's is + // going anywhere — and the sentence must not say one is. + const html = render( + state( + {}, + { + recordTarget: "someone-else", + areas: ["blood-pressure"], + medication: "no", + }, + ), + { medications: true, workouts: true, documents: true }, + ); + expect(html).not.toContain('data-slot="onboarding-confirm-modules-off"'); + }); }); describe(" — Settings links on a first run (C5)", () => { diff --git a/src/components/onboarding/confirm-screen.tsx b/src/components/onboarding/confirm-screen.tsx index dae55b0c8..83c9b1349 100644 --- a/src/components/onboarding/confirm-screen.tsx +++ b/src/components/onboarding/confirm-screen.tsx @@ -124,11 +124,18 @@ export function ConfirmScreen({ state }: { state: OnboardingStateDto }) { const settingsReachable = isOnboardingSettled(state) || state.completedAt !== null; const forSomeoneElse = needs.recordTarget === "someone-else"; - // v1.39 (Wave C, C4) — `user.modules` is the map the navigation reads, so - // the screen can only name a module the person actually has today. + // `user.modules` is the map the navigation reads, so the screen can only + // name a module the person actually has today — and only when the answers + // are about that record. In the "someone I look after" arm they are not: + // `POST /api/onboarding/complete` applies the derivation to the managed + // record (or, when none was created, to nothing at all) and stamps the + // guardian's own record without deriving. Reading the actor's map there + // would name modules that are staying exactly where they are — the same + // guardian-derivation confusion v1.38.18 closed in the write, re-entering + // through the copy. An empty map makes the list empty. const { chosen, alwaysOn, wouldSwitchOff } = confirmedModules( needs, - user?.modules ?? {}, + forSomeoneElse ? {} : (user?.modules ?? {}), ); const back = previousScreen(state, "confirm");