mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
Turn the health score green at 70
The app carries three scores and meant two things by a green dot. Readiness and the sleep score both call 70 green; the health score alone wanted 75. One app cannot do that, so the outlier moved. The yellow floor stays at 50: raising the bar for a reward and lowering the bar for a warning are different decisions, and only the first one was on the table. The band is still not a function of the number. The composite takes the worse of the mean's band and the worst counted pillar's, so a composite carrying a red pillar stays red however high the mean sits - the stored band on a recorded day exists for exactly that reason. Only the mean-side thresholds moved. The method version moves with it. A day already recorded keeps the band it was actually shown under, and the notice key carries the version, so each account is told once that the rules moved. The week-over-week comparison is left alone on purpose: the number itself does not change, only the colour it is drawn in, so a subtraction across the change still compares two numbers worked out the same way.
This commit is contained in:
1 parent
4e934a191d
commit
9bcd5dfaf5
9 files changed
+182
-24
No files matched your search
@@ -9,6 +9,7 @@ import type {
|
||||
HealthScoreReport,
|
||||
ScorePillarResult,
|
||||
} from "@/lib/analytics/score/types";
|
||||
import { SCORE_VERSION } from "@/lib/analytics/score/types";
|
||||
import { HeroStrip } from "../hero-strip";
|
||||
|
||||
/**
|
||||
@@ -148,7 +149,7 @@ function reportWith(pillars: ScorePillarResult[]): HealthScoreReport {
|
||||
composition: pillars.map((p) => p.id),
|
||||
configured: false,
|
||||
noiseFloor: 3,
|
||||
scoreVersion: 2,
|
||||
scoreVersion: SCORE_VERSION,
|
||||
},
|
||||
coverage,
|
||||
confidence: { score: 100, band: "high" },
|
||||
@@ -157,7 +158,7 @@ function reportWith(pillars: ScorePillarResult[]): HealthScoreReport {
|
||||
pillars,
|
||||
delta: 2,
|
||||
deltaReason: null,
|
||||
scoreVersion: 2,
|
||||
scoreVersion: SCORE_VERSION,
|
||||
weightGoal: {
|
||||
status: "insufficient",
|
||||
coverage: {
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
HealthScoreReport,
|
||||
ScorePillarResult,
|
||||
} from "@/lib/analytics/score/types";
|
||||
import { SCORE_VERSION } from "@/lib/analytics/score/types";
|
||||
import {
|
||||
HealthScoreCard,
|
||||
HealthScoreCardSkeleton,
|
||||
@@ -211,7 +212,7 @@ function report(overrides: Partial<HealthScoreReport> = {}): HealthScoreReport {
|
||||
pillars: [BLOOD_PRESSURE, ACTIVITY_BELOW_FLOOR],
|
||||
delta: null,
|
||||
deltaReason: "no_current_score",
|
||||
scoreVersion: 2,
|
||||
scoreVersion: SCORE_VERSION,
|
||||
weightGoal: {
|
||||
status: "insufficient",
|
||||
coverage: {
|
||||
@@ -241,7 +242,7 @@ function scoredReport(
|
||||
composition: ["BLOOD_PRESSURE", "ACTIVITY", "SLEEP"],
|
||||
configured: false,
|
||||
noiseFloor: 3,
|
||||
scoreVersion: 2,
|
||||
scoreVersion: SCORE_VERSION,
|
||||
},
|
||||
coverage: {
|
||||
requiredInputs: 3,
|
||||
@@ -371,7 +372,7 @@ describe("<HealthScoreCard> pillars", () => {
|
||||
composition: ["BLOOD_PRESSURE", "GLYCAEMIA"],
|
||||
configured: false,
|
||||
noiseFloor: 3,
|
||||
scoreVersion: 2,
|
||||
scoreVersion: SCORE_VERSION,
|
||||
},
|
||||
coverage: {
|
||||
requiredInputs: 3,
|
||||
@@ -600,7 +601,7 @@ describe("<HealthScoreCard> composite states", () => {
|
||||
expect(html).not.toContain('data-slot="health-score-card-progress"');
|
||||
expect(html).toContain("—");
|
||||
expect(html).not.toContain("/ 100");
|
||||
expect(html).toContain("Method version 2");
|
||||
expect(html).toContain(`Method version ${SCORE_VERSION}`);
|
||||
});
|
||||
|
||||
it("explains a missing comparison where the trend would be", () => {
|
||||
@@ -665,7 +666,9 @@ describe("<HealthScoreCard> footer", () => {
|
||||
const region = anatomyRegion(html);
|
||||
expect(region).toContain('data-slot="health-score-method"');
|
||||
expect(region).toContain("Overall band set by none");
|
||||
expect(region).toContain("Method version 2. Weekly comparison floor");
|
||||
expect(region).toContain(
|
||||
`Method version ${SCORE_VERSION}. Weekly comparison floor`,
|
||||
);
|
||||
expect(region).toContain('data-slot="provenance-explainer-method"');
|
||||
expect(region).toContain("equal-weighted average");
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {
|
||||
ScorePillarId,
|
||||
ScorePillarResult,
|
||||
} from "@/lib/analytics/score/types";
|
||||
import { SCORE_VERSION } from "@/lib/analytics/score/types";
|
||||
|
||||
// The "generated" freshness line reads the profile timezone via `useAuth`; stub
|
||||
// it so the SSR render does not reach for a QueryClient the test omits.
|
||||
@@ -116,7 +117,7 @@ function scoreReport(pillars: ScorePillarResult[]): HealthScoreReport {
|
||||
composition: ["BLOOD_PRESSURE"],
|
||||
configured: false,
|
||||
noiseFloor: 3,
|
||||
scoreVersion: 2,
|
||||
scoreVersion: SCORE_VERSION,
|
||||
},
|
||||
coverage: {
|
||||
requiredInputs: 3,
|
||||
@@ -130,7 +131,7 @@ function scoreReport(pillars: ScorePillarResult[]): HealthScoreReport {
|
||||
pillars,
|
||||
delta: 2,
|
||||
deltaReason: null,
|
||||
scoreVersion: 2,
|
||||
scoreVersion: SCORE_VERSION,
|
||||
weightGoal: {
|
||||
status: "insufficient",
|
||||
coverage: {
|
||||
|
||||
Reference in new issue
Block a user