mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
feat(api): publish the setup state on the account payload, and read it
Additive: `onboarding` carries the nine steps with their status, the answers as given, the flow's own completion stamp and the one task it offered. Always present — a record that never entered the flow reads as empty answers with nine pending steps, so a client branches on the statuses rather than on whether the field exists, and an unknown step id is skipped rather than refused. It is resolved for the CALLER's own record rather than for the active one, unlike the two module fields beside it. The three write routes are actor-only, and publishing a setup state the browser cannot write would be a read it could act on and never complete. Both ends land here, because a field with no reader is the failure this repository keeps rediscovering. The getting-started checklist orders its rows from the answers — medication first for somebody who takes one daily, the data-source row first for somebody who named a wearable — and it stays on screen while the flow is unfinished. That is the second half: five readings were never evidence that the setup finished, and now a pending step, an unconfirmed set of answers or an offered task that produced nothing keeps the list where it is. The ordering only applies once the answers are confirmed. Re-ordering the dashboard under somebody who is still mid-question would be movement they did not ask for.
This commit is contained in:
1 parent
021ea8f1ff
commit
dbfad0f28e
7 files changed
+852
-35
No files matched your search
@@ -23,6 +23,7 @@ import { isDateFormatPreference, storeDateFormat } from "@/lib/date-format";
|
||||
import { storeTimezone } from "@/lib/timezone-mirror";
|
||||
import type { ModuleKey } from "@/lib/modules/registry";
|
||||
import type { ModuleAccessState } from "@/lib/sharing/module-disclosure";
|
||||
import type { OnboardingStateDto } from "@/lib/onboarding/needs";
|
||||
import type { TourProgress } from "@/lib/onboarding/tour-progress";
|
||||
import { clearOfflineCachesForSessionEnd } from "@/lib/pwa/query-persister";
|
||||
import {
|
||||
@@ -81,6 +82,18 @@ export interface AuthUser {
|
||||
* `onboardingTourCompleted` boolean, which stays the auto-launch gate.
|
||||
*/
|
||||
onboardingTourProgress: AuthTourProgress | null;
|
||||
/**
|
||||
* v1.39 (C1) — the needs-based setup flow's state for this record: the nine
|
||||
* ordered steps with their `pending | done | skipped` status, the answers as
|
||||
* given, the flow's own completion stamp (distinct from
|
||||
* `onboardingCompletedAt` above, which stays the first-run redirect's gate)
|
||||
* and the one task the flow offered.
|
||||
*
|
||||
* Optional in the type so a stale /me payload — an older server image, or a
|
||||
* test fixture written before the field existed — coerces to "no flow" in
|
||||
* the mapper below rather than failing the shape.
|
||||
*/
|
||||
onboarding?: OnboardingStateDto | null;
|
||||
/**
|
||||
* v1.18.6 (DISC-02) — ISO timestamp of the one-time medical-disclaimer
|
||||
* acknowledgment, or null when never acknowledged. The onboarding welcome
|
||||
@@ -386,6 +399,10 @@ export async function fetchMe(): Promise<AuthUser> {
|
||||
// v1.18.6 — coerce against a stale /me payload (older server image
|
||||
// without the field) to null so the tour starts from the top.
|
||||
onboardingTourProgress: data.onboardingTourProgress ?? null,
|
||||
// v1.39 (C1) — coerce against a stale /me payload (an older server image
|
||||
// without the field) to null, which every reader treats as "no flow was
|
||||
// ever run" rather than as an unfinished one.
|
||||
onboarding: data.onboarding ?? null,
|
||||
// v1.7.0 — coerce against a stale /me payload (older server image
|
||||
// without the field) so the display defaults to metric.
|
||||
unitPreference: data.unitPreference === "imperial" ? "imperial" : "metric",
|
||||
|
||||
Reference in new issue
Block a user