mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
fix(ketones): offer ketone logging in the catalog and as a checkup
Ketones joined in v1.47.2 without their two sibling lists. The metric catalog treated them as connectable and sent a user without readings to the integrations page, where nothing delivers ketones; they now count as manual-only and the row offers "Log ketones". And a checkup could not be tied to ketones, so a "measure ketones" reminder never resolved on its own; ketones are now a reminder target next to blood glucose, with a label in all ten locales. A catalog test also holds every metric that cannot be connected to a way to log it.
This commit is contained in:
1 parent
3edb63d759
commit
2a68b39a85
16 files changed
+56
-5
No files matched your search
@@ -28,6 +28,7 @@ const LOCALES = readdirSync(MESSAGES_DIR)
|
||||
const REQUIRED_KEYS = [
|
||||
// Newly added Vorsorge reminder type labels.
|
||||
"measurementReminders.types.WAIST_CIRCUMFERENCE",
|
||||
"measurementReminders.types.BLOOD_KETONES",
|
||||
"measurementReminders.types.WHO5_SCORE",
|
||||
"measurementReminders.types.SCI_SCORE",
|
||||
// Pre-existing screening labels (regression floor).
|
||||
|
||||
@@ -16,6 +16,7 @@ export const TYPE_GROUPS = [
|
||||
"BLOOD_PRESSURE_SYS",
|
||||
"PULSE",
|
||||
"BLOOD_GLUCOSE",
|
||||
"BLOOD_KETONES",
|
||||
"OXYGEN_SATURATION",
|
||||
"BODY_TEMPERATURE",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { METRIC_CATALOG_ENTRIES } from "../metric-catalog";
|
||||
|
||||
/**
|
||||
* The metric catalog offers "Connect a source" for a metric without readings
|
||||
* and the metric's own entry action for one only a person can log. Ketones
|
||||
* shipped without joining the manual list, so their row sent people to the
|
||||
* integrations page, where nothing delivers ketones.
|
||||
*/
|
||||
describe("metric catalog", () => {
|
||||
it("offers ketones as a manual entry, not a source to connect", () => {
|
||||
const ketones = METRIC_CATALOG_ENTRIES.find((e) => e.id === "ketones");
|
||||
expect(ketones).toBeDefined();
|
||||
expect(ketones?.connectable).toBe(false);
|
||||
expect(ketones?.manualHref).toBe("/measurements?add=BLOOD_KETONES");
|
||||
expect(ketones?.manualCtaKey).toBe("insights.bloodKetones.emptyState.cta");
|
||||
});
|
||||
|
||||
it("gives every metric that cannot be connected a way to log it", () => {
|
||||
const manualOnly = METRIC_CATALOG_ENTRIES.filter(
|
||||
(e) => e.kind === "metric" && !e.connectable,
|
||||
);
|
||||
expect(manualOnly.length).toBeGreaterThan(0);
|
||||
for (const entry of manualOnly) {
|
||||
expect(entry.manualHref, entry.id).toBeTruthy();
|
||||
expect(entry.manualCtaKey, entry.id).toBeTruthy();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -109,12 +109,13 @@ const SOURCE_KEY_OVERRIDES: Partial<Record<SubPageSlug, string>> = {
|
||||
/**
|
||||
* Metrics with no device path at all — manual entry is the only source.
|
||||
* Mood and medications are inherently self-report (no sensor produces a
|
||||
* mood score or an adherence event). Pain, grip strength, and waist-to-
|
||||
* height ratio are ALSO manual-only despite sitting beside device-fed
|
||||
* siblings in their group: none carries an Apple Health mapping
|
||||
* mood score or an adherence event). Pain, grip strength, waist-to-height
|
||||
* ratio and blood ketones are ALSO manual-only despite sitting beside
|
||||
* device-fed siblings in their group: none carries an Apple Health mapping
|
||||
* (`apple-health-mapping.ts`) or a Withings/wearable source — pain is a
|
||||
* 0–10 self-rating, grip strength is read off a hand dynamometer, and
|
||||
* waist-to-height is logged directly (not derived like BMI). Cross-
|
||||
* 0–10 self-rating, grip strength is read off a hand dynamometer,
|
||||
* waist-to-height is logged directly (not derived like BMI), and ketones
|
||||
* come off a fingerstick meter that no integration reads. Cross-
|
||||
* checked against every routed sub-page's `emptyStateCtaType` +
|
||||
* `emptyState.description` copy so this list can't silently drift from
|
||||
* what the metric's own empty state actually offers.
|
||||
@@ -125,6 +126,7 @@ const MANUAL_ONLY_SLUGS: ReadonlySet<SubPageSlug> = new Set([
|
||||
"pain",
|
||||
"grip-strength",
|
||||
"waist-to-height",
|
||||
"ketones",
|
||||
]);
|
||||
|
||||
const MANUAL_CTA: Partial<
|
||||
@@ -147,6 +149,10 @@ const MANUAL_CTA: Partial<
|
||||
href: "/measurements?add=WAIST_TO_HEIGHT",
|
||||
ctaKey: "insights.waistToHeight.emptyState.cta",
|
||||
},
|
||||
ketones: {
|
||||
href: "/measurements?add=BLOOD_KETONES",
|
||||
ctaKey: "insights.bloodKetones.emptyState.cta",
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,7 @@ describe("measurementReminderTypeEnum (V3 — completeness)", () => {
|
||||
"BLOOD_PRESSURE_SYS",
|
||||
"PULSE",
|
||||
"BLOOD_GLUCOSE",
|
||||
"BLOOD_KETONES",
|
||||
"OXYGEN_SATURATION",
|
||||
"BODY_TEMPERATURE",
|
||||
// Body composition
|
||||
|
||||
@@ -45,6 +45,8 @@ export const measurementReminderTypeEnum = z
|
||||
"BLOOD_PRESSURE_SYS",
|
||||
"PULSE",
|
||||
"BLOOD_GLUCOSE",
|
||||
// Ketones come off the same fingerstick meter as glucose.
|
||||
"BLOOD_KETONES",
|
||||
"OXYGEN_SATURATION",
|
||||
"BODY_TEMPERATURE",
|
||||
// Body composition (one scale reading produces the whole family)
|
||||
|
||||
Reference in new issue
Block a user