Files
HealthLog/src/lib/medication-category.ts
T
Marc-André Bombeck 70ff3eef73 chore(cleanup): trim 13 dead exports surfaced by knip
Narrow each helper's visibility to its actual reach instead of leaving
it exported "just in case":

  - Drop the `export` keyword on file-local helpers / constants:
    `getTrendSentiment`, `isPRWithin30Days`, `buildCoachMetricSourceType`,
    `countPassedSchedules`, `getGithubConfig`, `isComparisonBaseline`,
    `DASHBOARD_LAYOUT_VERSION`, `INTL_LOCALE_MAP`, `SIDE_EFFECT_NOTES_MAX`,
    `MEDICATION_CATEGORIES`, `openApiBase`, `ALL_MOOD_GRANULARITIES`.
  - Remove never-used dead code:
    `CodexOAuthNotConfiguredError` (declared as a backwards-compat shim
    no caller ever consumed), `editMessageReplyMarkup` (Telegram method
    nothing on the bot dispatch tree calls), and the stale
    `DISPLAY_TIMEZONE` re-export from `src/lib/format.ts`.

Knip drops from 48 -> 35 unused exports. Pure narrowing / deletion;
no behaviour change.
2026-05-21 17:52:01 +02:00

98 lines
2.7 KiB
TypeScript

import { prisma } from "@/lib/db";
import { MEDICATION_CATEGORY_VALUES } from "@/lib/validations/medication";
const MEDICATION_CATEGORIES = MEDICATION_CATEGORY_VALUES;
export type MedicationCategory = (typeof MEDICATION_CATEGORIES)[number];
const DEFAULT_CATEGORY: MedicationCategory = "OTHER";
let ensureTablePromise: Promise<void> | null = null;
function normalizeCategory(input: unknown): MedicationCategory {
if (typeof input !== "string") return DEFAULT_CATEGORY;
return MEDICATION_CATEGORIES.includes(input as MedicationCategory)
? (input as MedicationCategory)
: DEFAULT_CATEGORY;
}
async function ensureMedicationCategoryTable() {
if (!ensureTablePromise) {
ensureTablePromise = (async () => {
await prisma.$executeRawUnsafe(`
CREATE TABLE IF NOT EXISTS medication_categories (
medication_id TEXT PRIMARY KEY REFERENCES medications(id) ON DELETE CASCADE,
category TEXT NOT NULL DEFAULT 'OTHER',
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
`);
await prisma.$executeRawUnsafe(`
CREATE INDEX IF NOT EXISTS medication_categories_category_idx
ON medication_categories(category);
`);
})().catch((err) => {
ensureTablePromise = null;
throw err;
});
}
await ensureTablePromise;
}
export async function getMedicationCategories(
medicationIds: string[],
): Promise<Record<string, MedicationCategory>> {
if (medicationIds.length === 0) return {};
await ensureMedicationCategoryTable();
const rows = await prisma.$queryRawUnsafe<
Array<{ medication_id: string; category: string }>
>(
`
SELECT medication_id, category
FROM medication_categories
WHERE medication_id = ANY($1::text[])
`,
medicationIds,
);
const map: Record<string, MedicationCategory> = {};
for (const id of medicationIds) {
map[id] = DEFAULT_CATEGORY;
}
for (const row of rows) {
map[row.medication_id] = normalizeCategory(row.category);
}
return map;
}
export async function setMedicationCategory(
medicationId: string,
category: unknown,
) {
await ensureMedicationCategoryTable();
const normalized = normalizeCategory(category);
await prisma.$executeRawUnsafe(
`
INSERT INTO medication_categories (medication_id, category, updated_at)
VALUES ($1, $2, NOW())
ON CONFLICT (medication_id)
DO UPDATE SET category = EXCLUDED.category, updated_at = NOW()
`,
medicationId,
normalized,
);
return normalized;
}
export async function deleteMedicationCategory(medicationId: string) {
await ensureMedicationCategoryTable();
await prisma.$executeRawUnsafe(
`DELETE FROM medication_categories WHERE medication_id = $1`,
medicationId,
);
}