feat(mental-health): screener UI, locale-aware copy, and OpenAPI surface

Add the opt-in PHQ-9 / GAD-7 questionnaire surface at /insights/mental-wellbeing:
instrument picker, 0–3 item scale, server-scored result with the validated
severity band, the verbatim Pfizer/PHQ attribution, the screening-not-diagnosis
disclaimer, and a calm crisis-resource card on a positive item-9. The surface
deliberately does NOT mount the shared Coach-launch card — mental-health item
content stays out of the AI.

- i18n: full mentalHealth block plus the six new measurement-type labels and the
  longevity-marker catalogue names/descriptions across all six locales
  (de/en/es/fr/it/pl). Instrument item wording uses the validated German text and
  the canonical English elsewhere (re-wording invalidates the score).
- OpenAPI: regenerate the contract for /api/mental-health/assessments (response
  excludes raw item answers by construction).
- Exclude the new manual / instrument types from the HealthKit-counterpart guard.
This commit is contained in:
Marc-André Bombeck committed 2026-06-28 16:05:51 +02:00
1 parent 7575275d7e
commit c322a68d19
13 files changed
+1453 -22

No files matched your search

@@ -40,7 +40,10 @@ import {
type InstrumentId,
} from "@/lib/mental-health/instruments";
import { crisisResourcesForLocale } from "@/lib/mental-health/crisis-resources";
import type { MeasurementType, MeasurementSource } from "@/generated/prisma/client";
import type {
MeasurementType,
MeasurementSource,
} from "@/generated/prisma/client";
function shapeRow(row: {
id: string;
@@ -81,7 +84,11 @@ export const GET = apiHandler(async (request: NextRequest) => {
}
const { instrument, limit, offset } = parsed.data;
const rows = await prisma.mentalHealthAssessment.findMany({
where: { userId: user.id, deletedAt: null, ...(instrument ? { instrument } : {}) },
where: {
userId: user.id,
deletedAt: null,
...(instrument ? { instrument } : {}),
},
orderBy: { takenAt: "desc" },
take: limit ?? 100,
skip: offset ?? 0,