mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
Thirty-one files carried internal build vocabulary and anchors pointing at notes that are not in the repository: a reader of `checklist.ts` in a year would find its rationale keyed to a research id they cannot open, inside a comment that also names an internal build stage. Two test titles carried the same anchors. The version tags and the whole of the reasoning stay; only the vocabulary and the dangling references go, with the few sentences that were built around an anchor rewritten to stand on their own.
87 lines
3.4 KiB
TypeScript
87 lines
3.4 KiB
TypeScript
/**
|
|
* v1.39 (C2) — what the confirm screen says is switched on.
|
|
*
|
|
* A READ of the registry's derivation, never a second mapping: the list the
|
|
* person confirms is `deriveOnboardingModuleDefaults` applied to the same
|
|
* answers `POST /api/onboarding/complete` will apply it to, with the same
|
|
* conservative defaults for a skipped question. A wizard that computed its
|
|
* own list would drift from the one the route actually writes, and the
|
|
* confirm screen would then be confirming something else.
|
|
*
|
|
* What the route writes on top of this — the merge that never retracts a
|
|
* module switched on by hand or one holding data — only ever ADDS to the
|
|
* list, which is why the sentence beside it says "everything else stays
|
|
* under Settings" rather than "is off".
|
|
*/
|
|
import {
|
|
deriveOnboardingModuleDefaults,
|
|
mergeDerivedModulePreferences,
|
|
MODULE_KEYS,
|
|
ONBOARDING_ALWAYS_ON_MODULES,
|
|
type ModuleKey,
|
|
} from "@/lib/modules/registry";
|
|
|
|
import type { OnboardingNeeds } from "./needs";
|
|
|
|
export interface ConfirmedModules {
|
|
/** What the answers switch on, in registry order — the always-on trio aside. */
|
|
chosen: ModuleKey[];
|
|
/** On whatever the answers say. */
|
|
alwaysOn: ModuleKey[];
|
|
/**
|
|
* v1.39 — what the derivation takes OUT of the navigation:
|
|
* modules this record shows today that the answers do not ask for. Empty
|
|
* until the account payload has resolved, because a module the payload
|
|
* says nothing about is a module this screen knows nothing about.
|
|
*/
|
|
wouldSwitchOff: ModuleKey[];
|
|
}
|
|
|
|
/**
|
|
* @param current the module map the record shows today (`user.modules`), so
|
|
* the screen names only modules that are actually in the navigation now.
|
|
*/
|
|
export function confirmedModules(
|
|
needs: OnboardingNeeds,
|
|
current: Partial<Record<ModuleKey, boolean>> = {},
|
|
): ConfirmedModules {
|
|
const derived = deriveOnboardingModuleDefaults({
|
|
// Q1 is required and a confirm screen is never reached without it; the
|
|
// fallback only keeps the type total.
|
|
recordTarget: needs.recordTarget ?? "me",
|
|
areas: needs.areas,
|
|
// The same defaults the route applies to a skipped question.
|
|
medication: needs.medication ?? "no",
|
|
visit: needs.visit ?? "no",
|
|
});
|
|
const on = new Set<ModuleKey>();
|
|
for (const [key, value] of Object.entries(derived.preferences)) {
|
|
if (value) on.add(key as ModuleKey);
|
|
}
|
|
if (derived.cycleTracking) on.add("cycle");
|
|
const alwaysOn = new Set<ModuleKey>(ONBOARDING_ALWAYS_ON_MODULES);
|
|
// The registry's own merge rule decides what a derivation puts at `false`,
|
|
// so this screen never restates it. It is asked with nothing to spare —
|
|
// no stored preference, no domain holding rows — because that is the
|
|
// record the confirm screen is looking at on a first run, and it is the
|
|
// maximum the completion can take away. What the merge would spare on a
|
|
// re-run (a module switched on by hand, one holding data) it spares
|
|
// server-side, so this list can only ever be longer than what happens,
|
|
// never shorter, and the sentence beside it says how to get one back.
|
|
const afterDerivation = mergeDerivedModulePreferences(
|
|
{},
|
|
derived.preferences,
|
|
new Set<string>(),
|
|
);
|
|
return {
|
|
chosen: MODULE_KEYS.filter((key) => on.has(key) && !alwaysOn.has(key)),
|
|
alwaysOn: MODULE_KEYS.filter((key) => alwaysOn.has(key)),
|
|
wouldSwitchOff: MODULE_KEYS.filter(
|
|
(key) =>
|
|
!alwaysOn.has(key) &&
|
|
current[key] === true &&
|
|
afterDerivation[key] === false,
|
|
),
|
|
};
|
|
}
|