diff --git a/src/lib/i18n/config.ts b/src/lib/i18n/config.ts index 8759dadb5..97c94bbc6 100644 --- a/src/lib/i18n/config.ts +++ b/src/lib/i18n/config.ts @@ -19,7 +19,7 @@ export const localeLabels: Record = { * know to expect rough edges and where to contribute fixes. Promoting * a locale here turns the banner off. */ -export const MAINTAINED_LOCALES: ReadonlySet = new Set(["de", "en"]); +const MAINTAINED_LOCALES: ReadonlySet = new Set(["de", "en"]); export function isMaintainedLocale(locale: Locale): boolean { return MAINTAINED_LOCALES.has(locale); diff --git a/src/lib/insights/chart-tokens.ts b/src/lib/insights/chart-tokens.ts index 21ed87897..00e14167e 100644 --- a/src/lib/insights/chart-tokens.ts +++ b/src/lib/insights/chart-tokens.ts @@ -205,10 +205,3 @@ export function tokenToMetric(token: ChartToken): string { return token.slice("metric:".length); } -/** Token kinds the renderer needs to distinguish. MeasurementType tokens - * feed ``; `metric:MOOD` mounts the dedicated, self-fetching - * `` instead. */ -export function tokenKind(token: ChartToken): "measurement" | "mood" { - if (token === "metric:MOOD") return "mood"; - return "measurement"; -} diff --git a/src/lib/insights/sub-page-metric.ts b/src/lib/insights/sub-page-metric.ts index 04af80070..feeb0268a 100644 --- a/src/lib/insights/sub-page-metric.ts +++ b/src/lib/insights/sub-page-metric.ts @@ -40,7 +40,7 @@ // `gewicht`, `bmi`, `schlaf`, `stimmung`, `medikamente`, `workouts`) // stay flat — they predate v1.4.32 and the maintainer's audit kept // them as direct entries. -export const SUB_PAGE_METRIC = { +const SUB_PAGE_METRIC = { // ── vitals ── blutdruck: ["BLOOD_PRESSURE_SYS", "BLOOD_PRESSURE_DIA", "PULSE"], puls: ["PULSE"], diff --git a/src/lib/logging/background.ts b/src/lib/logging/background.ts index 1e9deb55f..e8ce8f182 100644 --- a/src/lib/logging/background.ts +++ b/src/lib/logging/background.ts @@ -33,17 +33,3 @@ export async function withBackgroundEvent( }); } -/** - * Fire-and-forget Variante: schluckt Fehler und loggt sie nur. - * Fuer Webhook-Sends, Achievement-Checks, etc. - */ -export async function withBackgroundEventSafe( - taskName: string, - fn: (evt: WideEventBuilder) => Promise, -): Promise { - try { - await withBackgroundEvent(taskName, fn); - } catch { - // Fehler wurde bereits ins Event geschrieben und emittiert - } -} diff --git a/src/lib/logging/index.ts b/src/lib/logging/index.ts index 062a56601..88b6df6ba 100644 --- a/src/lib/logging/index.ts +++ b/src/lib/logging/index.ts @@ -10,7 +10,7 @@ export { WideEventBuilder } from "./event-builder"; export { eventStorage, getEvent, annotate } from "./context"; export { shouldEmit } from "./sampler"; export { emitEvent, emitIfSampled } from "./transports"; -export { withBackgroundEvent, withBackgroundEventSafe } from "./background"; +export { withBackgroundEvent } from "./background"; export { appendLogEvent, readLogBuffer, diff --git a/src/lib/measurements/import-apple-health-export.ts b/src/lib/measurements/import-apple-health-export.ts index 476b8a353..e56e622c8 100644 --- a/src/lib/measurements/import-apple-health-export.ts +++ b/src/lib/measurements/import-apple-health-export.ts @@ -148,7 +148,7 @@ interface MutableTypeStat { } /** Tick frequency for the live `ImportJob.progress` write. */ -export const PROGRESS_TICK_RECORDS = 1_000; +const PROGRESS_TICK_RECORDS = 1_000; const SPOT_FLUSH_BATCH = 500; const WORKOUT_FLUSH_BATCH = 100; diff --git a/src/lib/rollups/measurement-rollups.ts b/src/lib/rollups/measurement-rollups.ts index a6de1b45f..e8c95bc94 100644 --- a/src/lib/rollups/measurement-rollups.ts +++ b/src/lib/rollups/measurement-rollups.ts @@ -23,10 +23,9 @@ * * Reads: * - `readRollupBuckets` returns the persisted rows. The reader - * side (`analytics`, `comprehensive`, `summaries-slice`) calls - * `isRollupFresh` first to decide whether to fall through to the - * live aggregator + persist-on-miss. Cheap heuristic — one - * indexed query for the newest measurement's `measuredAt`. + * side (`analytics`, `comprehensive`, `summaries-slice`) decides + * whether to fall through to the live aggregator + persist-on-miss + * via its own per-tier freshness probe. */ import { prisma } from "@/lib/db"; import { getGlobalBoss } from "@/lib/jobs/boss-instance"; @@ -303,42 +302,6 @@ export async function readRollupBuckets( })); } -/** - * Cheap freshness heuristic — one indexed query against - * `measurements` for the newest row per (user, type). Returns true - * when the persisted rollup covers every measurement currently in - * the DB, false when there's a newer measurement than the freshest - * rollup row (the rollup needs a recompute). - * - * `null` newest measurement means the user has no rows of this type, - * in which case the rollups are trivially fresh (empty == empty). - */ -export async function isRollupFresh( - userId: string, - type: MeasurementType, - granularity: RollupGranularity, - newestComputedAt: Date | null, -): Promise { - const newest = await prisma.measurement.findFirst({ - where: { userId, type, deletedAt: null }, - orderBy: { measuredAt: "desc" }, - select: { measuredAt: true, updatedAt: true }, - }); - if (!newest) { - // No measurements at all — empty rollup set is fresh by definition. - return true; - } - if (!newestComputedAt) { - // We have measurements but no rollup rows — definitely stale. - return false; - } - // Stale when the latest row was written / updated after the most - // recent rollup `computed_at` for this `(user, type, granularity)`. - const watermark = - newest.updatedAt > newest.measuredAt ? newest.updatedAt : newest.measuredAt; - return watermark <= newestComputedAt; -} - // ─── internals ──────────────────────────────────────────── /**