Publish the mood-tag layout schema its own description relies on

The annotation was already in the assigning form and still never reached
the document, because both consumers extend the base rather than
reference it and .extend() builds a new object. Same shape as Medication
and CoachPrefs, same remedy: name it in the forced-registration block.
This commit is contained in:
Marc-André Bombeck committed 2026-08-22 15:34:27 +02:00
1 parent 50287d2743
commit 60e17a2617
3 files changed
+44 -2

No files matched your search

+28
View File
@@ -68573,6 +68573,34 @@ components:
- showEvidenceByDefault
- defaultWindow
additionalProperties: false
MoodTagLayout:
type: object
properties:
groupOrder:
maxItems: 50
type: array
items:
type: string
minLength: 1
maxLength: 80
placements:
type: object
propertyNames:
type: string
minLength: 1
maxLength: 80
additionalProperties:
type: array
items:
type: string
minLength: 1
maxLength: 80
additionalProperties: false
description: "Per-user mood-tag presentation blob. `groupOrder`: category keys in display order (unknown dropped,
missing appended in seeded order). `placements`: categoryKey → ordered tag keys; a placed tag renders in that
group at that index, un-placed tags follow in their home category. Display-only — placements referencing
hidden/archived/unknown keys are silently dropped at read time. Both fields optional: PUT merges
preserve-when-absent."
parameters:
AccountSelector:
name: X-HealthLog-Account
+7 -1
View File
@@ -72,7 +72,7 @@ import {
} from "./medications";
import { mcpPaths } from "./mcp";
import { metaPaths } from "./meta";
import { moodPaths } from "./mood";
import { moodPaths, moodTagLayout } from "./mood";
import { notificationTransportPaths } from "./notifications-transport";
import { notificationChannelPaths } from "./notifications";
import { nutrientPaths } from "./nutrients";
@@ -183,6 +183,11 @@ export const openApiComponents: NonNullable<ZodOpenApiObject["components"]> = {
// this forced registration the schema the description points to would be
// silently absent from the published spec.
//
// `MoodTagLayout` joins them for exactly the same reason: its annotation is
// in the assigning form and correct, but both consumers `.extend()` it, so
// the base name is never referenced and the description the mood surface
// relies on would go unpublished.
//
// `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`,
@@ -193,6 +198,7 @@ export const openApiComponents: NonNullable<ZodOpenApiObject["components"]> = {
MedicationDoseHistoryImportFatalReason:
medicationDoseHistoryImportFatalReasonEnum,
CoachPrefs: coachPrefsSchema,
MoodTagLayout: moodTagLayout,
},
// v1.36.0 — the per-request account selector, defined in the sharing route
// module so that `src/__tests__/acting-account-boundary-guard.test.ts` keeps
+9 -1
View File
@@ -114,7 +114,15 @@ const listMoodEntriesQuery = listMoodEntriesSchema.meta({
"Filters + paging for the mood-entry list. `from` / `to` bound the local-day `date` label (YYYY-MM-DD, inclusive). `limit` capped at 500.",
});
const moodTagLayout = moodTagLayoutSchema.meta({
/**
* Exported for the forced registration in `./index.ts`.
*
* Both consumers are an `.extend()` of this base, and `.extend()` builds a new
* object rather than a reference, so the name never carries forward on its own
* even though the annotation is in the assigning form. Same shape as
* `CoachPrefs` and `Medication`, and the same remedy.
*/
export const moodTagLayout = moodTagLayoutSchema.meta({
id: "MoodTagLayout",
description:
"Per-user mood-tag presentation blob. `groupOrder`: category keys in display order (unknown dropped, missing appended in seeded order). `placements`: categoryKey → ordered tag keys; a placed tag renders in that group at that index, un-placed tags follow in their home category. Display-only — placements referencing hidden/archived/unknown keys are silently dropped at read time. Both fields optional: PUT merges preserve-when-absent.",