mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
GET /api/medications/intake/dose-history-import/{jobId}/status reads
through the same readMedicationIntakeImportJob projection as the
per-medication route, so both 200 responses now point at one shared
MedicationIntakeImportJobStatusEnvelope object instead of two
independently generated copies.
Audited every other route description for a schema named by id that
never resolves to a components.schemas entry. Found one more:
CoachPrefs is named in the coach-prefs PUT description, but every
actual consumer is a .extend() of it, so the base never carried
forward to a $ref. Force-registered it the same way as the
dose-history fatal-reason enum. The remaining unresolved meta ids are
request/query schemas zod-openapi inlines rather than hoists — none of
them are named by id in another schema's prose, so nothing points a
reader at a component that silently isn't there.
164 lines
6.1 KiB
TypeScript
164 lines
6.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 { allergyPaths } from "./allergies";
|
|
import { authPaths } from "./auth";
|
|
import {
|
|
coachFeedbackPaths,
|
|
coachPaths,
|
|
coachReminderSuggestionPaths,
|
|
coachReminderPaths,
|
|
coachSuggestedActionPaths,
|
|
} from "./coach";
|
|
import { consentPaths } from "./consent";
|
|
import { customMetricPaths } from "./custom-metrics";
|
|
import { dailyPaths } from "./daily";
|
|
import { cyclePaths } from "./cycle";
|
|
import { dashboardWidgetPaths } from "./dashboard";
|
|
import { biomarkerPaths } from "./biomarkers";
|
|
import { inboundDocumentPaths } from "./documents";
|
|
import { devicePaths } from "./devices";
|
|
import { exportPaths } from "./export";
|
|
import { familyHistoryPaths } from "./family-history";
|
|
import { healthRecordPaths } from "./health-record";
|
|
import { illnessPaths } from "./illness";
|
|
import { importPaths } from "./import";
|
|
import { insightsPaths } from "./insights";
|
|
import { integrationPaths } from "./integrations";
|
|
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,
|
|
medicationDoseHistoryImportFatalReasonEnum,
|
|
} from "./medications";
|
|
import { metaPaths } from "./meta";
|
|
import { moodPaths } from "./mood";
|
|
import { nutrientPaths } from "./nutrients";
|
|
import { onboardingPaths } from "./onboarding";
|
|
import { profilePaths } from "./profile";
|
|
import { settingsPaths } from "./settings";
|
|
import { syncPaths } from "./sync";
|
|
import { workoutPaths } from "./workouts";
|
|
import { coachPrefsSchema } from "@/lib/validations/coach-prefs";
|
|
|
|
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,
|
|
...allergyPaths,
|
|
...familyHistoryPaths,
|
|
...inboundDocumentPaths,
|
|
...customMetricPaths,
|
|
...onboardingPaths,
|
|
// v1.28 — nutrient-intake sync (appended; spread order is load-bearing).
|
|
...nutrientPaths,
|
|
// v1.28 — HealthKit integration config (appended; spread order is
|
|
// load-bearing).
|
|
...integrationPaths,
|
|
// v1.28 — the unified daily digest (P3 spine; appended, spread order is
|
|
// load-bearing).
|
|
...dailyPaths,
|
|
// v1.32.21 (R5a) — dashboard widget layout: previously absent from the
|
|
// registry entirely, now documented as the reference optimistic-concurrency
|
|
// contract (appended, spread order is load-bearing).
|
|
...dashboardWidgetPaths,
|
|
};
|
|
|
|
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.
|
|
//
|
|
// `MedicationDoseHistoryImportFatalReason` lives here for the same reason:
|
|
// the dose-history-import 422 description names it as the closed set
|
|
// behind `errorCode`, but `ErrorEnvelope.meta.errorCode` is a bare string
|
|
// shared by every route, so nothing ever `$ref`s the enum itself. Without
|
|
// this forced registration the schema the description points to would be
|
|
// silently absent from the published spec.
|
|
//
|
|
// `CoachPrefs` is the same shape: the PUT `/api/auth/me/coach-prefs`
|
|
// description tells the reader "Body is validated against `CoachPrefs`",
|
|
// but every actual consumer is a `.extend()` of it (`PutCoachPrefsRequest`,
|
|
// `CoachPrefsResponse`) — `.extend()` builds a new object, so the base
|
|
// never carries forward to a $ref on its own.
|
|
schemas: {
|
|
Medication: medicationResource,
|
|
MedicationDoseHistoryImportFatalReason:
|
|
medicationDoseHistoryImportFatalReasonEnum,
|
|
CoachPrefs: coachPrefsSchema,
|
|
},
|
|
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.",
|
|
},
|
|
},
|
|
};
|