mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
refactor(insights): classify the derived BMI through classifyBMI
The derived BMI card kept its own copy of the WHO cut-offs beside `classifyBMI`, which the targets panel, the status text and the overview use. It now maps that one classifier onto its four-word vocabulary, so a later change to the cut-offs has one place to land.
This commit is contained in:
1 parent
4fa5e6381e
commit
46b1cd6f34
2 files changed
+32
-5
No files matched your search
@@ -27,6 +27,12 @@ describe("classifyBmi (WHO)", () => {
|
||||
it("obese ≥ 30 (red)", () => {
|
||||
expect(classifyBmi(31)).toEqual({ category: "obese", band: "red" });
|
||||
});
|
||||
it("puts each WHO cut-off in the upper category, every obesity grade obese", () => {
|
||||
expect(classifyBmi(18.5).category).toBe("normal");
|
||||
expect(classifyBmi(25).category).toBe("overweight");
|
||||
expect(classifyBmi(30).category).toBe("obese");
|
||||
expect(classifyBmi(45)).toEqual({ category: "obese", band: "red" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("computeBmi", () => {
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
*/
|
||||
import type { MeasurementType } from "@/generated/prisma/client";
|
||||
import { prisma } from "@/lib/db";
|
||||
import {
|
||||
classifyBMI,
|
||||
type BmiClassification,
|
||||
} from "@/lib/analytics/classifications";
|
||||
import {
|
||||
buildInsufficient,
|
||||
buildOk,
|
||||
@@ -63,15 +67,32 @@ export interface BmiValue {
|
||||
series: number[];
|
||||
}
|
||||
|
||||
/** WHO category + band for a BMI value. Pure. */
|
||||
const CATEGORY_OF: Readonly<Record<string, BmiCategory>> = {
|
||||
Underweight: "underweight",
|
||||
Normal: "normal",
|
||||
Overweight: "overweight",
|
||||
};
|
||||
|
||||
const BAND_OF: Readonly<Record<BmiClassification["severity"], BmiBand>> = {
|
||||
normal: "green",
|
||||
warning: "yellow",
|
||||
danger: "red",
|
||||
};
|
||||
|
||||
/**
|
||||
* WHO category + band for a BMI value, in this payload's vocabulary. The
|
||||
* cut-offs are `classifyBMI`'s, so the derived card and the targets panel
|
||||
* cannot disagree about where a reading falls. Pure.
|
||||
*/
|
||||
export function classifyBmi(bmi: number): {
|
||||
category: BmiCategory;
|
||||
band: BmiBand;
|
||||
} {
|
||||
if (bmi < 18.5) return { category: "underweight", band: "yellow" };
|
||||
if (bmi < 25) return { category: "normal", band: "green" };
|
||||
if (bmi < 30) return { category: "overweight", band: "yellow" };
|
||||
return { category: "obese", band: "red" };
|
||||
const { category, severity } = classifyBMI(bmi);
|
||||
return {
|
||||
category: CATEGORY_OF[category] ?? "obese",
|
||||
band: BAND_OF[severity],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user