mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
chore(knip): drop fourteen orphaned types + scope contracts ignore-block
Every `z.infer<>` source-of-truth type the residual flagged had no
external consumer:
- `MetricSource`, `AIRecommendation`, `AIRecommendationRationale`,
`AICitation`, `AIWarning`, `StoryboardAnnotation` in
`src/lib/ai/schema.ts`
- `InsightFinding` in `src/lib/ai/types.ts`
- `CoachChatRequest` in `src/lib/ai/coach/types.ts`
- `ApplyProfileInput` in `src/lib/auth/profile-update.ts`
- `CreateSideEffectInput`, `ListSideEffectsInput` in
`src/lib/medications/side-effects/validators.ts`
- `AnalyticsSlicePayload` in `src/lib/queries/use-analytics-query.ts`
- `WithingsWebhookAuthOutcome` in `src/lib/withings/webhook-handler.ts`
Plus three stragglers — `ThresholdOverride` (the persisted shape is the
sibling `ThresholdOverridesJson`), `ChartRangePreset` + the now-orphaned
`CHART_RANGE_PRESETS` constant it was derived from (no chart reads the
preset list), and the `WebPushChannelConfig` + `ApnsChannelConfig` +
`ChannelConfig` triplet in `src/lib/notifications/types.ts` (the
dispatcher imports the two real channel configs by name; the empty
records and the union added nothing).
`src/lib/validations/**` keeps its `z.infer<>` types — that's the
external API surface the iOS client matches against. Muted via
`ignoreIssues` so the gate can enforce while the contract surface
stays self-documenting.
This commit is contained in:
1 parent
c032dfb617
commit
0c48ecc39c
11 files changed
+2
-77
No files matched your search
@@ -72,6 +72,7 @@
|
||||
],
|
||||
"ignoreExportsUsedInFile": true,
|
||||
"ignoreIssues": {
|
||||
"src/components/ui/**": ["exports", "types"]
|
||||
"src/components/ui/**": ["exports", "types"],
|
||||
"src/lib/validations/**": ["types"]
|
||||
}
|
||||
}
|
||||
@@ -97,8 +97,6 @@ export const coachChatRequestSchema = z.object({
|
||||
scope: coachScopeSchema.optional(),
|
||||
});
|
||||
|
||||
export type CoachChatRequest = z.infer<typeof coachChatRequestSchema>;
|
||||
|
||||
/**
|
||||
* SSE event shapes emitted by the streaming endpoint.
|
||||
*
|
||||
|
||||
@@ -67,8 +67,6 @@ export const metricSourceSchema = z.object({
|
||||
n: z.number().int().nonnegative().optional(),
|
||||
});
|
||||
|
||||
export type MetricSource = z.infer<typeof metricSourceSchema>;
|
||||
|
||||
/**
|
||||
* Set of valid `referenceId` values, derived from
|
||||
* `MEDICAL_REFERENCES` so the two cannot drift. Validated lazily
|
||||
@@ -118,10 +116,6 @@ export const aiRecommendationRationaleSchema = z.object({
|
||||
deviation: z.string().min(1, "rationale.deviation required"),
|
||||
});
|
||||
|
||||
export type AIRecommendationRationale = z.infer<
|
||||
typeof aiRecommendationRationaleSchema
|
||||
>;
|
||||
|
||||
export const aiRecommendationSchema = z
|
||||
.object({
|
||||
/**
|
||||
@@ -191,8 +185,6 @@ export const aiRecommendationSchema = z
|
||||
}
|
||||
});
|
||||
|
||||
export type AIRecommendation = z.infer<typeof aiRecommendationSchema>;
|
||||
|
||||
export const aiCitationSchema = z.object({
|
||||
/** Snapshot key being cited. */
|
||||
type: z.string().min(1, "citation.type required"),
|
||||
@@ -202,8 +194,6 @@ export const aiCitationSchema = z.object({
|
||||
summary: z.string().min(1, "citation.summary required"),
|
||||
});
|
||||
|
||||
export type AICitation = z.infer<typeof aiCitationSchema>;
|
||||
|
||||
export const aiWarningSchema = z.object({
|
||||
/** Topic — "blood_pressure", "pulse", etc. */
|
||||
topic: z.string().min(1, "warning.topic required"),
|
||||
@@ -213,8 +203,6 @@ export const aiWarningSchema = z.object({
|
||||
severity: recommendationSeveritySchema.optional(),
|
||||
});
|
||||
|
||||
export type AIWarning = z.infer<typeof aiWarningSchema>;
|
||||
|
||||
/**
|
||||
* v1.4.20 phase B1 — Daily Briefing block.
|
||||
*
|
||||
@@ -419,8 +407,6 @@ export const storyboardAnnotationSchema = z.object({
|
||||
.max(400, "storyboardAnnotation.detail must be <= 400 chars"),
|
||||
});
|
||||
|
||||
export type StoryboardAnnotation = z.infer<typeof storyboardAnnotationSchema>;
|
||||
|
||||
export const storyboardAnnotationsSchema = z
|
||||
.array(storyboardAnnotationSchema)
|
||||
.max(20, "storyboardAnnotations can hold at most 20 entries");
|
||||
|
||||
@@ -99,7 +99,6 @@ export const insightResultSchema = z.object({
|
||||
});
|
||||
|
||||
export type InsightResult = z.infer<typeof insightResultSchema>;
|
||||
export type InsightFinding = z.infer<typeof insightFindingSchema>;
|
||||
|
||||
// ─── Provider Types ────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -42,13 +42,6 @@ export type ThresholdMetric =
|
||||
| "BONE_MASS"
|
||||
| "OXYGEN_SATURATION";
|
||||
|
||||
export interface ThresholdOverride {
|
||||
min: number;
|
||||
max: number;
|
||||
/** Set true when the value was entered by the user (not the computed default). */
|
||||
isOverride?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shape persisted in User.thresholdsJson. Any metric missing = use default.
|
||||
*/
|
||||
|
||||
@@ -21,8 +21,6 @@ const extendedProfileSchema = profileSchema.extend({
|
||||
moodReminderEnabled: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export type ApplyProfileInput = z.infer<typeof extendedProfileSchema>;
|
||||
|
||||
export interface ApplyProfileResult {
|
||||
ok: true;
|
||||
user: {
|
||||
|
||||
@@ -15,21 +15,3 @@
|
||||
|
||||
/** Full-size trend-card body height (non-mini chart cards on the dashboard). */
|
||||
export const CHART_HEIGHT_PX = 240;
|
||||
|
||||
/**
|
||||
* Range-preset options for charts that expose a 7d / 30d / 90d / All
|
||||
* range selector. Each entry carries the i18n keys for the visible
|
||||
* label + sr-only title, plus a `points` count used by the underlying
|
||||
* `HealthChart` query window. `points: 0` denotes "all data".
|
||||
*
|
||||
* Re-used by the GLP-1 dashboard tile so its range strip stays in
|
||||
* lockstep with the rest of the trend strip.
|
||||
*/
|
||||
export const CHART_RANGE_PRESETS = [
|
||||
{ labelKey: "charts.points7Label", titleKey: "charts.points7Title", points: 7 },
|
||||
{ labelKey: "charts.points30Label", titleKey: "charts.points30Title", points: 30 },
|
||||
{ labelKey: "charts.points90Label", titleKey: "charts.points90Title", points: 90 },
|
||||
{ labelKey: "charts.pointsAllLabel", titleKey: "charts.pointsAllTitle", points: 0 },
|
||||
] as const;
|
||||
|
||||
export type ChartRangePreset = (typeof CHART_RANGE_PRESETS)[number];
|
||||
@@ -73,5 +73,3 @@ export const listSideEffectsSchema = z.object({
|
||||
limit: z.coerce.number().int().min(1).max(200).optional().default(50),
|
||||
});
|
||||
|
||||
export type CreateSideEffectInput = z.infer<typeof createSideEffectSchema>;
|
||||
export type ListSideEffectsInput = z.infer<typeof listSideEffectsSchema>;
|
||||
@@ -71,22 +71,6 @@ export interface NtfyChannelConfig {
|
||||
authToken?: string;
|
||||
}
|
||||
|
||||
export type WebPushChannelConfig = Record<string, never>;
|
||||
|
||||
/**
|
||||
* APNs channel config is empty by design — the per-device APNs token +
|
||||
* environment live on the `Device` model, not on the channel row. The
|
||||
* channel row exists so per-event preference toggles in
|
||||
* `NotificationPreference` apply uniformly across all four channels.
|
||||
*/
|
||||
export type ApnsChannelConfig = Record<string, never>;
|
||||
|
||||
export type ChannelConfig =
|
||||
| TelegramChannelConfig
|
||||
| NtfyChannelConfig
|
||||
| WebPushChannelConfig
|
||||
| ApnsChannelConfig;
|
||||
|
||||
// ── Notification payload ──
|
||||
|
||||
export interface NotificationPayload {
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useQuery, type UseQueryResult } from "@tanstack/react-query";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { queryKeys } from "@/lib/query-keys";
|
||||
import type { DataSummary } from "@/lib/analytics/trends";
|
||||
import type { SubPageAnalyticsData } from "@/types/analytics";
|
||||
|
||||
/**
|
||||
* v1.4.33 IW2 — single TanStack-Query wrapper for `/api/analytics`.
|
||||
@@ -39,15 +38,6 @@ import type { SubPageAnalyticsData } from "@/types/analytics";
|
||||
* stubbed on the slim path per the IW1 follow-up.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Strict structural subset shared between the slim slice and the thick
|
||||
* default payload. Consumers that only read `summaries` should type
|
||||
* the hook return as `AnalyticsSlicePayload` (or import
|
||||
* `SubPageAnalyticsData` directly — same shape, kept aliased for
|
||||
* call-site clarity).
|
||||
*/
|
||||
export type AnalyticsSlicePayload = SubPageAnalyticsData;
|
||||
|
||||
/**
|
||||
* Discriminator for the server-side slice. `undefined` (the default)
|
||||
* routes onto the thick payload; `"summaries"` routes onto IW1's
|
||||
|
||||
@@ -43,10 +43,6 @@ const WITHINGS_SLEEP_APPLI = 44;
|
||||
const WITHINGS_ACTIVITY_QUEUE = "withings-activity-sync";
|
||||
const WITHINGS_SLEEP_QUEUE = "withings-sleep-sync";
|
||||
|
||||
export type WithingsWebhookAuthOutcome =
|
||||
| { ok: true }
|
||||
| { ok: false; reason: "missing_secret" | "mismatch" | "not_configured" };
|
||||
|
||||
/**
|
||||
* Constant-time comparison helper. Returns false unless both inputs have
|
||||
* the same byte length AND match exactly.
|
||||
|
||||
Reference in new issue
Block a user