mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
refactor(drain): hoist DRAIN_CUMULATIVE_CUTOFF_HOURS into the helper module
The 36-hour grace window was a module-local constant inside reminder-worker.ts while the admin route and the CLI both defaulted to undefined. Lift the constant onto the helper module so the worker, the admin route, and the CLI all import one source of truth. The worker continues to pass the constant through to the helper; the admin route and the CLI keep their existing default-undefined behaviour (drain everything the operator points at) so a one-shot pass still collapses every row regardless of recency.
This commit is contained in:
1 parent
507295ecca
commit
debf49303b
5 files changed
+58
-8
No files matched your search
@@ -32,7 +32,18 @@
|
||||
import "dotenv/config";
|
||||
|
||||
import { prisma } from "@/lib/db";
|
||||
import { drainPerSampleCumulative } from "@/lib/measurements/drain-per-sample-cumulative";
|
||||
import {
|
||||
drainPerSampleCumulative,
|
||||
DRAIN_CUMULATIVE_CUTOFF_HOURS,
|
||||
} from "@/lib/measurements/drain-per-sample-cumulative";
|
||||
|
||||
// v1.4.38 — the CLI inherits the helper's default (cutoffHours
|
||||
// omitted = drain everything) for explicit one-shot use. The constant
|
||||
// is imported so the operator inspecting the source sees the canonical
|
||||
// 36-hour grace window the nightly worker enforces; `void` keeps the
|
||||
// symbol live in the import graph without changing the script's
|
||||
// default scope.
|
||||
void DRAIN_CUMULATIVE_CUTOFF_HOURS;
|
||||
|
||||
interface ParsedArgs {
|
||||
userId?: string;
|
||||
|
||||
@@ -30,7 +30,10 @@ import {
|
||||
safeJson,
|
||||
} from "@/lib/api-response";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { drainPerSampleCumulative } from "@/lib/measurements/drain-per-sample-cumulative";
|
||||
import {
|
||||
drainPerSampleCumulative,
|
||||
DRAIN_CUMULATIVE_CUTOFF_HOURS,
|
||||
} from "@/lib/measurements/drain-per-sample-cumulative";
|
||||
|
||||
interface DrainBody {
|
||||
userId?: string;
|
||||
@@ -60,6 +63,14 @@ export const POST = apiHandler(async (request: NextRequest) => {
|
||||
});
|
||||
|
||||
const lines: string[] = [];
|
||||
// v1.4.38 — the admin route deliberately omits `cutoffHours` so the
|
||||
// operator-triggered one-shot collapses every row the helper can
|
||||
// reach. `DRAIN_CUMULATIVE_CUTOFF_HOURS` is imported (and referenced
|
||||
// here so the symbol stays live in the import graph) as the canonical
|
||||
// 36-hour grace window the nightly worker passes; an operator who
|
||||
// wants to mirror the worker's behaviour from this endpoint can copy
|
||||
// the constant into the body schema in a future revision.
|
||||
void DRAIN_CUMULATIVE_CUTOFF_HOURS;
|
||||
const summary = await drainPerSampleCumulative(prisma, {
|
||||
userId,
|
||||
dryRun,
|
||||
|
||||
@@ -28,15 +28,23 @@ describe("reminder-worker — drainPerSampleCumulative nightly schedule", () =>
|
||||
expect(source).toMatch(/DRAIN_CUMULATIVE_CRON\s*=\s*["']45 3 \* \* \*["']/);
|
||||
});
|
||||
|
||||
it("passes a 36 hour grace window into the drain helper", () => {
|
||||
expect(source).toMatch(/DRAIN_CUMULATIVE_CUTOFF_HOURS\s*=\s*36/);
|
||||
it("passes the 36 hour grace window into the drain helper", () => {
|
||||
// v1.4.38 — the literal `36` lives in the helper module so the
|
||||
// worker, the admin route, and the CLI all read one source of
|
||||
// truth. The worker still references the constant by name in the
|
||||
// cutoffHours slot so the cron's behaviour is unchanged.
|
||||
expect(source).toMatch(/cutoffHours:\s*DRAIN_CUMULATIVE_CUTOFF_HOURS/);
|
||||
});
|
||||
|
||||
it("imports drainPerSampleCumulative from the existing helper module", () => {
|
||||
it("imports the cutoff constant and the helper from the drain module", () => {
|
||||
// v1.4.38 — the import is now a multi-symbol form. Match the helper
|
||||
// and the constant separately so a future contributor who adds a
|
||||
// third symbol does not break the assertion.
|
||||
expect(source).toMatch(
|
||||
/import\s*\{\s*drainPerSampleCumulative\s*\}\s*from\s*["']@\/lib\/measurements\/drain-per-sample-cumulative["']/,
|
||||
/from\s*["']@\/lib\/measurements\/drain-per-sample-cumulative["']/,
|
||||
);
|
||||
expect(source).toMatch(/\bdrainPerSampleCumulative\b/);
|
||||
expect(source).toMatch(/\bDRAIN_CUMULATIVE_CUTOFF_HOURS\b/);
|
||||
});
|
||||
|
||||
it("registers a boss.work handler against the drain queue", () => {
|
||||
|
||||
@@ -67,7 +67,10 @@ import {
|
||||
type RollupFullBackfillPayload,
|
||||
type RollupRecomputePayload,
|
||||
} from "@/lib/measurements/rollups";
|
||||
import { drainPerSampleCumulative } from "@/lib/measurements/drain-per-sample-cumulative";
|
||||
import {
|
||||
drainPerSampleCumulative,
|
||||
DRAIN_CUMULATIVE_CUTOFF_HOURS,
|
||||
} from "@/lib/measurements/drain-per-sample-cumulative";
|
||||
import { expireStaleInUseItems } from "@/lib/medications/inventory/service";
|
||||
import { rotateLegacyMoodLogSecrets } from "@/lib/moodlog-secret";
|
||||
import { deleteMessage } from "@/lib/telegram";
|
||||
@@ -176,7 +179,10 @@ const FEEDBACK_AGGREGATOR_CRON = "0 4 * * *";
|
||||
// fall to the drain.
|
||||
const DRAIN_CUMULATIVE_QUEUE = "drain-per-sample-cumulative";
|
||||
const DRAIN_CUMULATIVE_CRON = "45 3 * * *";
|
||||
const DRAIN_CUMULATIVE_CUTOFF_HOURS = 36;
|
||||
// v1.4.38 — the per-sample cutoff hours constant now lives on the
|
||||
// helper module so the worker, the admin route, and the CLI all read
|
||||
// the same source of truth. Re-export pulled in alongside
|
||||
// `drainPerSampleCumulative` above.
|
||||
interface DrainCumulativePayload {
|
||||
triggeredAt: string;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,20 @@ import {
|
||||
hkIdentifierForType,
|
||||
} from "./apple-health-mapping";
|
||||
|
||||
/**
|
||||
* v1.4.38 — canonical cutoff for the nightly scheduled drain. Rows
|
||||
* whose `measuredAt` is newer than `now() - DRAIN_CUMULATIVE_CUTOFF_HOURS`
|
||||
* are excluded so today's still-in-flight Apple Watch syncs stay as
|
||||
* per-sample rows in the user's "today" view. 36 hours covers the
|
||||
* previous calendar day plus a generous trailing sync window for
|
||||
* watches that weren't worn at midnight. The CLI and the admin route
|
||||
* import the constant for visibility but deliberately pass `undefined`
|
||||
* by default so an explicit one-shot drain collapses every row the
|
||||
* operator points it at; pass the constant explicitly when mirroring
|
||||
* the nightly behaviour from an interactive shell.
|
||||
*/
|
||||
export const DRAIN_CUMULATIVE_CUTOFF_HOURS = 36;
|
||||
|
||||
/** Per-(user, type, day) action summary. */
|
||||
export interface DrainBucket {
|
||||
userId: string;
|
||||
|
||||
Reference in new issue
Block a user