Tighten the setup flow after a review of the whole diff

The done screen moves focus to its heading like every other screen; the
confirm screen's preference list holds only dt/dd pairs and the settings
link stands beside it; Back from Q1 is not offered once the flow has
been entered, because the front door would resume past the welcome and
bounce straight back; the medication task records no target on the
ledger, as the contract says, and keeps the id on the screen; and the
two success affordances go through the outcome module rather than a
hand-rolled tick. The error-code catalogue lists the answers and restart
codes and no longer the retired step ones, and the session-surface guard
learns the one new deriving helper the onboarding pages read through.
This commit is contained in:
Marc-André Bombeck committed 2026-09-10 16:09:18 +02:00
1 parent 2686da2803
commit 8c7cdcfc2b
9 files changed
+78 -89

No files matched your search

-12
View File
@@ -14,7 +14,6 @@
import type { OnboardingSourceKey } from "./needs";
import {
hasEnteredOnboardingFlow,
ONBOARDING_STEP_IDS,
type OnboardingFirstResultTask,
type OnboardingNeeds,
type OnboardingStateDto,
@@ -23,17 +22,6 @@ import {
export type OnboardingScreenId = "welcome" | OnboardingStepId;
export const ONBOARDING_SCREEN_IDS: readonly OnboardingScreenId[] = [
"welcome",
...ONBOARDING_STEP_IDS,
];
export function isOnboardingScreenId(
value: string,
): value is OnboardingScreenId {
return (ONBOARDING_SCREEN_IDS as readonly string[]).includes(value);
}
/**
* The Q4 sources whose connection the browser can finish on its own — an
* OAuth handshake or a URL-plus-secret form on Settings → Integrations.
+4 -6
View File
@@ -234,15 +234,13 @@ export const ERROR_CODE_CATALOGUE: Readonly<Record<string, readonly string[]>> =
"nutrient.water.invalid_day",
],
onboarding: [
"onboarding.answers.invalid",
"onboarding.answers.rateLimited",
"onboarding.complete.invalid",
"onboarding.disclaimer.invalid",
"onboarding.step.completed",
"onboarding.step.concurrent",
"onboarding.step.invalid",
"onboarding.step.outOfOrder",
"onboarding.step.rateLimited",
"onboarding.restart.invalid",
"onboarding.restart.rateLimited",
"onboarding.tour.invalid",
"onboarding.user.notFound",
],
personal_records: ["personal_records.invalid_query"],
practitioner: ["practitioner.invalid"],
+3 -3
View File
@@ -18,12 +18,12 @@ export const onboardingKeys = {
/** `POST /api/onboarding/disclaimer` — the one-time acknowledgment. */
onboardingDisclaimerMutation: () => ["onboarding", "disclaimer"] as const,
/**
* The latest reading of one type, read back after the first-result step
* The latest reading of one area, read back after the first-result step
* logged it so the screen can show the value on its tile. Rides under the
* `["measurements"]` prefix so `measurementDependentKeys` evicts it.
*/
onboardingLatestReading: (type: string) =>
["measurements", "onboarding-latest", type] as const,
onboardingLatestReading: (area: string) =>
["measurements", "onboarding-latest", area] as const,
/**
* The upcoming-visit count the checklist's "prepare the visit" row reads
* off the visits list's meta. Its own key under the `["encounters"]`