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

@@ -125,6 +125,7 @@ function medication(schedules: unknown[]) {
startsOn: null,
endsOn: null,
oneShot: false,
asNeeded: false,
schedules,
};
}
@@ -160,6 +161,29 @@ async function callRouteData(): Promise<Record<string, unknown>> {
return body.data as Record<string, unknown>;
}
describe("GET /api/medications/[id]/compliance - applicability", () => {
it("returns not-applicable instead of 100 percent for a scheduled mirror with no local schedule", async () => {
vi.mocked(prisma.medication.findUnique).mockResolvedValue({
...medication([]),
asNeeded: false,
externalSource: "APPLE_HEALTH",
externalId: "hk-concept-1",
} as never);
const data = await callRouteData();
expect(data).toEqual({
applicable: false,
notApplicableReason: "NO_LOCAL_SCHEDULE",
compliance7: null,
compliance30: null,
dailyCompliance: {},
complianceDisplay: null,
});
expect(prisma.medicationIntakeEvent.findMany).not.toHaveBeenCalled();
});
});
describe("GET /api/medications/[id]/compliance — per-slot timing", () => {
it("classifies both doses of a single-row twice-daily schedule as on_time (green cell)", async () => {
const { start: dayStart } = dayBoundsForOffset(DAY_OFFSET);
@@ -334,6 +358,8 @@ describe("GET /api/medications/[id]/compliance — complianceDisplay", () => {
short: { rate: number; streak: number };
long: { rate: number };
};
expect(data.applicable).toBe(true);
expect(data.notApplicableReason).toBeNull();
expect(display.shortDays).toBe(7);
expect(display.longDays).toBe(30);
expect(display.expectedLong).toBeGreaterThanOrEqual(display.minStableDoses);
@@ -96,12 +96,17 @@ export const GET = apiHandler(
entity_type: "medication",
entity_id: id,
},
meta: {
compliance7: payload.compliance7.rate,
compliance30: payload.compliance30.rate,
complianceShortDays: payload.complianceDisplay.shortDays,
complianceLongDays: payload.complianceDisplay.longDays,
},
meta: payload.applicable
? {
compliance7: payload.compliance7!.rate,
compliance30: payload.compliance30!.rate,
complianceShortDays: payload.complianceDisplay!.shortDays,
complianceLongDays: payload.complianceDisplay!.longDays,
}
: {
complianceApplicable: false,
complianceNotApplicableReason: payload.notApplicableReason,
},
});
return apiSuccess(payload);
@@ -93,6 +93,7 @@ function medication(id: string) {
startsOn: null,
endsOn: null,
oneShot: false,
asNeeded: false,
schedules: [dailySchedule(`${id}-sched`)],
scheduleRevisions: [],
};
@@ -133,6 +134,8 @@ describe("GET /api/medications/compliance", () => {
expect(items).toHaveLength(2);
expect(items.map((i) => i.medicationId)).toEqual(["med-1", "med-2"]);
for (const item of items) {
expect(item.applicable).toBe(true);
expect(item.notApplicableReason).toBeNull();
expect(item.compliance7).toBeDefined();
expect(item.compliance30).toBeDefined();
expect(item.complianceDisplay).toBeDefined();
@@ -141,6 +144,35 @@ describe("GET /api/medications/compliance", () => {
}
});
it("returns a settled not-applicable row for a scheduled mirror with no local schedule", async () => {
vi.mocked(prisma.medication.findMany).mockResolvedValue([
{
...medication("mirror-1"),
asNeeded: false,
externalSource: "APPLE_HEALTH",
externalId: "hk-concept-1",
schedules: [],
},
] as never);
const res = await (GET as (req: Request) => Promise<Response>)(
new Request("http://localhost"),
);
expect(res.status).toBe(200);
const body = await res.json();
expect(body.data).toEqual([
{
medicationId: "mirror-1",
applicable: false,
notApplicableReason: "NO_LOCAL_SCHEDULE",
compliance7: null,
compliance30: null,
complianceDisplay: null,
},
]);
expect(prisma.medicationIntakeEvent.findMany).not.toHaveBeenCalled();
});
it("reads each medication through the shared per-medication cache cell", async () => {
vi.mocked(prisma.medication.findMany).mockResolvedValue([
medication("med-1"),
@@ -174,7 +206,10 @@ describe("GET /api/medications/compliance", () => {
const call = vi.mocked(prisma.medication.findMany).mock.calls[0][0] as {
where: { userId: string };
};
expect(call.where.userId).toBe("user-1");
expect(call.where).toEqual({
userId: "user-1",
asNeeded: false,
});
});
it("returns 429 when the per-user rate limit is exhausted", async () => {
@@ -80,6 +80,8 @@ export const GET = apiHandler(async () => {
);
return {
medicationId: medication.id,
applicable: payload.applicable,
notApplicableReason: payload.notApplicableReason,
compliance7: payload.compliance7,
compliance30: payload.compliance30,
complianceDisplay: payload.complianceDisplay,