mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
fix(export): cap the FHIR MedicationAdministration count per export
The administration set was windowed only to the report period (up to 730 days). A chronic medication dosed several times a day across that window, multiplied across several medications, can still materialise thousands of MedicationAdministration resources into a single Bundle — bounded by the window but unbounded by dose frequency. Cap the set at the most-recent 1000 acted intakes overall. The omitted rows are the oldest in the window, so recent adherence is preserved intact. When the cap trims rows the aggregator records the original and included counts and the FHIR document narrative discloses the truncation, so the export is honest about the omitted history rather than silently dropping it. Cover the cap in the report aggregator and the narrative note in the bundle builder. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> (cherry picked from commit c6ce7df2bf6efb5e2c9d948d8f189d95d1289758)
This commit is contained in:
1 parent
f0f2caab79
commit
ada9006d9c
4 files changed
+151
-1
No files matched your search
@@ -239,3 +239,59 @@ describe("doctor-report — per-section toggles", () => {
|
||||
expect(Object.keys(data.compliance).length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("doctor-report — MedicationAdministration export cap", () => {
|
||||
it("caps the administration set at 1000 most-recent rows and flags the truncation", async () => {
|
||||
const prisma = getPrismaClient();
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
username: "dr-admin-cap",
|
||||
email: "dr-admin-cap@example.test",
|
||||
heightCm: 180,
|
||||
},
|
||||
});
|
||||
const med = await prisma.medication.create({
|
||||
data: { userId: user.id, name: "Metformin", dose: "500 mg", active: true },
|
||||
});
|
||||
|
||||
// 1001 acted (taken) intakes spread across the window so the cap
|
||||
// must trim exactly one — the OLDEST — keeping the most-recent 1000.
|
||||
const rangeMs = RANGE.end.getTime() - RANGE.start.getTime();
|
||||
const rows = Array.from({ length: 1001 }, (_, i) => {
|
||||
const at = new Date(
|
||||
RANGE.start.getTime() + Math.floor((rangeMs * i) / 1001),
|
||||
);
|
||||
return {
|
||||
userId: user.id,
|
||||
medicationId: med.id,
|
||||
scheduledFor: at,
|
||||
takenAt: at,
|
||||
};
|
||||
});
|
||||
await prisma.medicationIntakeEvent.createMany({ data: rows });
|
||||
|
||||
const data = await collectDoctorReportData(user.id, RANGE);
|
||||
|
||||
expect(data.medicationAdministrations).toBeDefined();
|
||||
expect(data.medicationAdministrations?.length).toBe(1000);
|
||||
expect(data.medicationAdministrationsTruncation).toEqual({
|
||||
total: 1001,
|
||||
included: 1000,
|
||||
});
|
||||
// The OLDEST row was dropped — the earliest surviving administration
|
||||
// is strictly after the window start.
|
||||
const first = data.medicationAdministrations?.[0];
|
||||
expect(new Date(first!.effectiveAt).getTime()).toBeGreaterThan(
|
||||
RANGE.start.getTime(),
|
||||
);
|
||||
});
|
||||
|
||||
it("leaves the set untouched (no truncation flag) below the cap", async () => {
|
||||
const userId = await seedUserWithEveryDataType("dr-admin-no-cap");
|
||||
|
||||
const data = await collectDoctorReportData(userId, RANGE);
|
||||
|
||||
expect(data.medicationAdministrations?.length).toBe(1);
|
||||
expect(data.medicationAdministrationsTruncation ?? null).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user