mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
refactor(v1.4.16): apply simplify-review safe suggestions
7 of 8 apply-yes simplify findings landed:
F2 — `generateInsight()` confidenceContext config-bag dropped. No
production caller passed the resolver; the wrapper now derives inputs
from the parsed payload directly (n from metricSource.n, recencyDays
=0, deviationStdRatio=null). Two confidence-wrapper tests rewritten
to test the parsed-payload path. v1.4.17 will re-introduce a
resolver injection when the feedback ratchet ships a real second
caller.
F3 — `aiRecommendationRationaleSchema.referenceId` speculative
optional field removed. No consumer reads it; rec-level referenceId
is the canonical citation pointer.
F4 — `applyLastWorkingCache` doc-comment trimmed: dropped the
"NEW array" defensive note (no caller compares the input ref).
F5 — `<RecommendationFeedback>` re-uses the canonical
`RecommendationFeedbackRequest` types from the validation schema
instead of hand-maintaining the same enum vocabulary. Removes a
silent-drift risk if v1.4.17 adds another time-range value.
F6 — `formatRelativeTime` doc-comment trimmed: dropped the stale
`Intl.RelativeTimeFormat` polyfill claim (baseline-supported since
2018) — kept the genuine WHY (i18n consistency).
F7 — `<RecommendationCard>` 26-line slot-architecture header trimmed
to a 4-line WHY. The slots being narrated as "future" were filled by
B5d / B5e in the same file.
F9 — `pickProviderType` doc-comment trimmed: removed the
mis-anchored PROMPT_VERSION snapshot paragraph (the function only
picks providerType — promptVersion is read elsewhere).
F10 — `legacy-payload.ts` `UnknownRec` interface removed; cast
inlined as `(rec as { rationale?: unknown })`.
F12 — `<ConfidenceMeter>` 20-line band-policy header trimmed to a
3-line WHY. The bandFor() helper + colour-by-band record below are
the documentation now.
(F1 + F8 deferred — both flagged "no" in simplify review and need
Marc's call.)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
56614392be
commit
f3025a8dd5
10 files changed
+78
-175
No files matched your search
@@ -1,25 +1,9 @@
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
|
||||
/**
|
||||
* v1.4.16 phase B5d — `<ConfidenceMeter>`.
|
||||
*
|
||||
* Renders a deterministic 0..100 confidence score (server-computed by
|
||||
* `computeConfidence()` and overridden in `generateInsight()`) as
|
||||
* either a 5-bar meter (default) or an SVG ring.
|
||||
*
|
||||
* Color bands match research §2.A "three-band visual" extended to 4
|
||||
* bands so the under-50 region splits into "low" + "draft":
|
||||
*
|
||||
* - >=80: green ("high"), 5 bars / full ring
|
||||
* - 50..79: yellow ("medium"), 3-4 bars
|
||||
* - 25..49: orange ("low"), 2 bars / partial ring + caption
|
||||
* - <25: "draft" pill REPLACES the meter — Apple's
|
||||
* "quiet-when-unsure" affordance per research §2.A. The rec is
|
||||
* drafted but the model isn't asserting it.
|
||||
*
|
||||
* aria-label always announces the numeric score so a screen reader
|
||||
* isn't blind to the visual band distinction. Mobile-friendly: the
|
||||
* bars variant fits in 56 px wide; the ring variant in 28×28.
|
||||
* Renders a 0..100 confidence score as a 5-bar meter (default) or SVG
|
||||
* ring. Sub-25 replaces the meter with a "draft" pill ("quiet-when-
|
||||
* unsure"). aria-label always carries the numeric value.
|
||||
*/
|
||||
|
||||
export type ConfidenceBand = "high" | "medium" | "low" | "draft";
|
||||
|
||||
@@ -41,13 +41,8 @@ interface InsightsPageHeroProps {
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a relative time using the i18n translation keys. Avoids the
|
||||
* `Intl.RelativeTimeFormat` polyfill cost on the client AND keeps every
|
||||
* surface that renders relative times locked to the project's
|
||||
* established translation vocabulary.
|
||||
*
|
||||
* Buckets: <1min → just now; <60min → N min ago; <24h → N h ago;
|
||||
* else N days ago.
|
||||
* Bucketed relative-time using i18n translation keys so every surface
|
||||
* shares vocabulary. Buckets: <1m, <1h, <24h, else days.
|
||||
*/
|
||||
function formatRelativeTime(
|
||||
iso: string,
|
||||
|
||||
@@ -20,30 +20,10 @@ import {
|
||||
import { ConfidenceMeter } from "./confidence-meter";
|
||||
|
||||
/**
|
||||
* v1.4.16 phase B5c — Oura-style RecommendationCard.
|
||||
*
|
||||
* Each recommendation lives in its own collapsible card. The
|
||||
* collapsed row shows: severity badge + rec text + named slot for
|
||||
* the future confidence-ring (B5d) + chevron toggle.
|
||||
*
|
||||
* Expanding reveals:
|
||||
* - 3-row rationale card (Window / Compared to / Deviation)
|
||||
* - mini-chart pinned to the rationale's data window via
|
||||
* HealthChart's new `mini` + `windowOverride` props
|
||||
* - citation footnote (B5a) when `referenceId` resolves
|
||||
* - named slot for the future feedback-thumbs (B5e)
|
||||
*
|
||||
* Default state: collapsed. Chevron toggles `aria-expanded`. Plain-
|
||||
* string recs (legacy InsightResult shape) and recs without
|
||||
* `rationale` render as a non-expandable list item — there's nothing
|
||||
* to expand to. The legacy-payload CTA at the parent advisor card
|
||||
* level surfaces the regenerate prompt for those.
|
||||
*
|
||||
* Layout slots are deliberately named so B5d (confidence) and B5e
|
||||
* (feedback) can plug in without touching this file:
|
||||
*
|
||||
* - data-slot="rec-confidence-slot" → B5d ConfidenceRing
|
||||
* - data-slot="rec-feedback-slot" → B5e RecommendationFeedback
|
||||
* Collapsible recommendation card with severity badge, confidence
|
||||
* meter, and an expandable rationale block (window / compared-to /
|
||||
* deviation) + mini-chart. Plain-string and rationale-less recs
|
||||
* render as a non-expandable row.
|
||||
*/
|
||||
|
||||
const SEVERITY_BADGE_STYLES: Record<string, string> = {
|
||||
|
||||
@@ -31,18 +31,18 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { ThumbsUp, ThumbsDown, Loader2, Check } from "lucide-react";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import type { RecommendationFeedbackRequest } from "@/lib/validations/recommendation-feedback";
|
||||
|
||||
// v1.4.16 phase D reconcile (simplify F5) — re-export the canonical
|
||||
// types from the validation schema instead of hand-maintaining the
|
||||
// same enum vocabulary. Drift between the two used to be a real risk
|
||||
// (a future "last180days" added to the schema would silently break
|
||||
// the component without a compile error).
|
||||
export type RecommendationFeedbackSeverity =
|
||||
| "info"
|
||||
| "suggestion"
|
||||
| "important"
|
||||
| "urgent";
|
||||
RecommendationFeedbackRequest["recommendationSeverity"];
|
||||
|
||||
export type RecommendationFeedbackTimeRange =
|
||||
| "last7days"
|
||||
| "last30days"
|
||||
| "last90days"
|
||||
| "allTime";
|
||||
RecommendationFeedbackRequest["metricSourceTimeRange"];
|
||||
|
||||
export interface RecommendationFeedbackProps {
|
||||
recId: string;
|
||||
|
||||
Reference in new issue
Block a user