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:
Marc-André Bombeck committed 2026-05-15 17:48:20 +02:00
1 parent 39571c6e23
commit f72d2de27c
4 files changed
+40 -26

No files matched your search

-2
View File
@@ -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,
};
+14 -11
View File
@@ -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;
+11 -10
View File
@@ -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;
}
/**
+15 -3
View File
@@ -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;
}