mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 06:40:50 +00:00
chore(release): v1.28.34 — nutrient intake lands as quiet context (server side)
Supplement-style intake written to Apple Health by nutrition apps — vitamins, minerals, water, caffeine — can now sync as daily totals into a dedicated NutrientIntakeDay store (migration 0241): composite (user, day, nutrient) identity, re-post replaces, no soft delete, no rollup coupling. A code-side catalog carries the 26 nutrient codes with canonical units, plausibility caps, and EFSA dietary reference values (direction-aware; chromium cites NIH ODS where EFSA declined a DRV). Deliberately not a nutrition feature: no diary, no calories, no dashboard surface. POST /api/nutrients/batch is gated behind the new opt-in nutrients module (default off — with the module off the server refuses ingest entirely), rate-limited, idempotency-wrapped, with per-entry unit-mismatch and out-of-range skips. GET /api/nutrients serves a catalog-ordered summary; the only visible surface is a read-only card under Settings → Sources. Coach/correlation access is a later slice; the iOS reading side is coordinated in the companion-app tracker.
This commit is contained in:
1 parent
14a9a08a6e
commit
5445fc67ea
34 files changed
+2766
-12
No files matched your search
@@ -357,14 +357,18 @@ describe("registry — opt-in marker", () => {
|
||||
// are highly sensitive: `mcp` (remote external-assistant endpoint),
|
||||
// `environment` (outbound weather fetch tied to a coarse location),
|
||||
// `inboundDocuments` (sends an uploaded clinical document to the OCR/vision
|
||||
// provider), and `mentalHealth` (a depression / anxiety self-assessment — at
|
||||
// least as sensitive as mood, surfaced only on explicit opt-in). Every other
|
||||
// provider), `mentalHealth` (a depression / anxiety self-assessment — at
|
||||
// least as sensitive as mood, surfaced only on explicit opt-in), and
|
||||
// `nutrients` (supplement-pattern intake synced from the phone's health
|
||||
// store — the device-side HealthKit permission is not visible consent to
|
||||
// server/AI-side storage, so ingest refuses while off). Every other
|
||||
// module is the default-on disabled-allowlist.
|
||||
const OPT_IN_KEYS = new Set([
|
||||
"mcp",
|
||||
"environment",
|
||||
"inboundDocuments",
|
||||
"mentalHealth",
|
||||
"nutrients",
|
||||
]);
|
||||
|
||||
it("marks only the egress-surface modules opt-in (every other is default-on)", () => {
|
||||
|
||||
@@ -147,6 +147,15 @@ export const MODULE_KEYS = [
|
||||
// assessment routes refuse server-side. Item answers are always encrypted and
|
||||
// always excluded from the AI Coach / MCP regardless of this toggle.
|
||||
"mentalHealth",
|
||||
// v1.28 — micronutrient-intake sync (vitamins, minerals, water,
|
||||
// caffeine as day totals from Apple Health). OPT-IN (off by default):
|
||||
// the HealthKit read permission is consent to read on the DEVICE, not
|
||||
// visible consent to "a server — and later an AI assistant — holds my
|
||||
// supplement pattern"; the project already answered this for less
|
||||
// sensitive data (`environment`, weather, is opt-in). With it off the
|
||||
// ingest route refuses (403 `module.disabled`) and the settings card
|
||||
// does not render. The `optIn` marker inverts the per-user default.
|
||||
"nutrients",
|
||||
] as const;
|
||||
|
||||
export type ModuleKey = (typeof MODULE_KEYS)[number];
|
||||
@@ -323,6 +332,17 @@ export const MODULE_REGISTRY: Readonly<Record<ModuleKey, ModuleDefinition>> =
|
||||
// off the AI Coach / MCP regardless.
|
||||
optIn: true,
|
||||
},
|
||||
nutrients: {
|
||||
key: "nutrients",
|
||||
labelKey: "modules.nutrients.label",
|
||||
descriptionKey: "modules.nutrients.description",
|
||||
category: "device",
|
||||
// Off by default: supplement-pattern intake synced from the phone's
|
||||
// health store is server/AI-consent-sensitive even though the
|
||||
// HealthKit read permission was granted on the device. Ships dark;
|
||||
// ingest refuses while off (refuse-ingest posture, not surface-only).
|
||||
optIn: true,
|
||||
},
|
||||
});
|
||||
|
||||
const MODULE_KEY_SET: ReadonlySet<string> = new Set(MODULE_KEYS);
|
||||
|
||||
Reference in new issue
Block a user