feat(api): surface and update per-user module preferences

GET /api/auth/me now returns a resolved modules map for every toggleable
module (cycle/coach reflect their delegated state). New PATCH/GET
/api/auth/me/modules read and update the preferences: the body is strict
over the toggleable key set so a core-domain or unknown key is a 422, the
merge is field-by-field (no mass assignment), and userId is narrowed from
the session. Documented in the OpenAPI registry and yaml.

The disable-coach gate-inventory allowlist records the module gate's
intentional coach delegation read.
This commit is contained in:
Marc-André Bombeck committed 2026-06-15 20:54:02 +02:00
1 parent d1089ba232
commit fa53631c55
7 files changed
+738 -1

No files matched your search

@@ -317,6 +317,12 @@ describe("Coach per-user disableCoach invariant", () => {
// builder.
"src/lib/dashboard/snapshot.ts",
"src/app/api/dashboard/snapshot/route.ts",
// v1.18.0 — the module enable/disable gate delegates the `coach`
// module to the SAME two-layer source of truth (`user.disableCoach`
// AND the operator assistant master flag) rather than owning a
// second copy in `modulePreferencesJson`. Covered by the coach-
// delegation cases in `src/lib/modules/__tests__/gate.test.ts`.
"src/lib/modules/gate.ts",
];
/**