mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 06:40:50 +00:00
fix(hrv): keep RMSSD on the display surfaces for an account with no SDNN
Fitbit and Google Health HRV is filed as RMSSD since migration 0420, so an account whose only HRV comes from them lost it wherever a display surface read SDNN alone. The dashboard HRV tile keeps its RMSSD fallback with Recovery off while the account has no SDNN, and its toggle stays offered for either estimator. A briefing HRV signal counts as measured today when either series has a reading. The doctor report already files RMSSD as its own ungated leaf; a guard now holds that. Readiness, HRV balance and stress stay on SDNN; a test pins that an RMSSD-only account renormalises over the other components.
This commit is contained in:
1 parent
8d16799479
commit
bf3830203f
18 files changed
+232
-66
No files matched your search
@@ -235,7 +235,7 @@ export const GET = apiHandler(async () => {
|
||||
// linger for minutes after Recovery went off, which is the confusion this
|
||||
// is removing.
|
||||
//
|
||||
// The SDNN probe is an index-only existence check
|
||||
// The HRV probes are index-only existence checks
|
||||
// (`@@index([userId, type, measuredAt])`), not a summaries read; it runs
|
||||
// only when Recovery is off, so the common account pays nothing.
|
||||
// One flag, read the way this codebase reads one flag — not the whole
|
||||
@@ -243,20 +243,22 @@ export const GET = apiHandler(async () => {
|
||||
// is the only module that decides it.
|
||||
const recoveryEnabled = await isModuleEnabled(user.id, "recovery");
|
||||
let hasSdnn = true;
|
||||
let hasRmssd = true;
|
||||
if (!recoveryEnabled) {
|
||||
const sdnnRow = await prisma.measurement.findFirst({
|
||||
where: {
|
||||
userId: user.id,
|
||||
type: "HEART_RATE_VARIABILITY",
|
||||
deletedAt: null,
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
const [sdnnRow, rmssdRow] = await Promise.all(
|
||||
(["HEART_RATE_VARIABILITY", "HRV_RMSSD"] as const).map((type) =>
|
||||
prisma.measurement.findFirst({
|
||||
where: { userId: user.id, type, deletedAt: null },
|
||||
select: { id: true },
|
||||
}),
|
||||
),
|
||||
);
|
||||
hasSdnn = sdnnRow !== null;
|
||||
hasRmssd = rmssdRow !== null;
|
||||
}
|
||||
const unavailable = unavailableWidgetIds(
|
||||
{ recovery: recoveryEnabled },
|
||||
{ hasSdnn },
|
||||
{ hasSdnn, hasRmssd },
|
||||
);
|
||||
return apiSuccess(
|
||||
unavailable.length > 0
|
||||
|
||||
Reference in new issue
Block a user