mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 14:40:52 +00:00
fix(nutrients): recompute supplement rows when the module returns or the zone moves
This commit is contained in:
1 parent
37645fc4bb
commit
cc9d523bc8
7 files changed
+96
No files matched your search
@@ -44,6 +44,7 @@ import {
|
||||
} from "@/lib/optimistic-lock";
|
||||
import { resolveModuleMap, normalisePrefs } from "@/lib/modules/gate";
|
||||
import { modulePrefsPatchSchema } from "@/lib/validations/modules";
|
||||
import { recomputeSupplementsIfNutrientsTurnedOn } from "@/lib/medications/ingredients/recompute-job";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -140,6 +141,12 @@ export const PATCH = apiHandler(async (req: Request) => {
|
||||
});
|
||||
if ("conflict" in guarded) return guarded.conflict;
|
||||
|
||||
await recomputeSupplementsIfNutrientsTurnedOn(
|
||||
user.id,
|
||||
existing?.modulePreferencesJson,
|
||||
merged,
|
||||
);
|
||||
|
||||
// A module toggle can add or remove a Health Score pillar, so the
|
||||
// cached composite was computed from a composition that no longer
|
||||
// holds. Without this the score stays stale for up to an hour after a
|
||||
|
||||
@@ -31,6 +31,12 @@ vi.mock("@/lib/rollups/medication-compliance-rollups", () => ({
|
||||
enqueueUserMedicationComplianceBackfill: refoldMock,
|
||||
}));
|
||||
|
||||
// The supplement nutrient rows are keyed by the same local day.
|
||||
const nutrientMock = vi.hoisted(() => vi.fn(async () => ({ queued: true })));
|
||||
vi.mock("@/lib/medications/ingredients/recompute-job", () => ({
|
||||
enqueueSupplementNutrientRecompute: nutrientMock,
|
||||
}));
|
||||
|
||||
vi.mock("next/headers", () => ({
|
||||
headers: vi.fn(async () => ({ get: () => null })),
|
||||
cookies: vi.fn(async () => ({
|
||||
@@ -118,6 +124,7 @@ describe("PUT /api/auth/me/timezone", () => {
|
||||
const res = await PUT(mkReq({ timezone: "America/New_York" }));
|
||||
expect(res.status).toBe(200);
|
||||
expect(refoldMock).toHaveBeenCalledWith("user-1");
|
||||
expect(nutrientMock).toHaveBeenCalledWith("user-1");
|
||||
});
|
||||
|
||||
it("does not re-fold when the zone is unchanged", async () => {
|
||||
@@ -130,6 +137,7 @@ describe("PUT /api/auth/me/timezone", () => {
|
||||
const res = await PUT(mkReq({ timezone: "Europe/Berlin" }));
|
||||
expect(res.status).toBe(200);
|
||||
expect(refoldMock).not.toHaveBeenCalled();
|
||||
expect(nutrientMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("trims whitespace before validating", async () => {
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { auditLog } from "@/lib/auth/audit";
|
||||
import { invalidateUserTimezone, isValidTimezone } from "@/lib/tz/resolver";
|
||||
import { enqueueSupplementNutrientRecompute } from "@/lib/medications/ingredients/recompute-job";
|
||||
import { enqueueUserMedicationComplianceBackfill } from "@/lib/rollups/medication-compliance-rollups";
|
||||
|
||||
export const PUT = apiHandler(async (request: NextRequest) => {
|
||||
@@ -69,6 +70,8 @@ export const PUT = apiHandler(async (request: NextRequest) => {
|
||||
// job; best-effort, the singleton key collapses rapid re-picks.
|
||||
if ((before?.timezone ?? null) !== tz) {
|
||||
const refold = await enqueueUserMedicationComplianceBackfill(user.id);
|
||||
// The supplement nutrient rows are keyed by the same local day.
|
||||
await enqueueSupplementNutrientRecompute(user.id);
|
||||
annotate({
|
||||
meta: {
|
||||
timezone_compliance_refold_enqueued: refold.enqueued,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
import { enqueueSupplementNutrientRecompute } from "@/lib/medications/ingredients/recompute-job";
|
||||
import {
|
||||
apiHandler,
|
||||
requireGuardianAuth,
|
||||
@@ -239,6 +240,8 @@ export const PATCH = apiHandler(
|
||||
}
|
||||
if (patch.timezone !== undefined) {
|
||||
invalidateUserMedications(access.recordId, { evict: true });
|
||||
// The supplement nutrient rows are keyed by the local day.
|
||||
await enqueueSupplementNutrientRecompute(access.recordId);
|
||||
}
|
||||
settings = {
|
||||
...record,
|
||||
|
||||
Reference in new issue
Block a user