From 70ff3eef734fac4d6cbae692ee19f93115fdb956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 21 May 2026 17:50:04 +0200 Subject: [PATCH] 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. --- src/components/charts/trend-card.tsx | 2 +- .../insights/personal-record-badge.tsx | 12 +++++------- src/lib/ai/codex-oauth.ts | 14 -------------- src/lib/ai/feedback-attribution.ts | 2 +- src/lib/dashboard-layout.ts | 4 ++-- src/lib/feedback/publish-github.ts | 2 +- src/lib/format-locale.ts | 2 +- src/lib/format.ts | 4 +--- src/lib/medication-category.ts | 2 +- .../medications/side-effects/validators.ts | 2 +- src/lib/medications/window-status.ts | 2 +- src/lib/openapi/registry.ts | 2 +- src/lib/rollups/mood-rollups.ts | 2 +- src/lib/telegram.ts | 19 ------------------- 14 files changed, 17 insertions(+), 54 deletions(-) diff --git a/src/components/charts/trend-card.tsx b/src/components/charts/trend-card.tsx index 7118d6bff..1679c828b 100644 --- a/src/components/charts/trend-card.tsx +++ b/src/components/charts/trend-card.tsx @@ -64,7 +64,7 @@ export type TrendDirectionSentiment = "up-good" | "up-bad" | "neutral"; */ export type TrendSentimentDirection = "positive" | "negative" | "neutral"; -export function getTrendSentiment( +function getTrendSentiment( change: number | null | undefined, sentiment: TrendDirectionSentiment, ): TrendSentimentDirection { diff --git a/src/components/insights/personal-record-badge.tsx b/src/components/insights/personal-record-badge.tsx index 0e7b5842f..14e6ecd1b 100644 --- a/src/components/insights/personal-record-badge.tsx +++ b/src/components/insights/personal-record-badge.tsx @@ -52,14 +52,12 @@ interface PersonalRecordBadgeProps { const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000; /** - * Pure freshness check — exported for unit testing so the component - * itself stays free of clock calls (the React purity linter rejects - * `Date.now()` inside a component body or hook initializer). Callers - * pass a `now` reference; consumers in production read it from the - * surrounding query refetch boundary where one stale-time tick = - * one new clock reading. + * Pure freshness check kept out of the component body so the React + * purity linter doesn't trip on the `Date.now()` reference; callers + * pass `now` from the surrounding query refetch boundary where one + * stale-time tick = one new clock reading. */ -export function isPRWithin30Days(achievedAtIso: string, now: number): boolean { +function isPRWithin30Days(achievedAtIso: string, now: number): boolean { const ts = new Date(achievedAtIso).getTime(); return Number.isFinite(ts) && now - ts <= THIRTY_DAYS_MS; } diff --git a/src/lib/ai/codex-oauth.ts b/src/lib/ai/codex-oauth.ts index fc6628c5f..33eb67473 100644 --- a/src/lib/ai/codex-oauth.ts +++ b/src/lib/ai/codex-oauth.ts @@ -53,20 +53,6 @@ export function generateState(): string { return base64url(randomBytes(32)); } -/** - * Backwards-compatible no-op type. Older callers that imported the error - * type continue to compile. Codex OAuth always considers itself - * configured because we ship the public client ID as the default. - */ -export class CodexOAuthNotConfiguredError extends Error { - constructor() { - super( - "Codex OAuth is not configured on this instance — set CODEX_OAUTH_CLIENT_ID", - ); - this.name = "CodexOAuthNotConfiguredError"; - } -} - export function getCodexClientId(): string { return process.env.CODEX_OAUTH_CLIENT_ID?.trim() || DEFAULT_CLIENT_ID; } diff --git a/src/lib/ai/feedback-attribution.ts b/src/lib/ai/feedback-attribution.ts index 7e6792a5f..7802984d3 100644 --- a/src/lib/ai/feedback-attribution.ts +++ b/src/lib/ai/feedback-attribution.ts @@ -106,7 +106,7 @@ export interface CoachFeedbackAttribution extends FeedbackAttribution { metricSourceType: string; } -export function buildCoachMetricSourceType( +function buildCoachMetricSourceType( tone: string, verbosity: string, ): string { diff --git a/src/lib/dashboard-layout.ts b/src/lib/dashboard-layout.ts index efa564769..d53df38f8 100644 --- a/src/lib/dashboard-layout.ts +++ b/src/lib/dashboard-layout.ts @@ -91,7 +91,7 @@ export interface DashboardWidgetConfig { export const COMPARISON_BASELINES = ["none", "lastMonth", "lastYear"] as const; export type ComparisonBaseline = (typeof COMPARISON_BASELINES)[number]; -export function isComparisonBaseline( +function isComparisonBaseline( value: unknown, ): value is ComparisonBaseline { return ( @@ -196,7 +196,7 @@ export interface DashboardLayout { chartOverlayPrefs?: ChartOverlayPrefsMap; } -export const DASHBOARD_LAYOUT_VERSION = 1; +const DASHBOARD_LAYOUT_VERSION = 1; /** * Default layout mirrors v1.1 behavior: core vitals always on, mood + diff --git a/src/lib/feedback/publish-github.ts b/src/lib/feedback/publish-github.ts index 20eafcff5..d31d56e9d 100644 --- a/src/lib/feedback/publish-github.ts +++ b/src/lib/feedback/publish-github.ts @@ -37,7 +37,7 @@ export class GithubPublishError extends Error { * Resolves the configured GitHub token + repo from AppSettings (or env). * Returns null if no configuration is present (caller should treat as 503). */ -export async function getGithubConfig(): Promise<{ +async function getGithubConfig(): Promise<{ token: string; repo: string; } | null> { diff --git a/src/lib/format-locale.ts b/src/lib/format-locale.ts index 6b52d86a1..6de1643df 100644 --- a/src/lib/format-locale.ts +++ b/src/lib/format-locale.ts @@ -29,7 +29,7 @@ export const DISPLAY_TIMEZONE = "Europe/Berlin"; * `Intl.*`. When we add locales, extend this map — do not rely on the short * tag directly since browsers differ in how they handle "en" vs "en-US". */ -export const INTL_LOCALE_MAP: Record = { +const INTL_LOCALE_MAP: Record = { de: "de-DE", en: "en-US", fr: "fr-FR", diff --git a/src/lib/format.ts b/src/lib/format.ts index 85e72959f..b32a85f3b 100644 --- a/src/lib/format.ts +++ b/src/lib/format.ts @@ -15,11 +15,9 @@ * stay consistent with the server-rendered locale. */ -import { makeFormatters, DISPLAY_TIMEZONE } from "./format-locale"; +import { makeFormatters } from "./format-locale"; import type { Locale } from "./i18n/config"; -export { DISPLAY_TIMEZONE }; - function activeLocale(): Locale { if (typeof document === "undefined") return "en"; // Prefer the cookie (what SSR used) over localStorage to stay in sync diff --git a/src/lib/medication-category.ts b/src/lib/medication-category.ts index 5c1b8cc07..c36476bf8 100644 --- a/src/lib/medication-category.ts +++ b/src/lib/medication-category.ts @@ -1,7 +1,7 @@ import { prisma } from "@/lib/db"; import { MEDICATION_CATEGORY_VALUES } from "@/lib/validations/medication"; -export const MEDICATION_CATEGORIES = MEDICATION_CATEGORY_VALUES; +const MEDICATION_CATEGORIES = MEDICATION_CATEGORY_VALUES; export type MedicationCategory = (typeof MEDICATION_CATEGORIES)[number]; diff --git a/src/lib/medications/side-effects/validators.ts b/src/lib/medications/side-effects/validators.ts index b7188440f..279ce0393 100644 --- a/src/lib/medications/side-effects/validators.ts +++ b/src/lib/medications/side-effects/validators.ts @@ -40,7 +40,7 @@ export const SIDE_EFFECT_ENTRY_VALUES = Object.values( MedicationSideEffectEntry, ) as readonly MedicationSideEffectEntry[]; -export const SIDE_EFFECT_NOTES_MAX = 280; +const SIDE_EFFECT_NOTES_MAX = 280; /** * v1.4.25 W21 Fix-N (code-M6) — `category` was dropped from the wire diff --git a/src/lib/medications/window-status.ts b/src/lib/medications/window-status.ts index d36753b98..c7c1d1139 100644 --- a/src/lib/medications/window-status.ts +++ b/src/lib/medications/window-status.ts @@ -124,7 +124,7 @@ function isLastIntakeInCurrentWindow( * to suppress "overdue" pills once the user has already covered every * passed schedule with intake events for the day. */ -export function countPassedSchedules( +function countPassedSchedules( schedules: Schedule[], nowBerlin: Date, ): number { diff --git a/src/lib/openapi/registry.ts b/src/lib/openapi/registry.ts index cd24470f7..6343ce618 100644 --- a/src/lib/openapi/registry.ts +++ b/src/lib/openapi/registry.ts @@ -26,7 +26,7 @@ import { createDocument, type ZodOpenApiObject } from "zod-openapi"; import { openApiPaths, openApiComponents } from "./routes"; -export const openApiBase: Pick< +const openApiBase: Pick< ZodOpenApiObject, "openapi" | "info" | "servers" | "tags" > = { diff --git a/src/lib/rollups/mood-rollups.ts b/src/lib/rollups/mood-rollups.ts index 3100340e9..e525e7f10 100644 --- a/src/lib/rollups/mood-rollups.ts +++ b/src/lib/rollups/mood-rollups.ts @@ -51,7 +51,7 @@ import type { const ASYNC_GRANULARITIES: RollupGranularity[] = ["WEEK", "MONTH", "YEAR"]; /** All granularities the rollup table tracks. */ -export const ALL_MOOD_GRANULARITIES: RollupGranularity[] = [ +const ALL_MOOD_GRANULARITIES: RollupGranularity[] = [ "DAY", "WEEK", "MONTH", diff --git a/src/lib/telegram.ts b/src/lib/telegram.ts index 3e9401777..156661410 100644 --- a/src/lib/telegram.ts +++ b/src/lib/telegram.ts @@ -115,25 +115,6 @@ export async function answerTelegramCallbackQuery( return json.ok; } -export async function editMessageReplyMarkup( - botToken: string, - chatId: string, - messageId: number, - replyMarkup?: TelegramReplyMarkup, -): Promise { - const json = await telegramApiRequest(botToken, "editMessageReplyMarkup", { - chat_id: chatId, - message_id: messageId, - reply_markup: replyMarkup ?? { inline_keyboard: [] }, - }); - if (!json.ok) { - getEvent()?.addWarning( - `[telegram] editMessageReplyMarkup failed: ${json.description}`, - ); - } - return json.ok; -} - export async function setTelegramWebhook( botToken: string, webhookUrl: string,