mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
Add the validated mental-health self-assessment surface, beside mood tracking (never replacing it) and off by default: - MentalHealthAssessment stores per-item answers in a single AES-256-GCM Bytes blob (registered for key rotation); only the server-authoritative total, severity band, and item-9 flag are denormalised. The total projects to a PHQ9_SCORE / GAD7_SCORE measurement row so the trend rides existing infra without ever exposing item content. - Item-9 safety: any non-zero PHQ-9 self-harm answer surfaces a calm, locale-aware crisis-resource set (DE: TelefonSeelsorge 0800 111 0 111 / 112; international fallback) and stamps crisisShownAt. No clinical interpretation, no AI ingestion of item content, no third-party alerting. - API + OpenAPI: POST/GET /api/mental-health/assessments; the response excludes raw item answers by construction. Required Pfizer/PHQ attribution lives in the instrument module, rendered verbatim. The screener scores are kept off the Coach snapshot and MCP surfaces, and out of exports by default — item content never reaches the AI pipeline.
119 lines
4.1 KiB
TypeScript
119 lines
4.1 KiB
TypeScript
/**
|
|
* OpenAPI route table — thin aggregation index.
|
|
*
|
|
* The route table is split into domain modules under this directory;
|
|
* this index assembles them into the single `openApiPaths` object the
|
|
* registry consumes. The spread order below is load-bearing: the YAML
|
|
* emitter runs with `sortMapEntries: false` (see
|
|
* `scripts/generate-openapi.ts`), so the key order of this object is
|
|
* the path order of the committed `docs/api/openapi.yaml`. Keep the
|
|
* spread sequence stable when adding a module — append inside the
|
|
* domain module, not by reordering here.
|
|
*
|
|
* Schemas come from `src/lib/validations/*` so the wire contract stays
|
|
* single-source-of-truth. The `.meta()` annotations on each schema land
|
|
* the title + description in `components.schemas.*` automatically.
|
|
*
|
|
* Routes are intentionally registered as inline operation objects
|
|
* rather than via a wrapping helper — `zod-openapi`'s `createDocument`
|
|
* type-checks the route table directly, which catches schema-shape
|
|
* regressions at typecheck time.
|
|
*/
|
|
import type { ZodOpenApiObject } from "zod-openapi";
|
|
|
|
import { adminDiagnosticPaths, adminInvitePaths } from "./admin";
|
|
import { authPaths } from "./auth";
|
|
import {
|
|
coachFeedbackPaths,
|
|
coachPaths,
|
|
coachReminderSuggestionPaths,
|
|
coachReminderPaths,
|
|
coachSuggestedActionPaths,
|
|
} from "./coach";
|
|
import { consentPaths } from "./consent";
|
|
import { cyclePaths } from "./cycle";
|
|
import { biomarkerPaths } from "./biomarkers";
|
|
import { devicePaths } from "./devices";
|
|
import { exportPaths } from "./export";
|
|
import { healthRecordPaths } from "./health-record";
|
|
import { illnessPaths } from "./illness";
|
|
import { importPaths } from "./import";
|
|
import { insightsPaths } from "./insights";
|
|
import { insightsSignalPaths } from "./insights-signals";
|
|
import { labsPaths } from "./labs";
|
|
import { ocrPaths } from "./ocr";
|
|
import { measurementPaths } from "./measurements";
|
|
import { measurementReminderPaths } from "./measurement-reminders";
|
|
import { mentalHealthPaths } from "./mental-health";
|
|
import { medicationPaths, medicationResource } from "./medications";
|
|
import { metaPaths } from "./meta";
|
|
import { moodPaths } from "./mood";
|
|
import { onboardingPaths } from "./onboarding";
|
|
import { profilePaths } from "./profile";
|
|
import { settingsPaths } from "./settings";
|
|
import { syncPaths } from "./sync";
|
|
import { workoutPaths } from "./workouts";
|
|
|
|
export const openApiPaths: NonNullable<ZodOpenApiObject["paths"]> = {
|
|
...cyclePaths,
|
|
...metaPaths,
|
|
...healthRecordPaths,
|
|
...exportPaths,
|
|
...authPaths,
|
|
...syncPaths,
|
|
...measurementPaths,
|
|
...workoutPaths,
|
|
...devicePaths,
|
|
...medicationPaths,
|
|
...profilePaths,
|
|
...coachPaths,
|
|
...coachReminderSuggestionPaths,
|
|
...coachReminderPaths,
|
|
...coachSuggestedActionPaths,
|
|
...adminInvitePaths,
|
|
...coachFeedbackPaths,
|
|
...adminDiagnosticPaths,
|
|
...insightsPaths,
|
|
...insightsSignalPaths,
|
|
...moodPaths,
|
|
...settingsPaths,
|
|
...consentPaths,
|
|
...importPaths,
|
|
...measurementReminderPaths,
|
|
...labsPaths,
|
|
...ocrPaths,
|
|
...biomarkerPaths,
|
|
...illnessPaths,
|
|
...mentalHealthPaths,
|
|
...onboardingPaths,
|
|
};
|
|
|
|
export const openApiComponents: NonNullable<ZodOpenApiObject["components"]> = {
|
|
// Schemas listed here are forced into `components.schemas` even when no
|
|
// route references them directly. `Medication` lives in this slot
|
|
// because its only consumers are the `MedicationListEntry` /
|
|
// `MedicationDetail` variants which extend it — `.extend()` inlines
|
|
// the base shape into the derived schema, so without an explicit
|
|
// registration the standalone `Medication` component would never
|
|
// emit. The iOS codegen reads from `Medication` directly for the
|
|
// shared Swift struct backing both variants.
|
|
schemas: {
|
|
Medication: medicationResource,
|
|
},
|
|
securitySchemes: {
|
|
bearerAuth: {
|
|
type: "http",
|
|
scheme: "bearer",
|
|
bearerFormat: "hlk_<64hex>",
|
|
description:
|
|
"Native-client API token. Use the `token` field returned by /api/auth/login on a native client.",
|
|
},
|
|
cookieAuth: {
|
|
type: "apiKey",
|
|
in: "cookie",
|
|
name: "healthlog_session",
|
|
description: "Browser session cookie — set by /api/auth/login.",
|
|
},
|
|
},
|
|
};
|