mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
chore(cleanup): retire dead exports across glp1 modules and scheduling helpers
Sweeps the leftover export surface across four modules surfaced by
the v1.4.26 backlog dead-M5 / dead-M7 / simp-M6 / simp-M7 / BL-P4-5
items:
* src/lib/medications/glp1-knowledge.ts — eight constituent type
exports (`Glp1Route`, `Glp1DrugClass`, `Glp1Pharmacology`,
`Glp1Storage`, `Glp1Pen`, `Glp1AdverseReactions`, `Glp1Indications`,
`Glp1SourceCitations`) drop the `export` keyword. All eight are
used only as constituents of the still-exported `Glp1DrugRecord`
aggregate and have no external import sites; narrowing the module
surface stops a future tree-shaker from re-pulling them.
* src/lib/medications/scheduling/cadence.ts — `ExpectedDose` drops
its `export` keyword (no external readers).
* src/lib/medications/scheduling/cadence.ts — `pairDoses` drops the
redundant second `.sort()`. Sorting by `windowStart` and by the
centre `(start+end)/2` produce the same order for the chronologically
separable windows pairDoses actually sees, so the O(n log n) tail
that re-sorted the result was wasted work.
* src/lib/medications/titration/ladder.ts — `escalationDue`'s
JSDoc gets the parameter-role documentation simp-M7 called out.
The `drugId` parameter renames to `drugIdForCeiling` so the
"next-step exists" lookup role is obvious at the call site.
* src/lib/ai/coach/glp1-snapshot.ts — `__testables.WEEKDAY_KEYS`
and the underlying private constant retire (zero callers).
This commit is contained in:
1 parent
39571c6e23
commit
f72d2de27c
4 files changed
+40
-26
No files matched your search
@@ -70,7 +70,6 @@ function deriveDrugNames(raw: string): { display: string; generic: string } {
|
||||
return { display, generic };
|
||||
}
|
||||
|
||||
const WEEKDAY_KEYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] as const;
|
||||
|
||||
function parseDaysOfWeek(raw: string | null): number[] {
|
||||
if (!raw) return [];
|
||||
@@ -417,5 +416,4 @@ export const __testables = {
|
||||
parseTagList,
|
||||
parseDaysOfWeek,
|
||||
predictNextInjection,
|
||||
WEEKDAY_KEYS,
|
||||
};
|
||||
@@ -45,16 +45,16 @@ export type Glp1DrugId =
|
||||
* record AND a per-brand override map so a single drug-id can carry
|
||||
* mixed routes (semaglutide → Ozempic/Wegovy sc, Rybelsus oral).
|
||||
*/
|
||||
export type Glp1Route = "subcutaneous" | "oral";
|
||||
type Glp1Route = "subcutaneous" | "oral";
|
||||
|
||||
/**
|
||||
* Drug class descriptor — Tirzepatide is the only dual GIP/GLP-1
|
||||
* agonist among EMA-approved agents (2026-05); the rest are pure
|
||||
* GLP-1 receptor agonists.
|
||||
*/
|
||||
export type Glp1DrugClass = "GIP-GLP1 dual agonist" | "GLP-1 receptor agonist";
|
||||
type Glp1DrugClass = "GIP-GLP1 dual agonist" | "GLP-1 receptor agonist";
|
||||
|
||||
export type Glp1Pharmacology = {
|
||||
type Glp1Pharmacology = {
|
||||
/** Terminal elimination half-life. Days for the long-acting agents,
|
||||
* hours for liraglutide / short-acting exenatide. */
|
||||
halfLifeDays: number;
|
||||
@@ -83,7 +83,7 @@ export type Glp1Pharmacology = {
|
||||
compartmentModel: "one-compartment" | "two-compartment";
|
||||
};
|
||||
|
||||
export type Glp1Storage = {
|
||||
type Glp1Storage = {
|
||||
/** Refrigerated stability — every GLP-1 product is shipped 2–8 °C
|
||||
* per EMA. */
|
||||
unopened: {
|
||||
@@ -97,7 +97,7 @@ export type Glp1Storage = {
|
||||
};
|
||||
};
|
||||
|
||||
export type Glp1Pen = {
|
||||
type Glp1Pen = {
|
||||
/** Pen device name as printed on the carton. */
|
||||
type: string;
|
||||
/** Doses per pen / per cartridge — drives W19b inventory
|
||||
@@ -105,7 +105,7 @@ export type Glp1Pen = {
|
||||
dosesPerPen: number | null;
|
||||
};
|
||||
|
||||
export type Glp1AdverseReactions = {
|
||||
type Glp1AdverseReactions = {
|
||||
/** ≥ 1/10 frequency per EMA §4.8. */
|
||||
veryCommon: readonly string[];
|
||||
/** 1/100 to <1/10 per EMA §4.8. */
|
||||
@@ -116,12 +116,12 @@ export type Glp1AdverseReactions = {
|
||||
rare: readonly string[];
|
||||
};
|
||||
|
||||
export type Glp1Indications = {
|
||||
type Glp1Indications = {
|
||||
t2dm: { firstLine: boolean };
|
||||
weightManagement: { bmiThreshold: number | null };
|
||||
};
|
||||
|
||||
export type Glp1SourceCitations = {
|
||||
type Glp1SourceCitations = {
|
||||
/** Direct link to the EMA EPAR product-information PDF. */
|
||||
sourceEMA: string;
|
||||
/** Peer-reviewed pharmacometric citation where one exists. */
|
||||
@@ -548,7 +548,8 @@ export const GLP1_DRUGS: Readonly<Record<Glp1DrugId, Glp1DrugRecord>> = {
|
||||
|
||||
/**
|
||||
* Resolve the route for a given drug + brand. Falls back to the
|
||||
* record default when no per-brand override is registered.
|
||||
* record default when no per-brand override is registered. Read by
|
||||
* the glp1-knowledge test suite.
|
||||
*/
|
||||
export function routeForBrand(
|
||||
drugId: Glp1DrugId,
|
||||
@@ -597,8 +598,9 @@ export function findDrugIdByBrand(brand: string): Glp1DrugId | null {
|
||||
}
|
||||
|
||||
/**
|
||||
* The catalog's drug-ids in stable order. Useful for iteration in
|
||||
* tests and UI surfaces that need a deterministic display order.
|
||||
* The catalog's drug-ids in stable order. Read by the GLP-1 PK +
|
||||
* ladder test suites so a future drug addition flows through the
|
||||
* verification matrix without a hand-rolled list.
|
||||
*/
|
||||
export const GLP1_DRUG_IDS: readonly Glp1DrugId[] = [
|
||||
"tirzepatide",
|
||||
@@ -607,3 +609,4 @@ export const GLP1_DRUG_IDS: readonly Glp1DrugId[] = [
|
||||
"dulaglutide",
|
||||
"exenatide",
|
||||
] as const;
|
||||
|
||||
@@ -45,7 +45,7 @@ export interface IntakeEventLike {
|
||||
}
|
||||
|
||||
/** One slot the schedule expected the user to dose. */
|
||||
export interface ExpectedDose {
|
||||
interface ExpectedDose {
|
||||
/** Midnight of the local day this dose was expected. */
|
||||
day: Date;
|
||||
/** Start of the dose window for this day (Date with HH:mm applied). */
|
||||
@@ -308,16 +308,18 @@ export function pairDoses(
|
||||
now: Date,
|
||||
): PairedDose[] {
|
||||
const claimed = new Set<number>();
|
||||
const result: PairedDose[] = [];
|
||||
|
||||
// Sort slots by window centre so the earlier slot picks its match
|
||||
// first; same shape as the reminder-worker's "process schedules in
|
||||
// window order" loop.
|
||||
// v1.4.27 B7 / simp-M6 — sort once by `windowStart` for the match
|
||||
// pass and return the result in the same order. Slots that touch
|
||||
// pairDoses are always strictly chronologically separable (the
|
||||
// window radius is far smaller than the day grid step), so sorting
|
||||
// by `windowStart` and sorting by the centre `(start+end)/2`
|
||||
// produce the same order. Dropping the second `.sort()` at the
|
||||
// end keeps the contract intact and removes the O(n log n) tail.
|
||||
const sorted = [...slots].sort(
|
||||
(a, b) =>
|
||||
(a.windowStart.getTime() + a.windowEnd.getTime()) / 2 -
|
||||
(b.windowStart.getTime() + b.windowEnd.getTime()) / 2,
|
||||
(a, b) => a.windowStart.getTime() - b.windowStart.getTime(),
|
||||
);
|
||||
const result: PairedDose[] = [];
|
||||
|
||||
for (const slot of sorted) {
|
||||
const centre = (slot.windowStart.getTime() + slot.windowEnd.getTime()) / 2;
|
||||
@@ -352,8 +354,7 @@ export function pairDoses(
|
||||
result.push({ ...slot, match, status });
|
||||
}
|
||||
|
||||
// Restore the chronological order callers expect.
|
||||
return result.sort((a, b) => a.windowStart.getTime() - b.windowStart.getTime());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -183,7 +183,19 @@ export function weeksOnCurrentStep(
|
||||
|
||||
/**
|
||||
* Display flag — true when the EMA-reference minimum dwell time has
|
||||
* elapsed AND a next step exists.
|
||||
* elapsed AND a next ladder step exists.
|
||||
*
|
||||
* Parameters:
|
||||
* - `drugIdForCeiling`: identifies which ladder to walk so the
|
||||
* "next step exists" guard knows when the user has hit the
|
||||
* ceiling. The dwell-time check itself reads `typicalWeeks`
|
||||
* straight off `currentStep`; the drug id is only needed to
|
||||
* answer "is there a step above this one?".
|
||||
* - `currentStep`: the step the user is sitting on today. Null
|
||||
* when titration is paused or the user is at the bottom of the
|
||||
* ladder with no recorded dose history.
|
||||
* - `weeksOnStep`: how many complete weeks have elapsed since the
|
||||
* user landed on `currentStep`. Computed by `weeksOnCurrentStep`.
|
||||
*
|
||||
* IMPORTANT: this is a *reference* signal, not advice. The UI copy
|
||||
* tied to this boolean is strictly observational ("ladder typically
|
||||
@@ -191,11 +203,11 @@ export function weeksOnCurrentStep(
|
||||
* the W19c safety ground-rules.
|
||||
*/
|
||||
export function escalationDue(
|
||||
drugId: Glp1DrugId,
|
||||
drugIdForCeiling: Glp1DrugId,
|
||||
currentStep: TitrationStep | null,
|
||||
weeksOnStep: number,
|
||||
): boolean {
|
||||
if (!currentStep) return false;
|
||||
if (!nextStep(drugId, currentStep)) return false;
|
||||
if (!nextStep(drugIdForCeiling, currentStep)) return false;
|
||||
return weeksOnStep >= currentStep.typicalWeeks;
|
||||
}
|
||||
Reference in new issue
Block a user