mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 22:02:16 +00:00
chore(release): v1.4.39.3 — dashboard slim/thick merge robustness and list-page precision
The post-deploy CI for v1.4.39.2 surfaced eight e2e failures across chromium-desktop and chromium-mobile (chart-overlay-controls, dashboard, charts-mobile, measurement-flow) that all routed through two narrow regressions and one durable test-fixture gap. ### Fixed - Dashboard slim/thick merge no longer blanks the tile strip when the slim slice resolves with an empty summaries record. The v1.4.39.2 inline `slim?.summaries ?? thick?.summaries` short-circuited on JavaScript's truthy-empty-object even when thick carried the full payload. The merge moved to a pure `mergeSlimAndThickAnalytics` helper that uses object emptiness as the discriminator: populated slim still wins on overlapping fields (progressive-paint contract preserved), empty slim falls through to thick, both empty leaves the dashboard's data-floor gates to render the appropriate empty state. Eight new behaviour-level unit tests cover the edge cases. - `MeasurementList` non-grouped rows now preserve decimal precision on both the desktop table and the mobile card grid. The v1.4.37 W7c collapsed-list view passed every value through `fmt.integer`, which kept the per-day step / activity aggregates correct but silently truncated single weight / body-fat / temperature readings — 78.4 kg rendered as "78 kg". Grouped rows (cumulative HK type day aggregates) stay on `fmt.integer` because their readings are integer-only; non-grouped rows now use `fmt.number` which honours up to three fraction digits without forcing a minimum. ### Changed - Playwright route mocks for `/api/analytics` migrate from the literal `**/api/analytics` string glob to the regex form `/\/api\/analytics(\?|$)/` across every authenticated spec. The string glob does not match the sliced URL form `/api/analytics?slice=summaries` the v1.4.39.2 dashboard split fires alongside the thick request, so the slim request fell through to the real route on the seeded test user that returns empty summaries. Ten specs migrate: dashboard, chart-overlay-controls, measurement-flow, charts-mobile, a11y, v1427-responsive-sheet, v1427-coach-launch, v1427-measurements-add-param, v1427-insights-empty-state, onboarding-tour-passthrough. The regex form is the durable alignment with the v1.4.37 W-CI lesson that already swept `onboarding-flicker.spec.ts` and `mobile-viewport.spec.ts`. ### Notes - No schema migration. Runtime + test-fixture-only changes. - `pnpm test --run` green at 4662 / 4663 (1 long-standing skip). - Full Playwright suite green at 116 passing / 36 skipped / 152 total on both `chromium-desktop` and `chromium-mobile` profiles, against the production Next.js build. Closes every failure from CI run 26213226723.
This commit is contained in:
1 parent
d665a5db42
commit
dbb5979a97
16 files changed
+426
-34
No files matched your search
+24
-21
@@ -66,6 +66,7 @@ import { useTranslations, useFormatters } from "@/lib/i18n/context";
|
||||
import { queryKeys } from "@/lib/query-keys";
|
||||
import { useAnalyticsQuery } from "@/lib/queries/use-analytics-query";
|
||||
import type { DataSummary } from "@/lib/analytics/trends";
|
||||
import { mergeSlimAndThickAnalytics } from "@/lib/analytics/merge-slim-thick";
|
||||
import { getBpTargets } from "@/lib/analytics/bp-targets";
|
||||
import {
|
||||
buildTrafficLightBands,
|
||||
@@ -245,28 +246,30 @@ export default function DashboardPage() {
|
||||
const analyticsSlimQuery = useAnalyticsQuery({ slice: "summaries" });
|
||||
const analyticsThickQuery = useAnalyticsQuery();
|
||||
const data = useMemo<AnalyticsData | undefined>(() => {
|
||||
const slim = analyticsSlimQuery.data;
|
||||
const thick = analyticsThickQuery.data;
|
||||
if (!slim && !thick) return undefined;
|
||||
// Slim wins on overlapping fields when both have resolved — slim
|
||||
// and thick compute `summaries` / `lastSeenByType` from the same
|
||||
// SQL helpers so the values agree, and reading from whichever
|
||||
// resolves first keeps the tile strip painting as soon as either
|
||||
// query lands.
|
||||
const summaries =
|
||||
slim?.summaries ?? thick?.summaries ?? ({} as Record<string, DataSummary>);
|
||||
const lastSeenByType =
|
||||
slim?.lastSeenByType ?? thick?.lastSeenByType;
|
||||
// v1.4.39.3 — the merge moved to `mergeSlimAndThickAnalytics` so
|
||||
// the empty-slim-vs-populated-thick edge has direct unit
|
||||
// coverage. Pre-fix the inline `slim?.summaries ?? thick?.summaries`
|
||||
// short-circuited on a truthy-but-empty `{}` from the slim slice
|
||||
// and blanked the tile strip even when thick carried the full
|
||||
// payload — the regression Marc's v1.4.39.3 e2e CI flagged across
|
||||
// eight dashboard / chart specs. The helper falls back to thick
|
||||
// when slim resolves with no content and otherwise keeps the
|
||||
// v1.4.39.2 slim-wins-first progressive-paint contract.
|
||||
const merged = mergeSlimAndThickAnalytics(
|
||||
analyticsSlimQuery.data,
|
||||
analyticsThickQuery.data,
|
||||
);
|
||||
if (!merged) return undefined;
|
||||
return {
|
||||
summaries,
|
||||
lastSeenByType,
|
||||
bpInTargetPct: (thick?.bpInTargetPct ?? null) as number | null,
|
||||
bpInTargetPct7d: thick?.bpInTargetPct7d ?? null,
|
||||
bpInTargetPct30d: thick?.bpInTargetPct30d ?? null,
|
||||
bpInTargetPctAllTime: thick?.bpInTargetPctAllTime ?? null,
|
||||
bpInTargetPctPriorMonth: thick?.bpInTargetPctPriorMonth ?? null,
|
||||
bpInTargetPctPriorYear: thick?.bpInTargetPctPriorYear ?? null,
|
||||
glucoseByContext: thick?.glucoseByContext as
|
||||
summaries: merged.summaries,
|
||||
lastSeenByType: merged.lastSeenByType,
|
||||
bpInTargetPct: merged.bpInTargetPct,
|
||||
bpInTargetPct7d: merged.bpInTargetPct7d,
|
||||
bpInTargetPct30d: merged.bpInTargetPct30d,
|
||||
bpInTargetPctAllTime: merged.bpInTargetPctAllTime,
|
||||
bpInTargetPctPriorMonth: merged.bpInTargetPctPriorMonth,
|
||||
bpInTargetPctPriorYear: merged.bpInTargetPctPriorYear,
|
||||
glucoseByContext: merged.glucoseByContext as
|
||||
| Record<string, DataSummaryType>
|
||||
| undefined,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user