fix: mark mirror adherence not applicable

This commit is contained in:
muhdusama committed 2026-09-20 21:48:20 +10:00
1 parent c223b6d77d
commit 41d47c3184
24 files changed
+416 -69

No files matched your search

+2 -2
View File
@@ -1413,7 +1413,7 @@ export const medicationPaths: NonNullable<ZodOpenApiObject["paths"]> = {
tags: ["Medications"],
summary: "Batched adherence read for every medication of the caller",
description:
"Returns one compact adherence row per medication the caller owns (active + paused), ordered by `createdAt DESC` — the single round trip the medication cards consume instead of fanning out one `/api/medications/{id}/compliance` request per card. Each row carries the 7-/30-day summaries and the cadence-scaled display block; the per-day grid stays on the per-medication endpoint. Pure computation — no writes. Served through the same per-medication server cache as the per-id read, so the two endpoints warm each other.",
"Returns one compact row per non-PRN medication. A scheduled medication with no local schedule remains in the array with applicable=false, reason NO_LOCAL_SCHEDULE, and null percentage/display fields so card and table clients do not mistake it for 100 percent or leave it loading.",
responses: {
...recordRefusal(),
"200": {
@@ -1436,7 +1436,7 @@ export const medicationPaths: NonNullable<ZodOpenApiObject["paths"]> = {
tags: ["Medications"],
summary: "Adherence read for a medication",
description:
"Returns the 7- and 30-day adherence summaries, the per-day compliance grid for the history glyph track, and the two-row display block. Pure computation — no writes. Day boundaries are resolved in the user's IANA timezone, and the expected-dose denominator is cadence-aware (RRULE / rolling / one-shot / PRN / cyclic) and clamped to the medication's `createdAt`. Read `compliance30` for the headline 30-day taken-vs-expected percentage; build the per-day glyph track from `dailyCompliance` (draw a cell only where `due === true`).",
"Returns the cadence-aware adherence payload. A scheduled medication with no local schedule returns applicable=false, reason NO_LOCAL_SCHEDULE, null percentage/display fields, and an empty daily grid. Medications with a local schedule preserve the existing arithmetic, including windows in which no dose is due.",
requestParams: {
path: z.object({ id: z.string() }),
},
+38 -9
View File
@@ -755,32 +755,61 @@ export const complianceDisplay = z
export const medicationComplianceResponse = z
.object({
compliance7: complianceResult,
compliance30: complianceResult,
applicable: z
.boolean()
.describe(
"Whether a local adherence percentage applies to this medication.",
),
notApplicableReason: z
.literal("NO_LOCAL_SCHEDULE")
.nullable()
.describe(
"Reason adherence is not applicable. NO_LOCAL_SCHEDULE means the medication has no HealthLog-owned expected-dose grid.",
),
compliance7: complianceResult
.nullable()
.describe(
"Seven-day adherence summary, or null when applicable is false.",
),
compliance30: complianceResult
.nullable()
.describe(
"Thirty-day adherence summary, or null when applicable is false.",
),
dailyCompliance: z
.record(z.string(), dailyComplianceEntry)
.describe(
"Flat per-day map keyed `YYYY-MM-DD` in the user timezone, one entry per day for up to 90 days back, clamped to the medication's `createdAt` (so a recently-created med has fewer entries). No weekly/monthly collapse — this is the raw daily grid.",
"Flat per-day map keyed YYYY-MM-DD in the user timezone. Empty when adherence is not applicable.",
),
complianceDisplay: complianceDisplay
.nullable()
.describe(
"Cadence-scaled display block, or null when adherence is not applicable.",
),
complianceDisplay,
})
.meta({
id: "MedicationComplianceResponse",
description:
"Adherence read for a single medication. `compliance30` is the authoritative 30-day taken-vs-expected summary; `dailyCompliance` is the per-day grid for the history glyph track. The graded raw→week→month→year series used elsewhere for AI prompts does NOT apply here — this response is never downsampled.",
"Adherence read for a single medication. A scheduled medication with no local schedule returns applicable=false and NO_LOCAL_SCHEDULE rather than a vacuous 100 percent. Scheduled medications that have a local schedule keep the existing cadence-aware arithmetic, including windows with no doses due. PRN behaviour is unchanged.",
});
export const medicationComplianceSummaryEntry = z
.object({
medicationId: z.string(),
compliance7: complianceResult,
compliance30: complianceResult,
complianceDisplay,
applicable: z
.boolean()
.describe(
"Whether this medication has a local expected-dose grid and therefore a displayable adherence percentage.",
),
notApplicableReason: z.literal("NO_LOCAL_SCHEDULE").nullable(),
compliance7: complianceResult.nullable(),
compliance30: complianceResult.nullable(),
complianceDisplay: complianceDisplay.nullable(),
})
.meta({
id: "MedicationComplianceSummaryEntry",
description:
"Compact per-medication adherence row for the batched card read: the 7-/30-day summaries plus the cadence-scaled display block. The per-day `dailyCompliance` grid is NOT on this shape — read the per-medication `/compliance` endpoint for the history glyph track.",
"Compact per-medication adherence row for the batched card read. Zero-local-schedule scheduled medications remain present with applicable=false so clients render a settled not-applicable state instead of a loading skeleton.",
});
// v1.16.5 — schedule-era management (the Zeitplan-tab history timeline).