Files
HealthLog/docs/api
Marc-André Bombeck 609d248252 feat(cycle): choose cervix as the symptothermal secondary symptom
Let a user pick the Sensiplan double-check's second indicator — cervical
mucus (default) or cervix observation — mirroring the published NFP
standard where the temperature primary sign pairs with one chosen
secondary sign.

- `CycleProfile.secondarySymptom` (MUCUS default | CERVIX) drives which
  second sign the engine confirms against. Casual users keep temperature
  + mucus untouched; the choice lives behind the advanced cycle settings.
- `CycleDayLog` gains the three standard cervix signs — position
  (LOW/HIGH), firmness (FIRM/SOFT), opening/os (CLOSED/OPEN) — as nullable
  columns (migration 0157), wired through Zod, the day-log upsert, the
  DTO, the sync feed, backup/restore and OpenAPI. Additive and
  back-compatible: existing profiles backfill MUCUS, existing day-logs
  keep NULL cervix signs, iOS inherits the fields.
- The engine's `confirmSymptothermal` takes the secondary-symptom choice;
  on CERVIX it confirms against `detectCervixPeak` (last fertile-cervix
  day followed by three closed days — the cervix-closure rule) instead of
  the mucus peak. The double-check still requires BOTH the temperature
  shift AND the secondary peak: a single cervix sign never confirms, and
  the still-learning gate and conservative posture are unchanged.

Engine derived clean-room from the Arbeitsgruppe-NFP / Raith-Paula &
Frank-Herrmann standard.
2026-06-14 15:23:26 +02:00
..
2026-05-03 21:53:21 +02:00

HealthLog API Spec

openapi.yaml is the canonical OpenAPI 3.1 description for the HealthLog Next.js API. It is the source of truth for the native iOS client's DTO codegen.

Preview locally

Open an interactive Redoc preview in your browser:

npx @redocly/cli preview docs/api/openapi.yaml

Generate static HTML for sharing:

npx @redocly/cli build-docs docs/api/openapi.yaml --output docs/api/index.html

Validate

npx @redocly/cli lint docs/api/openapi.yaml

The spec is expected to be lint-clean (errors = 0). Some warnings are intentional:

  • no-server-example.com — http://localhost:3000 is the dev server.
  • operation-2xx-response / operation-4xx-response — webhook + redirect endpoints intentionally omit one or the other.
  • no-unused-components — ReminderPhase is exposed for client codegen even though no path response references it directly.

Layout

  • info — title, version (mirrored from package.json), description.
  • servers — production https://healthlog.bombeck.io plus http://localhost:3000 for local development.
  • tags — domain groupings (Auth, Measurements, Medications, Mood, Dashboard, Insights, Achievements, DoctorReport, Integrations, User, Tokens, Notifications, Onboarding, Health, Settings, Analytics, Export, AuditLog, Feedback, BugReport, Monitoring, Webhooks, Ingest, Admin).
  • securitySchemes:
    • bearerAuth — long-lived hlk_* API tokens issued via POST /api/tokens. Required on /api/ingest/medication.
    • sessionCookie — HttpOnly healthlog_session cookie set by the password and passkey login flows. Used by the web app and any iOS client running inside a web view.
  • components.schemas — DTOs for all routes plus the underlying Prisma models (e.g. Measurement, Medication, MedicationIntakeEvent, MoodEntry, User, DashboardLayout, ApiEnvelope, ApiError).
  • paths — all routes from src/app/api/**/route.ts, including the /api/admin/* family which is tagged Admin and marked internal.

Conventions

  • Successful responses use the envelope { data, error: null }.
  • Error responses use the envelope { data: null, error: '<message>' }.
  • Pagination uses limit + offset query parameters and a meta: { total, limit, offset } block on the response.
  • All timestamps are ISO 8601 / RFC 3339 (format: date-time) in UTC.
  • IDs are CUIDs (opaque strings).

Updating the spec

When adding or changing routes:

  1. Update the relevant route handler under src/app/api/**/route.ts.
  2. Mirror the change in openapi.yaml. Keep operationId camelCase and stable — the iOS codegen keys off it.
  3. Run npx @redocly/cli lint docs/api/openapi.yaml and resolve all errors. Warnings are tolerated when documented above.
  4. Bump info.version if the change is breaking for clients.