diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.01-anonymous.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.01-anonymous.json.snap new file mode 100644 index 000000000..b1fdd5326 --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.01-anonymous.json.snap @@ -0,0 +1,24 @@ +{ + "status": 401, + "body": { + "data": null, + "error": "Not authenticated", + "meta": { + "errorCode": "auth.missing", + "requestId": "" + } + }, + "events": [ + { + "status": 401, + "action": null, + "meta": null, + "warnings": null, + "error": { + "type": "HttpError", + "message": "Not authenticated" + } + } + ], + "effects": [] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.02-cold.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.02-cold.json.snap new file mode 100644 index 000000000..44932c375 --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.02-cold.json.snap @@ -0,0 +1,1303 @@ +{ + "status": 200, + "body": { + "data": { + "summaries": { + "WEIGHT": { + "count": 58, + "latest": 82, + "min": 82, + "max": 84.4, + "mean": 83.19, + "median": null, + "avg7": 82.11, + "avg30": 82.59, + "slope7": { + "slope": -0.039, + "direction": "down", + "confidence": 0.89 + }, + "slope30": { + "slope": -0.04, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 83.8, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_SYS": { + "count": 87, + "latest": 123, + "min": 123, + "max": 137, + "mean": 130.2, + "median": null, + "avg7": 131.14, + "avg30": 130.1, + "slope7": { + "slope": -1.107, + "direction": "down", + "confidence": 0.22 + }, + "slope30": { + "slope": 0.043, + "direction": "up", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 130.24, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_DIA": { + "count": 87, + "latest": 78, + "min": 78, + "max": 86, + "mean": 81.94, + "median": null, + "avg7": 81.43, + "avg30": 81.66, + "slope7": { + "slope": -0.5, + "direction": "down", + "confidence": 0.17 + }, + "slope30": { + "slope": -0.019, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": 82.03, + "avg30LastYear": null + }, + "PULSE": { + "count": 58, + "latest": 64, + "min": 64, + "max": 69, + "mean": 66.57, + "median": null, + "avg7": 66.14, + "avg30": 66.55, + "slope7": { + "slope": -0.357, + "direction": "down", + "confidence": 0.16 + }, + "slope30": { + "slope": -0.035, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": 66.59, + "avg30LastYear": null + }, + "BODY_FAT": { + "count": 8, + "latest": 24, + "min": 24, + "max": 25.1, + "mean": 24.61, + "median": null, + "avg7": 24, + "avg30": 24.33, + "slope7": null, + "slope30": { + "slope": -0.021, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 24.9, + "avg30LastYear": null + }, + "SLEEP_DURATION": { + "count": 81, + "latest": 12, + "min": 12, + "max": 240, + "mean": 98.64, + "median": null, + "avg7": 96.17, + "avg30": 98.64, + "slope7": { + "slope": -2.121, + "direction": "down", + "confidence": 0 + }, + "slope30": { + "slope": -0.379, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "ACTIVITY_STEPS": { + "count": 29, + "latest": 6000, + "min": 6000, + "max": 9833, + "mean": 7780.83, + "median": null, + "avg7": 7119, + "avg30": 7780.83, + "slope7": { + "slope": -373, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -34.049, + "direction": "down", + "confidence": 0.07 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "BLOOD_GLUCOSE": { + "count": 57, + "latest": 128, + "min": 92, + "max": 147, + "mean": 113.12, + "median": null, + "avg7": 112.76, + "avg30": 113.12, + "slope7": { + "slope": -1.064, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.113, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "OXYGEN_SATURATION": { + "count": 9, + "latest": 96, + "min": 96, + "max": 98, + "mean": 96.89, + "median": null, + "avg7": 96.86, + "avg30": 96.89, + "slope7": { + "slope": -0.036, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.016, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "HEART_RATE_VARIABILITY": { + "count": 29, + "latest": 45, + "min": 45, + "max": 52, + "mean": 48.17, + "median": null, + "avg7": 48, + "avg30": 48.17, + "slope7": { + "slope": -1, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -0.046, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "RESTING_HEART_RATE": { + "count": 38, + "latest": 58, + "min": 58, + "max": 61, + "mean": 59.45, + "median": null, + "avg7": 59.29, + "avg30": 59.38, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.08 + }, + "slope30": { + "slope": -0.009, + "direction": "stable", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 59.67, + "avg30LastYear": null + } + }, + "bmi": 25.9, + "bmiClassification": { + "category": "Overweight", + "color": "var(--warning)", + "severity": "warning" + }, + "bpClassification": { + "category": "High-normal", + "color": "var(--dracula-yellow)", + "severity": "elevated" + }, + "bpPctInTarget": 11, + "bpTargets": { + "sysLow": 120, + "sysHigh": 129, + "diaLow": 70, + "diaHigh": 79 + }, + "weightBpCorrelation": null, + "scatterData": [ + { + "weight": 84.4, + "sysBP": 131 + }, + { + "weight": 84.3, + "sysBP": 124 + }, + { + "weight": 84.3, + "sysBP": 132 + }, + { + "weight": 84.2, + "sysBP": 125 + }, + { + "weight": 84.2, + "sysBP": 133 + }, + { + "weight": 84.2, + "sysBP": 126 + }, + { + "weight": 84.1, + "sysBP": 134 + }, + { + "weight": 84.1, + "sysBP": 127 + }, + { + "weight": 84, + "sysBP": 135 + }, + { + "weight": 84, + "sysBP": 128 + }, + { + "weight": 84, + "sysBP": 136 + }, + { + "weight": 83.9, + "sysBP": 129 + }, + { + "weight": 83.9, + "sysBP": 137 + }, + { + "weight": 83.8, + "sysBP": 130 + }, + { + "weight": 83.8, + "sysBP": 123 + }, + { + "weight": 83.8, + "sysBP": 131 + }, + { + "weight": 83.7, + "sysBP": 124 + }, + { + "weight": 83.7, + "sysBP": 132 + }, + { + "weight": 83.6, + "sysBP": 125 + }, + { + "weight": 83.6, + "sysBP": 133 + }, + { + "weight": 83.6, + "sysBP": 126 + }, + { + "weight": 83.5, + "sysBP": 134 + }, + { + "weight": 83.5, + "sysBP": 127 + }, + { + "weight": 83.4, + "sysBP": 135 + }, + { + "weight": 83.4, + "sysBP": 128 + }, + { + "weight": 83.4, + "sysBP": 136 + }, + { + "weight": 83.3, + "sysBP": 129 + }, + { + "weight": 83.3, + "sysBP": 137 + }, + { + "weight": 83.2, + "sysBP": 130 + }, + { + "weight": 83.2, + "sysBP": 131 + }, + { + "weight": 83.1, + "sysBP": 124 + }, + { + "weight": 83.1, + "sysBP": 132 + }, + { + "weight": 83, + "sysBP": 125 + }, + { + "weight": 83, + "sysBP": 133 + }, + { + "weight": 83, + "sysBP": 126 + }, + { + "weight": 82.9, + "sysBP": 134 + }, + { + "weight": 82.9, + "sysBP": 127 + }, + { + "weight": 82.8, + "sysBP": 135 + }, + { + "weight": 82.8, + "sysBP": 128 + }, + { + "weight": 82.8, + "sysBP": 136 + }, + { + "weight": 82.7, + "sysBP": 129 + }, + { + "weight": 82.7, + "sysBP": 137 + }, + { + "weight": 82.6, + "sysBP": 130 + }, + { + "weight": 82.6, + "sysBP": 123 + }, + { + "weight": 82.6, + "sysBP": 131 + }, + { + "weight": 82.5, + "sysBP": 124 + }, + { + "weight": 82.5, + "sysBP": 132 + }, + { + "weight": 82.4, + "sysBP": 125 + }, + { + "weight": 82.4, + "sysBP": 133 + }, + { + "weight": 82.4, + "sysBP": 126 + }, + { + "weight": 82.3, + "sysBP": 134 + }, + { + "weight": 82.2, + "sysBP": 135 + }, + { + "weight": 82.2, + "sysBP": 128 + }, + { + "weight": 82.2, + "sysBP": 136 + }, + { + "weight": 82.1, + "sysBP": 129 + }, + { + "weight": 82.1, + "sysBP": 137 + }, + { + "weight": 82, + "sysBP": 130 + }, + { + "weight": 82, + "sysBP": 123 + } + ], + "bpMedicationCorrelation": null, + "bpMedicationScatterData": [ + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 0, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 0, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 123 + }, + { + "continuityPct": 0, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + } + ], + "moodSummary": { + "count": 45, + "latest": 1, + "min": 1, + "max": 5, + "mean": 3, + "median": 3, + "avg7": 2.86, + "avg30": 3, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.04 + }, + "slope30": { + "slope": -0.013, + "direction": "down", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 3, + "avg30LastYear": null + }, + "moodBpCorrelation": null, + "moodBpScatterData": [ + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + } + ], + "moodWeightCorrelation": null, + "moodWeightScatterData": [ + { + "mood": 3, + "weight": 83.8 + }, + { + "mood": 5, + "weight": 83.7 + }, + { + "mood": 2, + "weight": 83.7 + }, + { + "mood": 4, + "weight": 83.6 + }, + { + "mood": 1, + "weight": 83.6 + }, + { + "mood": 3, + "weight": 83.6 + }, + { + "mood": 5, + "weight": 83.5 + }, + { + "mood": 2, + "weight": 83.5 + }, + { + "mood": 4, + "weight": 83.4 + }, + { + "mood": 1, + "weight": 83.4 + }, + { + "mood": 3, + "weight": 83.4 + }, + { + "mood": 5, + "weight": 83.3 + }, + { + "mood": 2, + "weight": 83.3 + }, + { + "mood": 4, + "weight": 83.2 + }, + { + "mood": 3, + "weight": 83.2 + }, + { + "mood": 5, + "weight": 83.1 + }, + { + "mood": 2, + "weight": 83.1 + }, + { + "mood": 4, + "weight": 83 + }, + { + "mood": 1, + "weight": 83 + }, + { + "mood": 3, + "weight": 83 + }, + { + "mood": 5, + "weight": 82.9 + }, + { + "mood": 2, + "weight": 82.9 + }, + { + "mood": 4, + "weight": 82.8 + }, + { + "mood": 1, + "weight": 82.8 + }, + { + "mood": 3, + "weight": 82.8 + }, + { + "mood": 5, + "weight": 82.7 + }, + { + "mood": 2, + "weight": 82.7 + }, + { + "mood": 4, + "weight": 82.6 + }, + { + "mood": 1, + "weight": 82.6 + }, + { + "mood": 3, + "weight": 82.6 + }, + { + "mood": 5, + "weight": 82.5 + }, + { + "mood": 2, + "weight": 82.5 + }, + { + "mood": 4, + "weight": 82.4 + }, + { + "mood": 1, + "weight": 82.4 + }, + { + "mood": 3, + "weight": 82.4 + }, + { + "mood": 5, + "weight": 82.3 + }, + { + "mood": 4, + "weight": 82.2 + }, + { + "mood": 1, + "weight": 82.2 + }, + { + "mood": 3, + "weight": 82.2 + }, + { + "mood": 5, + "weight": 82.1 + }, + { + "mood": 2, + "weight": 82.1 + }, + { + "mood": 4, + "weight": 82 + }, + { + "mood": 1, + "weight": 82 + } + ], + "moodPulseCorrelation": null, + "moodPulseScatterData": [ + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 2, + "pulse": 61 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + }, + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 1, + "pulse": 60 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + } + ], + "medications": [ + { + "id": "", + "name": "Ramipril", + "dose": "5mg", + "category": "BLOOD_PRESSURE", + "categoryLabel": null, + "compliance7": 100, + "compliance30": 76, + "streak": 0, + "taken7": 6, + "skipped7": 0, + "missed7": 0 + }, + { + "id": "", + "name": "Vitamin D", + "dose": "1000 IU", + "category": "OTHER", + "categoryLabel": null, + "compliance7": 43, + "compliance30": 47, + "streak": 1, + "taken7": 3, + "skipped7": 0, + "missed7": 4 + } + ], + "alerts": [ + { + "level": "info", + "title": "BMI in overweight range", + "message": "Your BMI of 25.9 is in the overweight range. Regular exercise and a balanced diet can help." + }, + { + "level": "warning", + "title": "Blood pressure often outside target range", + "message": "Only 11% of your readings are within the target range." + }, + { + "level": "success", + "title": "Excellent compliance: Ramipril", + "message": "100% compliance over the last 7 days. Keep it up!" + }, + { + "level": "warning", + "title": "Low compliance: Vitamin D", + "message": "Your 7-day compliance for Vitamin D is only 43%. Regular intake is important." + } + ], + "hasProvider": true, + "dataSpanDays": 90, + "totalMeasurements": 541, + "revalidating": false, + "ai": { + "briefing": { + "available": true, + "reason": null, + "onDeviceAllowed": true + }, + "statusText": { + "available": true, + "reason": null, + "onDeviceAllowed": true + } + } + }, + "error": null + }, + "events": [ + { + "status": 200, + "action": { + "name": "insights.comprehensive" + }, + "meta": { + "cache.analytics.key_hash": 3572442229, + "cache.analytics.outcome": "miss", + "insights": { + "slope_source": "rollup", + "anomaly_source": "live", + "regression_source": "rollup" + }, + "insights.sub_bpRaw_ms": "", + "insights.sub_buckets_ms": "", + "insights.sub_coverage_ms": "", + "insights.sub_firstAt_ms": "", + "insights.sub_latests_ms": "", + "insights.sub_narrow_ms": "", + "medications": 2, + "moodEntries": 45, + "totalMeasurements": 541 + }, + "warnings": null, + "error": null + } + ], + "effects": [ + { + "effect": "ensureUserRollupsFresh", + "args": [ + "" + ] + }, + { + "effect": "ensureUserMoodRollupsFresh", + "args": [ + "" + ] + } + ] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.03-warm.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.03-warm.json.snap new file mode 100644 index 000000000..cdd109367 --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.03-warm.json.snap @@ -0,0 +1,1274 @@ +{ + "status": 200, + "body": { + "data": { + "summaries": { + "WEIGHT": { + "count": 58, + "latest": 82, + "min": 82, + "max": 84.4, + "mean": 83.19, + "median": null, + "avg7": 82.11, + "avg30": 82.59, + "slope7": { + "slope": -0.039, + "direction": "down", + "confidence": 0.89 + }, + "slope30": { + "slope": -0.04, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 83.8, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_SYS": { + "count": 87, + "latest": 123, + "min": 123, + "max": 137, + "mean": 130.2, + "median": null, + "avg7": 131.14, + "avg30": 130.1, + "slope7": { + "slope": -1.107, + "direction": "down", + "confidence": 0.22 + }, + "slope30": { + "slope": 0.043, + "direction": "up", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 130.24, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_DIA": { + "count": 87, + "latest": 78, + "min": 78, + "max": 86, + "mean": 81.94, + "median": null, + "avg7": 81.43, + "avg30": 81.66, + "slope7": { + "slope": -0.5, + "direction": "down", + "confidence": 0.17 + }, + "slope30": { + "slope": -0.019, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": 82.03, + "avg30LastYear": null + }, + "PULSE": { + "count": 58, + "latest": 64, + "min": 64, + "max": 69, + "mean": 66.57, + "median": null, + "avg7": 66.14, + "avg30": 66.55, + "slope7": { + "slope": -0.357, + "direction": "down", + "confidence": 0.16 + }, + "slope30": { + "slope": -0.035, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": 66.59, + "avg30LastYear": null + }, + "BODY_FAT": { + "count": 8, + "latest": 24, + "min": 24, + "max": 25.1, + "mean": 24.61, + "median": null, + "avg7": 24, + "avg30": 24.33, + "slope7": null, + "slope30": { + "slope": -0.021, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 24.9, + "avg30LastYear": null + }, + "SLEEP_DURATION": { + "count": 81, + "latest": 12, + "min": 12, + "max": 240, + "mean": 98.64, + "median": null, + "avg7": 96.17, + "avg30": 98.64, + "slope7": { + "slope": -2.121, + "direction": "down", + "confidence": 0 + }, + "slope30": { + "slope": -0.379, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "ACTIVITY_STEPS": { + "count": 29, + "latest": 6000, + "min": 6000, + "max": 9833, + "mean": 7780.83, + "median": null, + "avg7": 7119, + "avg30": 7780.83, + "slope7": { + "slope": -373, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -34.049, + "direction": "down", + "confidence": 0.07 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "BLOOD_GLUCOSE": { + "count": 57, + "latest": 128, + "min": 92, + "max": 147, + "mean": 113.12, + "median": null, + "avg7": 112.76, + "avg30": 113.12, + "slope7": { + "slope": -1.064, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.113, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "OXYGEN_SATURATION": { + "count": 9, + "latest": 96, + "min": 96, + "max": 98, + "mean": 96.89, + "median": null, + "avg7": 96.86, + "avg30": 96.89, + "slope7": { + "slope": -0.036, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.016, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "HEART_RATE_VARIABILITY": { + "count": 29, + "latest": 45, + "min": 45, + "max": 52, + "mean": 48.17, + "median": null, + "avg7": 48, + "avg30": 48.17, + "slope7": { + "slope": -1, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -0.046, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "RESTING_HEART_RATE": { + "count": 38, + "latest": 58, + "min": 58, + "max": 61, + "mean": 59.45, + "median": null, + "avg7": 59.29, + "avg30": 59.38, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.08 + }, + "slope30": { + "slope": -0.009, + "direction": "stable", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 59.67, + "avg30LastYear": null + } + }, + "bmi": 25.9, + "bmiClassification": { + "category": "Overweight", + "color": "var(--warning)", + "severity": "warning" + }, + "bpClassification": { + "category": "High-normal", + "color": "var(--dracula-yellow)", + "severity": "elevated" + }, + "bpPctInTarget": 11, + "bpTargets": { + "sysLow": 120, + "sysHigh": 129, + "diaLow": 70, + "diaHigh": 79 + }, + "weightBpCorrelation": null, + "scatterData": [ + { + "weight": 84.4, + "sysBP": 131 + }, + { + "weight": 84.3, + "sysBP": 124 + }, + { + "weight": 84.3, + "sysBP": 132 + }, + { + "weight": 84.2, + "sysBP": 125 + }, + { + "weight": 84.2, + "sysBP": 133 + }, + { + "weight": 84.2, + "sysBP": 126 + }, + { + "weight": 84.1, + "sysBP": 134 + }, + { + "weight": 84.1, + "sysBP": 127 + }, + { + "weight": 84, + "sysBP": 135 + }, + { + "weight": 84, + "sysBP": 128 + }, + { + "weight": 84, + "sysBP": 136 + }, + { + "weight": 83.9, + "sysBP": 129 + }, + { + "weight": 83.9, + "sysBP": 137 + }, + { + "weight": 83.8, + "sysBP": 130 + }, + { + "weight": 83.8, + "sysBP": 123 + }, + { + "weight": 83.8, + "sysBP": 131 + }, + { + "weight": 83.7, + "sysBP": 124 + }, + { + "weight": 83.7, + "sysBP": 132 + }, + { + "weight": 83.6, + "sysBP": 125 + }, + { + "weight": 83.6, + "sysBP": 133 + }, + { + "weight": 83.6, + "sysBP": 126 + }, + { + "weight": 83.5, + "sysBP": 134 + }, + { + "weight": 83.5, + "sysBP": 127 + }, + { + "weight": 83.4, + "sysBP": 135 + }, + { + "weight": 83.4, + "sysBP": 128 + }, + { + "weight": 83.4, + "sysBP": 136 + }, + { + "weight": 83.3, + "sysBP": 129 + }, + { + "weight": 83.3, + "sysBP": 137 + }, + { + "weight": 83.2, + "sysBP": 130 + }, + { + "weight": 83.2, + "sysBP": 131 + }, + { + "weight": 83.1, + "sysBP": 124 + }, + { + "weight": 83.1, + "sysBP": 132 + }, + { + "weight": 83, + "sysBP": 125 + }, + { + "weight": 83, + "sysBP": 133 + }, + { + "weight": 83, + "sysBP": 126 + }, + { + "weight": 82.9, + "sysBP": 134 + }, + { + "weight": 82.9, + "sysBP": 127 + }, + { + "weight": 82.8, + "sysBP": 135 + }, + { + "weight": 82.8, + "sysBP": 128 + }, + { + "weight": 82.8, + "sysBP": 136 + }, + { + "weight": 82.7, + "sysBP": 129 + }, + { + "weight": 82.7, + "sysBP": 137 + }, + { + "weight": 82.6, + "sysBP": 130 + }, + { + "weight": 82.6, + "sysBP": 123 + }, + { + "weight": 82.6, + "sysBP": 131 + }, + { + "weight": 82.5, + "sysBP": 124 + }, + { + "weight": 82.5, + "sysBP": 132 + }, + { + "weight": 82.4, + "sysBP": 125 + }, + { + "weight": 82.4, + "sysBP": 133 + }, + { + "weight": 82.4, + "sysBP": 126 + }, + { + "weight": 82.3, + "sysBP": 134 + }, + { + "weight": 82.2, + "sysBP": 135 + }, + { + "weight": 82.2, + "sysBP": 128 + }, + { + "weight": 82.2, + "sysBP": 136 + }, + { + "weight": 82.1, + "sysBP": 129 + }, + { + "weight": 82.1, + "sysBP": 137 + }, + { + "weight": 82, + "sysBP": 130 + }, + { + "weight": 82, + "sysBP": 123 + } + ], + "bpMedicationCorrelation": null, + "bpMedicationScatterData": [ + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 0, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 0, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 123 + }, + { + "continuityPct": 0, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + } + ], + "moodSummary": { + "count": 45, + "latest": 1, + "min": 1, + "max": 5, + "mean": 3, + "median": 3, + "avg7": 2.86, + "avg30": 3, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.04 + }, + "slope30": { + "slope": -0.013, + "direction": "down", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 3, + "avg30LastYear": null + }, + "moodBpCorrelation": null, + "moodBpScatterData": [ + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + } + ], + "moodWeightCorrelation": null, + "moodWeightScatterData": [ + { + "mood": 3, + "weight": 83.8 + }, + { + "mood": 5, + "weight": 83.7 + }, + { + "mood": 2, + "weight": 83.7 + }, + { + "mood": 4, + "weight": 83.6 + }, + { + "mood": 1, + "weight": 83.6 + }, + { + "mood": 3, + "weight": 83.6 + }, + { + "mood": 5, + "weight": 83.5 + }, + { + "mood": 2, + "weight": 83.5 + }, + { + "mood": 4, + "weight": 83.4 + }, + { + "mood": 1, + "weight": 83.4 + }, + { + "mood": 3, + "weight": 83.4 + }, + { + "mood": 5, + "weight": 83.3 + }, + { + "mood": 2, + "weight": 83.3 + }, + { + "mood": 4, + "weight": 83.2 + }, + { + "mood": 3, + "weight": 83.2 + }, + { + "mood": 5, + "weight": 83.1 + }, + { + "mood": 2, + "weight": 83.1 + }, + { + "mood": 4, + "weight": 83 + }, + { + "mood": 1, + "weight": 83 + }, + { + "mood": 3, + "weight": 83 + }, + { + "mood": 5, + "weight": 82.9 + }, + { + "mood": 2, + "weight": 82.9 + }, + { + "mood": 4, + "weight": 82.8 + }, + { + "mood": 1, + "weight": 82.8 + }, + { + "mood": 3, + "weight": 82.8 + }, + { + "mood": 5, + "weight": 82.7 + }, + { + "mood": 2, + "weight": 82.7 + }, + { + "mood": 4, + "weight": 82.6 + }, + { + "mood": 1, + "weight": 82.6 + }, + { + "mood": 3, + "weight": 82.6 + }, + { + "mood": 5, + "weight": 82.5 + }, + { + "mood": 2, + "weight": 82.5 + }, + { + "mood": 4, + "weight": 82.4 + }, + { + "mood": 1, + "weight": 82.4 + }, + { + "mood": 3, + "weight": 82.4 + }, + { + "mood": 5, + "weight": 82.3 + }, + { + "mood": 4, + "weight": 82.2 + }, + { + "mood": 1, + "weight": 82.2 + }, + { + "mood": 3, + "weight": 82.2 + }, + { + "mood": 5, + "weight": 82.1 + }, + { + "mood": 2, + "weight": 82.1 + }, + { + "mood": 4, + "weight": 82 + }, + { + "mood": 1, + "weight": 82 + } + ], + "moodPulseCorrelation": null, + "moodPulseScatterData": [ + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 2, + "pulse": 61 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + }, + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 1, + "pulse": 60 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + } + ], + "medications": [ + { + "id": "", + "name": "Ramipril", + "dose": "5mg", + "category": "BLOOD_PRESSURE", + "categoryLabel": null, + "compliance7": 100, + "compliance30": 76, + "streak": 0, + "taken7": 6, + "skipped7": 0, + "missed7": 0 + }, + { + "id": "", + "name": "Vitamin D", + "dose": "1000 IU", + "category": "OTHER", + "categoryLabel": null, + "compliance7": 43, + "compliance30": 47, + "streak": 1, + "taken7": 3, + "skipped7": 0, + "missed7": 4 + } + ], + "alerts": [ + { + "level": "info", + "title": "BMI in overweight range", + "message": "Your BMI of 25.9 is in the overweight range. Regular exercise and a balanced diet can help." + }, + { + "level": "warning", + "title": "Blood pressure often outside target range", + "message": "Only 11% of your readings are within the target range." + }, + { + "level": "success", + "title": "Excellent compliance: Ramipril", + "message": "100% compliance over the last 7 days. Keep it up!" + }, + { + "level": "warning", + "title": "Low compliance: Vitamin D", + "message": "Your 7-day compliance for Vitamin D is only 43%. Regular intake is important." + } + ], + "hasProvider": true, + "dataSpanDays": 90, + "totalMeasurements": 541, + "revalidating": false, + "ai": { + "briefing": { + "available": true, + "reason": null, + "onDeviceAllowed": true + }, + "statusText": { + "available": true, + "reason": null, + "onDeviceAllowed": true + } + } + }, + "error": null + }, + "events": [ + { + "status": 200, + "action": null, + "meta": { + "cache.analytics.key_hash": 3572442229, + "cache.analytics.outcome": "hit" + }, + "warnings": null, + "error": null + } + ], + "effects": [] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.04-stale.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.04-stale.json.snap new file mode 100644 index 000000000..f2a85fa5b --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.04-stale.json.snap @@ -0,0 +1,1287 @@ +{ + "status": 200, + "body": { + "data": { + "summaries": { + "WEIGHT": { + "count": 58, + "latest": 82, + "min": 82, + "max": 84.4, + "mean": 83.19, + "median": null, + "avg7": 82.11, + "avg30": 82.59, + "slope7": { + "slope": -0.039, + "direction": "down", + "confidence": 0.89 + }, + "slope30": { + "slope": -0.04, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 83.8, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_SYS": { + "count": 87, + "latest": 123, + "min": 123, + "max": 137, + "mean": 130.2, + "median": null, + "avg7": 131.14, + "avg30": 130.1, + "slope7": { + "slope": -1.107, + "direction": "down", + "confidence": 0.22 + }, + "slope30": { + "slope": 0.043, + "direction": "up", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 130.24, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_DIA": { + "count": 87, + "latest": 78, + "min": 78, + "max": 86, + "mean": 81.94, + "median": null, + "avg7": 81.43, + "avg30": 81.66, + "slope7": { + "slope": -0.5, + "direction": "down", + "confidence": 0.17 + }, + "slope30": { + "slope": -0.019, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": 82.03, + "avg30LastYear": null + }, + "PULSE": { + "count": 58, + "latest": 64, + "min": 64, + "max": 69, + "mean": 66.57, + "median": null, + "avg7": 66.14, + "avg30": 66.55, + "slope7": { + "slope": -0.357, + "direction": "down", + "confidence": 0.16 + }, + "slope30": { + "slope": -0.035, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": 66.59, + "avg30LastYear": null + }, + "BODY_FAT": { + "count": 8, + "latest": 24, + "min": 24, + "max": 25.1, + "mean": 24.61, + "median": null, + "avg7": 24, + "avg30": 24.33, + "slope7": null, + "slope30": { + "slope": -0.021, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 24.9, + "avg30LastYear": null + }, + "SLEEP_DURATION": { + "count": 81, + "latest": 12, + "min": 12, + "max": 240, + "mean": 98.64, + "median": null, + "avg7": 96.17, + "avg30": 98.64, + "slope7": { + "slope": -2.121, + "direction": "down", + "confidence": 0 + }, + "slope30": { + "slope": -0.379, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "ACTIVITY_STEPS": { + "count": 29, + "latest": 6000, + "min": 6000, + "max": 9833, + "mean": 7780.83, + "median": null, + "avg7": 7119, + "avg30": 7780.83, + "slope7": { + "slope": -373, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -34.049, + "direction": "down", + "confidence": 0.07 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "BLOOD_GLUCOSE": { + "count": 57, + "latest": 128, + "min": 92, + "max": 147, + "mean": 113.12, + "median": null, + "avg7": 112.76, + "avg30": 113.12, + "slope7": { + "slope": -1.064, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.113, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "OXYGEN_SATURATION": { + "count": 9, + "latest": 96, + "min": 96, + "max": 98, + "mean": 96.89, + "median": null, + "avg7": 96.86, + "avg30": 96.89, + "slope7": { + "slope": -0.036, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.016, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "HEART_RATE_VARIABILITY": { + "count": 29, + "latest": 45, + "min": 45, + "max": 52, + "mean": 48.17, + "median": null, + "avg7": 48, + "avg30": 48.17, + "slope7": { + "slope": -1, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -0.046, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "RESTING_HEART_RATE": { + "count": 38, + "latest": 58, + "min": 58, + "max": 61, + "mean": 59.45, + "median": null, + "avg7": 59.29, + "avg30": 59.38, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.08 + }, + "slope30": { + "slope": -0.009, + "direction": "stable", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 59.67, + "avg30LastYear": null + } + }, + "bmi": 25.9, + "bmiClassification": { + "category": "Overweight", + "color": "var(--warning)", + "severity": "warning" + }, + "bpClassification": { + "category": "High-normal", + "color": "var(--dracula-yellow)", + "severity": "elevated" + }, + "bpPctInTarget": 11, + "bpTargets": { + "sysLow": 120, + "sysHigh": 129, + "diaLow": 70, + "diaHigh": 79 + }, + "weightBpCorrelation": null, + "scatterData": [ + { + "weight": 84.4, + "sysBP": 131 + }, + { + "weight": 84.3, + "sysBP": 124 + }, + { + "weight": 84.3, + "sysBP": 132 + }, + { + "weight": 84.2, + "sysBP": 125 + }, + { + "weight": 84.2, + "sysBP": 133 + }, + { + "weight": 84.2, + "sysBP": 126 + }, + { + "weight": 84.1, + "sysBP": 134 + }, + { + "weight": 84.1, + "sysBP": 127 + }, + { + "weight": 84, + "sysBP": 135 + }, + { + "weight": 84, + "sysBP": 128 + }, + { + "weight": 84, + "sysBP": 136 + }, + { + "weight": 83.9, + "sysBP": 129 + }, + { + "weight": 83.9, + "sysBP": 137 + }, + { + "weight": 83.8, + "sysBP": 130 + }, + { + "weight": 83.8, + "sysBP": 123 + }, + { + "weight": 83.8, + "sysBP": 131 + }, + { + "weight": 83.7, + "sysBP": 124 + }, + { + "weight": 83.7, + "sysBP": 132 + }, + { + "weight": 83.6, + "sysBP": 125 + }, + { + "weight": 83.6, + "sysBP": 133 + }, + { + "weight": 83.6, + "sysBP": 126 + }, + { + "weight": 83.5, + "sysBP": 134 + }, + { + "weight": 83.5, + "sysBP": 127 + }, + { + "weight": 83.4, + "sysBP": 135 + }, + { + "weight": 83.4, + "sysBP": 128 + }, + { + "weight": 83.4, + "sysBP": 136 + }, + { + "weight": 83.3, + "sysBP": 129 + }, + { + "weight": 83.3, + "sysBP": 137 + }, + { + "weight": 83.2, + "sysBP": 130 + }, + { + "weight": 83.2, + "sysBP": 131 + }, + { + "weight": 83.1, + "sysBP": 124 + }, + { + "weight": 83.1, + "sysBP": 132 + }, + { + "weight": 83, + "sysBP": 125 + }, + { + "weight": 83, + "sysBP": 133 + }, + { + "weight": 83, + "sysBP": 126 + }, + { + "weight": 82.9, + "sysBP": 134 + }, + { + "weight": 82.9, + "sysBP": 127 + }, + { + "weight": 82.8, + "sysBP": 135 + }, + { + "weight": 82.8, + "sysBP": 128 + }, + { + "weight": 82.8, + "sysBP": 136 + }, + { + "weight": 82.7, + "sysBP": 129 + }, + { + "weight": 82.7, + "sysBP": 137 + }, + { + "weight": 82.6, + "sysBP": 130 + }, + { + "weight": 82.6, + "sysBP": 123 + }, + { + "weight": 82.6, + "sysBP": 131 + }, + { + "weight": 82.5, + "sysBP": 124 + }, + { + "weight": 82.5, + "sysBP": 132 + }, + { + "weight": 82.4, + "sysBP": 125 + }, + { + "weight": 82.4, + "sysBP": 133 + }, + { + "weight": 82.4, + "sysBP": 126 + }, + { + "weight": 82.3, + "sysBP": 134 + }, + { + "weight": 82.2, + "sysBP": 135 + }, + { + "weight": 82.2, + "sysBP": 128 + }, + { + "weight": 82.2, + "sysBP": 136 + }, + { + "weight": 82.1, + "sysBP": 129 + }, + { + "weight": 82.1, + "sysBP": 137 + }, + { + "weight": 82, + "sysBP": 130 + }, + { + "weight": 82, + "sysBP": 123 + } + ], + "bpMedicationCorrelation": null, + "bpMedicationScatterData": [ + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 0, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 0, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 123 + }, + { + "continuityPct": 0, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + } + ], + "moodSummary": { + "count": 45, + "latest": 1, + "min": 1, + "max": 5, + "mean": 3, + "median": 3, + "avg7": 2.86, + "avg30": 3, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.04 + }, + "slope30": { + "slope": -0.013, + "direction": "down", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 3, + "avg30LastYear": null + }, + "moodBpCorrelation": null, + "moodBpScatterData": [ + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + } + ], + "moodWeightCorrelation": null, + "moodWeightScatterData": [ + { + "mood": 3, + "weight": 83.8 + }, + { + "mood": 5, + "weight": 83.7 + }, + { + "mood": 2, + "weight": 83.7 + }, + { + "mood": 4, + "weight": 83.6 + }, + { + "mood": 1, + "weight": 83.6 + }, + { + "mood": 3, + "weight": 83.6 + }, + { + "mood": 5, + "weight": 83.5 + }, + { + "mood": 2, + "weight": 83.5 + }, + { + "mood": 4, + "weight": 83.4 + }, + { + "mood": 1, + "weight": 83.4 + }, + { + "mood": 3, + "weight": 83.4 + }, + { + "mood": 5, + "weight": 83.3 + }, + { + "mood": 2, + "weight": 83.3 + }, + { + "mood": 4, + "weight": 83.2 + }, + { + "mood": 3, + "weight": 83.2 + }, + { + "mood": 5, + "weight": 83.1 + }, + { + "mood": 2, + "weight": 83.1 + }, + { + "mood": 4, + "weight": 83 + }, + { + "mood": 1, + "weight": 83 + }, + { + "mood": 3, + "weight": 83 + }, + { + "mood": 5, + "weight": 82.9 + }, + { + "mood": 2, + "weight": 82.9 + }, + { + "mood": 4, + "weight": 82.8 + }, + { + "mood": 1, + "weight": 82.8 + }, + { + "mood": 3, + "weight": 82.8 + }, + { + "mood": 5, + "weight": 82.7 + }, + { + "mood": 2, + "weight": 82.7 + }, + { + "mood": 4, + "weight": 82.6 + }, + { + "mood": 1, + "weight": 82.6 + }, + { + "mood": 3, + "weight": 82.6 + }, + { + "mood": 5, + "weight": 82.5 + }, + { + "mood": 2, + "weight": 82.5 + }, + { + "mood": 4, + "weight": 82.4 + }, + { + "mood": 1, + "weight": 82.4 + }, + { + "mood": 3, + "weight": 82.4 + }, + { + "mood": 5, + "weight": 82.3 + }, + { + "mood": 4, + "weight": 82.2 + }, + { + "mood": 1, + "weight": 82.2 + }, + { + "mood": 3, + "weight": 82.2 + }, + { + "mood": 5, + "weight": 82.1 + }, + { + "mood": 2, + "weight": 82.1 + }, + { + "mood": 4, + "weight": 82 + }, + { + "mood": 1, + "weight": 82 + } + ], + "moodPulseCorrelation": null, + "moodPulseScatterData": [ + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 2, + "pulse": 61 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + }, + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 1, + "pulse": 60 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + } + ], + "medications": [ + { + "id": "", + "name": "Ramipril", + "dose": "5mg", + "category": "BLOOD_PRESSURE", + "categoryLabel": null, + "compliance7": 100, + "compliance30": 76, + "streak": 0, + "taken7": 6, + "skipped7": 0, + "missed7": 0 + }, + { + "id": "", + "name": "Vitamin D", + "dose": "1000 IU", + "category": "OTHER", + "categoryLabel": null, + "compliance7": 43, + "compliance30": 47, + "streak": 1, + "taken7": 3, + "skipped7": 0, + "missed7": 4 + } + ], + "alerts": [ + { + "level": "info", + "title": "BMI in overweight range", + "message": "Your BMI of 25.9 is in the overweight range. Regular exercise and a balanced diet can help." + }, + { + "level": "warning", + "title": "Blood pressure often outside target range", + "message": "Only 11% of your readings are within the target range." + }, + { + "level": "success", + "title": "Excellent compliance: Ramipril", + "message": "100% compliance over the last 7 days. Keep it up!" + }, + { + "level": "warning", + "title": "Low compliance: Vitamin D", + "message": "Your 7-day compliance for Vitamin D is only 43%. Regular intake is important." + } + ], + "hasProvider": true, + "dataSpanDays": 90, + "totalMeasurements": 541, + "revalidating": true, + "ai": { + "briefing": { + "available": true, + "reason": null, + "onDeviceAllowed": true + }, + "statusText": { + "available": true, + "reason": null, + "onDeviceAllowed": true + } + } + }, + "error": null + }, + "events": [ + { + "status": 200, + "action": "", + "meta": { + "cache.analytics.key_hash": 3572442229, + "cache.analytics.outcome": "stale" + }, + "warnings": null, + "error": null + } + ], + "effects": [ + { + "effect": "ensureUserRollupsFresh", + "args": [ + "" + ] + }, + { + "effect": "ensureUserMoodRollupsFresh", + "args": [ + "" + ] + } + ] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.05-ai-analysis-off.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.05-ai-analysis-off.json.snap new file mode 100644 index 000000000..7235cd05c --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.05-ai-analysis-off.json.snap @@ -0,0 +1,1274 @@ +{ + "status": 200, + "body": { + "data": { + "summaries": { + "WEIGHT": { + "count": 58, + "latest": 82, + "min": 82, + "max": 84.4, + "mean": 83.19, + "median": null, + "avg7": 82.11, + "avg30": 82.59, + "slope7": { + "slope": -0.039, + "direction": "down", + "confidence": 0.89 + }, + "slope30": { + "slope": -0.04, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 83.8, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_SYS": { + "count": 87, + "latest": 123, + "min": 123, + "max": 137, + "mean": 130.2, + "median": null, + "avg7": 131.14, + "avg30": 130.1, + "slope7": { + "slope": -1.107, + "direction": "down", + "confidence": 0.22 + }, + "slope30": { + "slope": 0.043, + "direction": "up", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 130.24, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_DIA": { + "count": 87, + "latest": 78, + "min": 78, + "max": 86, + "mean": 81.94, + "median": null, + "avg7": 81.43, + "avg30": 81.66, + "slope7": { + "slope": -0.5, + "direction": "down", + "confidence": 0.17 + }, + "slope30": { + "slope": -0.019, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": 82.03, + "avg30LastYear": null + }, + "PULSE": { + "count": 58, + "latest": 64, + "min": 64, + "max": 69, + "mean": 66.57, + "median": null, + "avg7": 66.14, + "avg30": 66.55, + "slope7": { + "slope": -0.357, + "direction": "down", + "confidence": 0.16 + }, + "slope30": { + "slope": -0.035, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": 66.59, + "avg30LastYear": null + }, + "BODY_FAT": { + "count": 8, + "latest": 24, + "min": 24, + "max": 25.1, + "mean": 24.61, + "median": null, + "avg7": 24, + "avg30": 24.33, + "slope7": null, + "slope30": { + "slope": -0.021, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 24.9, + "avg30LastYear": null + }, + "SLEEP_DURATION": { + "count": 81, + "latest": 12, + "min": 12, + "max": 240, + "mean": 98.64, + "median": null, + "avg7": 96.17, + "avg30": 98.64, + "slope7": { + "slope": -2.121, + "direction": "down", + "confidence": 0 + }, + "slope30": { + "slope": -0.379, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "ACTIVITY_STEPS": { + "count": 29, + "latest": 6000, + "min": 6000, + "max": 9833, + "mean": 7780.83, + "median": null, + "avg7": 7119, + "avg30": 7780.83, + "slope7": { + "slope": -373, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -34.049, + "direction": "down", + "confidence": 0.07 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "BLOOD_GLUCOSE": { + "count": 57, + "latest": 128, + "min": 92, + "max": 147, + "mean": 113.12, + "median": null, + "avg7": 112.76, + "avg30": 113.12, + "slope7": { + "slope": -1.064, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.113, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "OXYGEN_SATURATION": { + "count": 9, + "latest": 96, + "min": 96, + "max": 98, + "mean": 96.89, + "median": null, + "avg7": 96.86, + "avg30": 96.89, + "slope7": { + "slope": -0.036, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.016, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "HEART_RATE_VARIABILITY": { + "count": 29, + "latest": 45, + "min": 45, + "max": 52, + "mean": 48.17, + "median": null, + "avg7": 48, + "avg30": 48.17, + "slope7": { + "slope": -1, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -0.046, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "RESTING_HEART_RATE": { + "count": 38, + "latest": 58, + "min": 58, + "max": 61, + "mean": 59.45, + "median": null, + "avg7": 59.29, + "avg30": 59.38, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.08 + }, + "slope30": { + "slope": -0.009, + "direction": "stable", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 59.67, + "avg30LastYear": null + } + }, + "bmi": 25.9, + "bmiClassification": { + "category": "Overweight", + "color": "var(--warning)", + "severity": "warning" + }, + "bpClassification": { + "category": "High-normal", + "color": "var(--dracula-yellow)", + "severity": "elevated" + }, + "bpPctInTarget": 11, + "bpTargets": { + "sysLow": 120, + "sysHigh": 129, + "diaLow": 70, + "diaHigh": 79 + }, + "weightBpCorrelation": null, + "scatterData": [ + { + "weight": 84.4, + "sysBP": 131 + }, + { + "weight": 84.3, + "sysBP": 124 + }, + { + "weight": 84.3, + "sysBP": 132 + }, + { + "weight": 84.2, + "sysBP": 125 + }, + { + "weight": 84.2, + "sysBP": 133 + }, + { + "weight": 84.2, + "sysBP": 126 + }, + { + "weight": 84.1, + "sysBP": 134 + }, + { + "weight": 84.1, + "sysBP": 127 + }, + { + "weight": 84, + "sysBP": 135 + }, + { + "weight": 84, + "sysBP": 128 + }, + { + "weight": 84, + "sysBP": 136 + }, + { + "weight": 83.9, + "sysBP": 129 + }, + { + "weight": 83.9, + "sysBP": 137 + }, + { + "weight": 83.8, + "sysBP": 130 + }, + { + "weight": 83.8, + "sysBP": 123 + }, + { + "weight": 83.8, + "sysBP": 131 + }, + { + "weight": 83.7, + "sysBP": 124 + }, + { + "weight": 83.7, + "sysBP": 132 + }, + { + "weight": 83.6, + "sysBP": 125 + }, + { + "weight": 83.6, + "sysBP": 133 + }, + { + "weight": 83.6, + "sysBP": 126 + }, + { + "weight": 83.5, + "sysBP": 134 + }, + { + "weight": 83.5, + "sysBP": 127 + }, + { + "weight": 83.4, + "sysBP": 135 + }, + { + "weight": 83.4, + "sysBP": 128 + }, + { + "weight": 83.4, + "sysBP": 136 + }, + { + "weight": 83.3, + "sysBP": 129 + }, + { + "weight": 83.3, + "sysBP": 137 + }, + { + "weight": 83.2, + "sysBP": 130 + }, + { + "weight": 83.2, + "sysBP": 131 + }, + { + "weight": 83.1, + "sysBP": 124 + }, + { + "weight": 83.1, + "sysBP": 132 + }, + { + "weight": 83, + "sysBP": 125 + }, + { + "weight": 83, + "sysBP": 133 + }, + { + "weight": 83, + "sysBP": 126 + }, + { + "weight": 82.9, + "sysBP": 134 + }, + { + "weight": 82.9, + "sysBP": 127 + }, + { + "weight": 82.8, + "sysBP": 135 + }, + { + "weight": 82.8, + "sysBP": 128 + }, + { + "weight": 82.8, + "sysBP": 136 + }, + { + "weight": 82.7, + "sysBP": 129 + }, + { + "weight": 82.7, + "sysBP": 137 + }, + { + "weight": 82.6, + "sysBP": 130 + }, + { + "weight": 82.6, + "sysBP": 123 + }, + { + "weight": 82.6, + "sysBP": 131 + }, + { + "weight": 82.5, + "sysBP": 124 + }, + { + "weight": 82.5, + "sysBP": 132 + }, + { + "weight": 82.4, + "sysBP": 125 + }, + { + "weight": 82.4, + "sysBP": 133 + }, + { + "weight": 82.4, + "sysBP": 126 + }, + { + "weight": 82.3, + "sysBP": 134 + }, + { + "weight": 82.2, + "sysBP": 135 + }, + { + "weight": 82.2, + "sysBP": 128 + }, + { + "weight": 82.2, + "sysBP": 136 + }, + { + "weight": 82.1, + "sysBP": 129 + }, + { + "weight": 82.1, + "sysBP": 137 + }, + { + "weight": 82, + "sysBP": 130 + }, + { + "weight": 82, + "sysBP": 123 + } + ], + "bpMedicationCorrelation": null, + "bpMedicationScatterData": [ + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 0, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 0, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 123 + }, + { + "continuityPct": 0, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + } + ], + "moodSummary": { + "count": 45, + "latest": 1, + "min": 1, + "max": 5, + "mean": 3, + "median": 3, + "avg7": 2.86, + "avg30": 3, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.04 + }, + "slope30": { + "slope": -0.013, + "direction": "down", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 3, + "avg30LastYear": null + }, + "moodBpCorrelation": null, + "moodBpScatterData": [ + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + } + ], + "moodWeightCorrelation": null, + "moodWeightScatterData": [ + { + "mood": 3, + "weight": 83.8 + }, + { + "mood": 5, + "weight": 83.7 + }, + { + "mood": 2, + "weight": 83.7 + }, + { + "mood": 4, + "weight": 83.6 + }, + { + "mood": 1, + "weight": 83.6 + }, + { + "mood": 3, + "weight": 83.6 + }, + { + "mood": 5, + "weight": 83.5 + }, + { + "mood": 2, + "weight": 83.5 + }, + { + "mood": 4, + "weight": 83.4 + }, + { + "mood": 1, + "weight": 83.4 + }, + { + "mood": 3, + "weight": 83.4 + }, + { + "mood": 5, + "weight": 83.3 + }, + { + "mood": 2, + "weight": 83.3 + }, + { + "mood": 4, + "weight": 83.2 + }, + { + "mood": 3, + "weight": 83.2 + }, + { + "mood": 5, + "weight": 83.1 + }, + { + "mood": 2, + "weight": 83.1 + }, + { + "mood": 4, + "weight": 83 + }, + { + "mood": 1, + "weight": 83 + }, + { + "mood": 3, + "weight": 83 + }, + { + "mood": 5, + "weight": 82.9 + }, + { + "mood": 2, + "weight": 82.9 + }, + { + "mood": 4, + "weight": 82.8 + }, + { + "mood": 1, + "weight": 82.8 + }, + { + "mood": 3, + "weight": 82.8 + }, + { + "mood": 5, + "weight": 82.7 + }, + { + "mood": 2, + "weight": 82.7 + }, + { + "mood": 4, + "weight": 82.6 + }, + { + "mood": 1, + "weight": 82.6 + }, + { + "mood": 3, + "weight": 82.6 + }, + { + "mood": 5, + "weight": 82.5 + }, + { + "mood": 2, + "weight": 82.5 + }, + { + "mood": 4, + "weight": 82.4 + }, + { + "mood": 1, + "weight": 82.4 + }, + { + "mood": 3, + "weight": 82.4 + }, + { + "mood": 5, + "weight": 82.3 + }, + { + "mood": 4, + "weight": 82.2 + }, + { + "mood": 1, + "weight": 82.2 + }, + { + "mood": 3, + "weight": 82.2 + }, + { + "mood": 5, + "weight": 82.1 + }, + { + "mood": 2, + "weight": 82.1 + }, + { + "mood": 4, + "weight": 82 + }, + { + "mood": 1, + "weight": 82 + } + ], + "moodPulseCorrelation": null, + "moodPulseScatterData": [ + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 2, + "pulse": 61 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + }, + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 1, + "pulse": 60 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + } + ], + "medications": [ + { + "id": "", + "name": "Ramipril", + "dose": "5mg", + "category": "BLOOD_PRESSURE", + "categoryLabel": null, + "compliance7": 100, + "compliance30": 76, + "streak": 0, + "taken7": 6, + "skipped7": 0, + "missed7": 0 + }, + { + "id": "", + "name": "Vitamin D", + "dose": "1000 IU", + "category": "OTHER", + "categoryLabel": null, + "compliance7": 43, + "compliance30": 47, + "streak": 1, + "taken7": 3, + "skipped7": 0, + "missed7": 4 + } + ], + "alerts": [ + { + "level": "info", + "title": "BMI in overweight range", + "message": "Your BMI of 25.9 is in the overweight range. Regular exercise and a balanced diet can help." + }, + { + "level": "warning", + "title": "Blood pressure often outside target range", + "message": "Only 11% of your readings are within the target range." + }, + { + "level": "success", + "title": "Excellent compliance: Ramipril", + "message": "100% compliance over the last 7 days. Keep it up!" + }, + { + "level": "warning", + "title": "Low compliance: Vitamin D", + "message": "Your 7-day compliance for Vitamin D is only 43%. Regular intake is important." + } + ], + "hasProvider": true, + "dataSpanDays": 90, + "totalMeasurements": 541, + "revalidating": false, + "ai": { + "briefing": { + "available": false, + "reason": "user_disabled", + "onDeviceAllowed": false + }, + "statusText": { + "available": false, + "reason": "user_disabled", + "onDeviceAllowed": false + } + } + }, + "error": null + }, + "events": [ + { + "status": 200, + "action": null, + "meta": { + "cache.analytics.key_hash": 3572442229, + "cache.analytics.outcome": "hit" + }, + "warnings": null, + "error": null + } + ], + "effects": [] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.06-operator-off.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.06-operator-off.json.snap new file mode 100644 index 000000000..f9b98e98f --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.06-operator-off.json.snap @@ -0,0 +1,1274 @@ +{ + "status": 200, + "body": { + "data": { + "summaries": { + "WEIGHT": { + "count": 58, + "latest": 82, + "min": 82, + "max": 84.4, + "mean": 83.19, + "median": null, + "avg7": 82.11, + "avg30": 82.59, + "slope7": { + "slope": -0.039, + "direction": "down", + "confidence": 0.89 + }, + "slope30": { + "slope": -0.04, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 83.8, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_SYS": { + "count": 87, + "latest": 123, + "min": 123, + "max": 137, + "mean": 130.2, + "median": null, + "avg7": 131.14, + "avg30": 130.1, + "slope7": { + "slope": -1.107, + "direction": "down", + "confidence": 0.22 + }, + "slope30": { + "slope": 0.043, + "direction": "up", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 130.24, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_DIA": { + "count": 87, + "latest": 78, + "min": 78, + "max": 86, + "mean": 81.94, + "median": null, + "avg7": 81.43, + "avg30": 81.66, + "slope7": { + "slope": -0.5, + "direction": "down", + "confidence": 0.17 + }, + "slope30": { + "slope": -0.019, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": 82.03, + "avg30LastYear": null + }, + "PULSE": { + "count": 58, + "latest": 64, + "min": 64, + "max": 69, + "mean": 66.57, + "median": null, + "avg7": 66.14, + "avg30": 66.55, + "slope7": { + "slope": -0.357, + "direction": "down", + "confidence": 0.16 + }, + "slope30": { + "slope": -0.035, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": 66.59, + "avg30LastYear": null + }, + "BODY_FAT": { + "count": 8, + "latest": 24, + "min": 24, + "max": 25.1, + "mean": 24.61, + "median": null, + "avg7": 24, + "avg30": 24.33, + "slope7": null, + "slope30": { + "slope": -0.021, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 24.9, + "avg30LastYear": null + }, + "SLEEP_DURATION": { + "count": 81, + "latest": 12, + "min": 12, + "max": 240, + "mean": 98.64, + "median": null, + "avg7": 96.17, + "avg30": 98.64, + "slope7": { + "slope": -2.121, + "direction": "down", + "confidence": 0 + }, + "slope30": { + "slope": -0.379, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "ACTIVITY_STEPS": { + "count": 29, + "latest": 6000, + "min": 6000, + "max": 9833, + "mean": 7780.83, + "median": null, + "avg7": 7119, + "avg30": 7780.83, + "slope7": { + "slope": -373, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -34.049, + "direction": "down", + "confidence": 0.07 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "BLOOD_GLUCOSE": { + "count": 57, + "latest": 128, + "min": 92, + "max": 147, + "mean": 113.12, + "median": null, + "avg7": 112.76, + "avg30": 113.12, + "slope7": { + "slope": -1.064, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.113, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "OXYGEN_SATURATION": { + "count": 9, + "latest": 96, + "min": 96, + "max": 98, + "mean": 96.89, + "median": null, + "avg7": 96.86, + "avg30": 96.89, + "slope7": { + "slope": -0.036, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.016, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "HEART_RATE_VARIABILITY": { + "count": 29, + "latest": 45, + "min": 45, + "max": 52, + "mean": 48.17, + "median": null, + "avg7": 48, + "avg30": 48.17, + "slope7": { + "slope": -1, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -0.046, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "RESTING_HEART_RATE": { + "count": 38, + "latest": 58, + "min": 58, + "max": 61, + "mean": 59.45, + "median": null, + "avg7": 59.29, + "avg30": 59.38, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.08 + }, + "slope30": { + "slope": -0.009, + "direction": "stable", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 59.67, + "avg30LastYear": null + } + }, + "bmi": 25.9, + "bmiClassification": { + "category": "Overweight", + "color": "var(--warning)", + "severity": "warning" + }, + "bpClassification": { + "category": "High-normal", + "color": "var(--dracula-yellow)", + "severity": "elevated" + }, + "bpPctInTarget": 11, + "bpTargets": { + "sysLow": 120, + "sysHigh": 129, + "diaLow": 70, + "diaHigh": 79 + }, + "weightBpCorrelation": null, + "scatterData": [ + { + "weight": 84.4, + "sysBP": 131 + }, + { + "weight": 84.3, + "sysBP": 124 + }, + { + "weight": 84.3, + "sysBP": 132 + }, + { + "weight": 84.2, + "sysBP": 125 + }, + { + "weight": 84.2, + "sysBP": 133 + }, + { + "weight": 84.2, + "sysBP": 126 + }, + { + "weight": 84.1, + "sysBP": 134 + }, + { + "weight": 84.1, + "sysBP": 127 + }, + { + "weight": 84, + "sysBP": 135 + }, + { + "weight": 84, + "sysBP": 128 + }, + { + "weight": 84, + "sysBP": 136 + }, + { + "weight": 83.9, + "sysBP": 129 + }, + { + "weight": 83.9, + "sysBP": 137 + }, + { + "weight": 83.8, + "sysBP": 130 + }, + { + "weight": 83.8, + "sysBP": 123 + }, + { + "weight": 83.8, + "sysBP": 131 + }, + { + "weight": 83.7, + "sysBP": 124 + }, + { + "weight": 83.7, + "sysBP": 132 + }, + { + "weight": 83.6, + "sysBP": 125 + }, + { + "weight": 83.6, + "sysBP": 133 + }, + { + "weight": 83.6, + "sysBP": 126 + }, + { + "weight": 83.5, + "sysBP": 134 + }, + { + "weight": 83.5, + "sysBP": 127 + }, + { + "weight": 83.4, + "sysBP": 135 + }, + { + "weight": 83.4, + "sysBP": 128 + }, + { + "weight": 83.4, + "sysBP": 136 + }, + { + "weight": 83.3, + "sysBP": 129 + }, + { + "weight": 83.3, + "sysBP": 137 + }, + { + "weight": 83.2, + "sysBP": 130 + }, + { + "weight": 83.2, + "sysBP": 131 + }, + { + "weight": 83.1, + "sysBP": 124 + }, + { + "weight": 83.1, + "sysBP": 132 + }, + { + "weight": 83, + "sysBP": 125 + }, + { + "weight": 83, + "sysBP": 133 + }, + { + "weight": 83, + "sysBP": 126 + }, + { + "weight": 82.9, + "sysBP": 134 + }, + { + "weight": 82.9, + "sysBP": 127 + }, + { + "weight": 82.8, + "sysBP": 135 + }, + { + "weight": 82.8, + "sysBP": 128 + }, + { + "weight": 82.8, + "sysBP": 136 + }, + { + "weight": 82.7, + "sysBP": 129 + }, + { + "weight": 82.7, + "sysBP": 137 + }, + { + "weight": 82.6, + "sysBP": 130 + }, + { + "weight": 82.6, + "sysBP": 123 + }, + { + "weight": 82.6, + "sysBP": 131 + }, + { + "weight": 82.5, + "sysBP": 124 + }, + { + "weight": 82.5, + "sysBP": 132 + }, + { + "weight": 82.4, + "sysBP": 125 + }, + { + "weight": 82.4, + "sysBP": 133 + }, + { + "weight": 82.4, + "sysBP": 126 + }, + { + "weight": 82.3, + "sysBP": 134 + }, + { + "weight": 82.2, + "sysBP": 135 + }, + { + "weight": 82.2, + "sysBP": 128 + }, + { + "weight": 82.2, + "sysBP": 136 + }, + { + "weight": 82.1, + "sysBP": 129 + }, + { + "weight": 82.1, + "sysBP": 137 + }, + { + "weight": 82, + "sysBP": 130 + }, + { + "weight": 82, + "sysBP": 123 + } + ], + "bpMedicationCorrelation": null, + "bpMedicationScatterData": [ + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 0, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 0, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 123 + }, + { + "continuityPct": 0, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + } + ], + "moodSummary": { + "count": 45, + "latest": 1, + "min": 1, + "max": 5, + "mean": 3, + "median": 3, + "avg7": 2.86, + "avg30": 3, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.04 + }, + "slope30": { + "slope": -0.013, + "direction": "down", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 3, + "avg30LastYear": null + }, + "moodBpCorrelation": null, + "moodBpScatterData": [ + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + } + ], + "moodWeightCorrelation": null, + "moodWeightScatterData": [ + { + "mood": 3, + "weight": 83.8 + }, + { + "mood": 5, + "weight": 83.7 + }, + { + "mood": 2, + "weight": 83.7 + }, + { + "mood": 4, + "weight": 83.6 + }, + { + "mood": 1, + "weight": 83.6 + }, + { + "mood": 3, + "weight": 83.6 + }, + { + "mood": 5, + "weight": 83.5 + }, + { + "mood": 2, + "weight": 83.5 + }, + { + "mood": 4, + "weight": 83.4 + }, + { + "mood": 1, + "weight": 83.4 + }, + { + "mood": 3, + "weight": 83.4 + }, + { + "mood": 5, + "weight": 83.3 + }, + { + "mood": 2, + "weight": 83.3 + }, + { + "mood": 4, + "weight": 83.2 + }, + { + "mood": 3, + "weight": 83.2 + }, + { + "mood": 5, + "weight": 83.1 + }, + { + "mood": 2, + "weight": 83.1 + }, + { + "mood": 4, + "weight": 83 + }, + { + "mood": 1, + "weight": 83 + }, + { + "mood": 3, + "weight": 83 + }, + { + "mood": 5, + "weight": 82.9 + }, + { + "mood": 2, + "weight": 82.9 + }, + { + "mood": 4, + "weight": 82.8 + }, + { + "mood": 1, + "weight": 82.8 + }, + { + "mood": 3, + "weight": 82.8 + }, + { + "mood": 5, + "weight": 82.7 + }, + { + "mood": 2, + "weight": 82.7 + }, + { + "mood": 4, + "weight": 82.6 + }, + { + "mood": 1, + "weight": 82.6 + }, + { + "mood": 3, + "weight": 82.6 + }, + { + "mood": 5, + "weight": 82.5 + }, + { + "mood": 2, + "weight": 82.5 + }, + { + "mood": 4, + "weight": 82.4 + }, + { + "mood": 1, + "weight": 82.4 + }, + { + "mood": 3, + "weight": 82.4 + }, + { + "mood": 5, + "weight": 82.3 + }, + { + "mood": 4, + "weight": 82.2 + }, + { + "mood": 1, + "weight": 82.2 + }, + { + "mood": 3, + "weight": 82.2 + }, + { + "mood": 5, + "weight": 82.1 + }, + { + "mood": 2, + "weight": 82.1 + }, + { + "mood": 4, + "weight": 82 + }, + { + "mood": 1, + "weight": 82 + } + ], + "moodPulseCorrelation": null, + "moodPulseScatterData": [ + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 2, + "pulse": 61 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + }, + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 1, + "pulse": 60 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + } + ], + "medications": [ + { + "id": "", + "name": "Ramipril", + "dose": "5mg", + "category": "BLOOD_PRESSURE", + "categoryLabel": null, + "compliance7": 100, + "compliance30": 76, + "streak": 0, + "taken7": 6, + "skipped7": 0, + "missed7": 0 + }, + { + "id": "", + "name": "Vitamin D", + "dose": "1000 IU", + "category": "OTHER", + "categoryLabel": null, + "compliance7": 43, + "compliance30": 47, + "streak": 1, + "taken7": 3, + "skipped7": 0, + "missed7": 4 + } + ], + "alerts": [ + { + "level": "info", + "title": "BMI in overweight range", + "message": "Your BMI of 25.9 is in the overweight range. Regular exercise and a balanced diet can help." + }, + { + "level": "warning", + "title": "Blood pressure often outside target range", + "message": "Only 11% of your readings are within the target range." + }, + { + "level": "success", + "title": "Excellent compliance: Ramipril", + "message": "100% compliance over the last 7 days. Keep it up!" + }, + { + "level": "warning", + "title": "Low compliance: Vitamin D", + "message": "Your 7-day compliance for Vitamin D is only 43%. Regular intake is important." + } + ], + "hasProvider": true, + "dataSpanDays": 90, + "totalMeasurements": 541, + "revalidating": false, + "ai": { + "briefing": { + "available": false, + "reason": "operator_disabled", + "onDeviceAllowed": false + }, + "statusText": { + "available": false, + "reason": "operator_disabled", + "onDeviceAllowed": false + } + } + }, + "error": null + }, + "events": [ + { + "status": 200, + "action": null, + "meta": { + "cache.analytics.key_hash": 3572442229, + "cache.analytics.outcome": "hit" + }, + "warnings": null, + "error": null + } + ], + "effects": [] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.07-manage-delegate.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.07-manage-delegate.json.snap new file mode 100644 index 000000000..06218e2c0 --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.07-manage-delegate.json.snap @@ -0,0 +1,1303 @@ +{ + "status": 200, + "body": { + "data": { + "summaries": { + "WEIGHT": { + "count": 58, + "latest": 82, + "min": 82, + "max": 84.4, + "mean": 83.19, + "median": null, + "avg7": 82.11, + "avg30": 82.59, + "slope7": { + "slope": -0.039, + "direction": "down", + "confidence": 0.89 + }, + "slope30": { + "slope": -0.04, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 83.8, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_SYS": { + "count": 87, + "latest": 123, + "min": 123, + "max": 137, + "mean": 130.2, + "median": null, + "avg7": 131.14, + "avg30": 130.1, + "slope7": { + "slope": -1.107, + "direction": "down", + "confidence": 0.22 + }, + "slope30": { + "slope": 0.043, + "direction": "up", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 130.24, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_DIA": { + "count": 87, + "latest": 78, + "min": 78, + "max": 86, + "mean": 81.94, + "median": null, + "avg7": 81.43, + "avg30": 81.66, + "slope7": { + "slope": -0.5, + "direction": "down", + "confidence": 0.17 + }, + "slope30": { + "slope": -0.019, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": 82.03, + "avg30LastYear": null + }, + "PULSE": { + "count": 58, + "latest": 64, + "min": 64, + "max": 69, + "mean": 66.57, + "median": null, + "avg7": 66.14, + "avg30": 66.55, + "slope7": { + "slope": -0.357, + "direction": "down", + "confidence": 0.16 + }, + "slope30": { + "slope": -0.035, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": 66.59, + "avg30LastYear": null + }, + "BODY_FAT": { + "count": 8, + "latest": 24, + "min": 24, + "max": 25.1, + "mean": 24.61, + "median": null, + "avg7": 24, + "avg30": 24.33, + "slope7": null, + "slope30": { + "slope": -0.021, + "direction": "down", + "confidence": 0.99 + }, + "anomalyCount": 0, + "avg30LastMonth": 24.9, + "avg30LastYear": null + }, + "SLEEP_DURATION": { + "count": 81, + "latest": 12, + "min": 12, + "max": 240, + "mean": 98.64, + "median": null, + "avg7": 96.17, + "avg30": 98.64, + "slope7": { + "slope": -2.121, + "direction": "down", + "confidence": 0 + }, + "slope30": { + "slope": -0.379, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "ACTIVITY_STEPS": { + "count": 29, + "latest": 6000, + "min": 6000, + "max": 9833, + "mean": 7780.83, + "median": null, + "avg7": 7119, + "avg30": 7780.83, + "slope7": { + "slope": -373, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -34.049, + "direction": "down", + "confidence": 0.07 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "BLOOD_GLUCOSE": { + "count": 57, + "latest": 128, + "min": 92, + "max": 147, + "mean": 113.12, + "median": null, + "avg7": 112.76, + "avg30": 113.12, + "slope7": { + "slope": -1.064, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.113, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "OXYGEN_SATURATION": { + "count": 9, + "latest": 96, + "min": 96, + "max": 98, + "mean": 96.89, + "median": null, + "avg7": 96.86, + "avg30": 96.89, + "slope7": { + "slope": -0.036, + "direction": "down", + "confidence": 0.01 + }, + "slope30": { + "slope": -0.016, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "HEART_RATE_VARIABILITY": { + "count": 29, + "latest": 45, + "min": 45, + "max": 52, + "mean": 48.17, + "median": null, + "avg7": 48, + "avg30": 48.17, + "slope7": { + "slope": -1, + "direction": "down", + "confidence": 1 + }, + "slope30": { + "slope": -0.046, + "direction": "down", + "confidence": 0.03 + }, + "anomalyCount": 0, + "avg30LastMonth": null, + "avg30LastYear": null + }, + "RESTING_HEART_RATE": { + "count": 38, + "latest": 58, + "min": 58, + "max": 61, + "mean": 59.45, + "median": null, + "avg7": 59.29, + "avg30": 59.38, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.08 + }, + "slope30": { + "slope": -0.009, + "direction": "stable", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 59.67, + "avg30LastYear": null + } + }, + "bmi": 25.9, + "bmiClassification": { + "category": "Overweight", + "color": "var(--warning)", + "severity": "warning" + }, + "bpClassification": { + "category": "High-normal", + "color": "var(--dracula-yellow)", + "severity": "elevated" + }, + "bpPctInTarget": 11, + "bpTargets": { + "sysLow": 120, + "sysHigh": 129, + "diaLow": 70, + "diaHigh": 79 + }, + "weightBpCorrelation": null, + "scatterData": [ + { + "weight": 84.4, + "sysBP": 131 + }, + { + "weight": 84.3, + "sysBP": 124 + }, + { + "weight": 84.3, + "sysBP": 132 + }, + { + "weight": 84.2, + "sysBP": 125 + }, + { + "weight": 84.2, + "sysBP": 133 + }, + { + "weight": 84.2, + "sysBP": 126 + }, + { + "weight": 84.1, + "sysBP": 134 + }, + { + "weight": 84.1, + "sysBP": 127 + }, + { + "weight": 84, + "sysBP": 135 + }, + { + "weight": 84, + "sysBP": 128 + }, + { + "weight": 84, + "sysBP": 136 + }, + { + "weight": 83.9, + "sysBP": 129 + }, + { + "weight": 83.9, + "sysBP": 137 + }, + { + "weight": 83.8, + "sysBP": 130 + }, + { + "weight": 83.8, + "sysBP": 123 + }, + { + "weight": 83.8, + "sysBP": 131 + }, + { + "weight": 83.7, + "sysBP": 124 + }, + { + "weight": 83.7, + "sysBP": 132 + }, + { + "weight": 83.6, + "sysBP": 125 + }, + { + "weight": 83.6, + "sysBP": 133 + }, + { + "weight": 83.6, + "sysBP": 126 + }, + { + "weight": 83.5, + "sysBP": 134 + }, + { + "weight": 83.5, + "sysBP": 127 + }, + { + "weight": 83.4, + "sysBP": 135 + }, + { + "weight": 83.4, + "sysBP": 128 + }, + { + "weight": 83.4, + "sysBP": 136 + }, + { + "weight": 83.3, + "sysBP": 129 + }, + { + "weight": 83.3, + "sysBP": 137 + }, + { + "weight": 83.2, + "sysBP": 130 + }, + { + "weight": 83.2, + "sysBP": 131 + }, + { + "weight": 83.1, + "sysBP": 124 + }, + { + "weight": 83.1, + "sysBP": 132 + }, + { + "weight": 83, + "sysBP": 125 + }, + { + "weight": 83, + "sysBP": 133 + }, + { + "weight": 83, + "sysBP": 126 + }, + { + "weight": 82.9, + "sysBP": 134 + }, + { + "weight": 82.9, + "sysBP": 127 + }, + { + "weight": 82.8, + "sysBP": 135 + }, + { + "weight": 82.8, + "sysBP": 128 + }, + { + "weight": 82.8, + "sysBP": 136 + }, + { + "weight": 82.7, + "sysBP": 129 + }, + { + "weight": 82.7, + "sysBP": 137 + }, + { + "weight": 82.6, + "sysBP": 130 + }, + { + "weight": 82.6, + "sysBP": 123 + }, + { + "weight": 82.6, + "sysBP": 131 + }, + { + "weight": 82.5, + "sysBP": 124 + }, + { + "weight": 82.5, + "sysBP": 132 + }, + { + "weight": 82.4, + "sysBP": 125 + }, + { + "weight": 82.4, + "sysBP": 133 + }, + { + "weight": 82.4, + "sysBP": 126 + }, + { + "weight": 82.3, + "sysBP": 134 + }, + { + "weight": 82.2, + "sysBP": 135 + }, + { + "weight": 82.2, + "sysBP": 128 + }, + { + "weight": 82.2, + "sysBP": 136 + }, + { + "weight": 82.1, + "sysBP": 129 + }, + { + "weight": 82.1, + "sysBP": 137 + }, + { + "weight": 82, + "sysBP": 130 + }, + { + "weight": 82, + "sysBP": 123 + } + ], + "bpMedicationCorrelation": null, + "bpMedicationScatterData": [ + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 0, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 0, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 126 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 127 + }, + { + "continuityPct": 0, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + }, + { + "continuityPct": 100, + "sysBP": 123 + }, + { + "continuityPct": 0, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 124 + }, + { + "continuityPct": 100, + "sysBP": 132 + }, + { + "continuityPct": 100, + "sysBP": 125 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 128 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 129 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 130 + } + ], + "moodSummary": { + "count": 45, + "latest": 1, + "min": 1, + "max": 5, + "mean": 3, + "median": 3, + "avg7": 2.86, + "avg30": 3, + "slope7": { + "slope": -0.143, + "direction": "down", + "confidence": 0.04 + }, + "slope30": { + "slope": -0.013, + "direction": "down", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 3, + "avg30LastYear": null + }, + "moodBpCorrelation": null, + "moodBpScatterData": [ + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 2, + "sysBP": 127 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 5, + "sysBP": 124 + }, + { + "mood": 2, + "sysBP": 132 + }, + { + "mood": 4, + "sysBP": 125 + }, + { + "mood": 1, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 126 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 4, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 128 + }, + { + "mood": 3, + "sysBP": 136 + }, + { + "mood": 5, + "sysBP": 129 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 4, + "sysBP": 130 + }, + { + "mood": 1, + "sysBP": 123 + } + ], + "moodWeightCorrelation": null, + "moodWeightScatterData": [ + { + "mood": 3, + "weight": 83.8 + }, + { + "mood": 5, + "weight": 83.7 + }, + { + "mood": 2, + "weight": 83.7 + }, + { + "mood": 4, + "weight": 83.6 + }, + { + "mood": 1, + "weight": 83.6 + }, + { + "mood": 3, + "weight": 83.6 + }, + { + "mood": 5, + "weight": 83.5 + }, + { + "mood": 2, + "weight": 83.5 + }, + { + "mood": 4, + "weight": 83.4 + }, + { + "mood": 1, + "weight": 83.4 + }, + { + "mood": 3, + "weight": 83.4 + }, + { + "mood": 5, + "weight": 83.3 + }, + { + "mood": 2, + "weight": 83.3 + }, + { + "mood": 4, + "weight": 83.2 + }, + { + "mood": 3, + "weight": 83.2 + }, + { + "mood": 5, + "weight": 83.1 + }, + { + "mood": 2, + "weight": 83.1 + }, + { + "mood": 4, + "weight": 83 + }, + { + "mood": 1, + "weight": 83 + }, + { + "mood": 3, + "weight": 83 + }, + { + "mood": 5, + "weight": 82.9 + }, + { + "mood": 2, + "weight": 82.9 + }, + { + "mood": 4, + "weight": 82.8 + }, + { + "mood": 1, + "weight": 82.8 + }, + { + "mood": 3, + "weight": 82.8 + }, + { + "mood": 5, + "weight": 82.7 + }, + { + "mood": 2, + "weight": 82.7 + }, + { + "mood": 4, + "weight": 82.6 + }, + { + "mood": 1, + "weight": 82.6 + }, + { + "mood": 3, + "weight": 82.6 + }, + { + "mood": 5, + "weight": 82.5 + }, + { + "mood": 2, + "weight": 82.5 + }, + { + "mood": 4, + "weight": 82.4 + }, + { + "mood": 1, + "weight": 82.4 + }, + { + "mood": 3, + "weight": 82.4 + }, + { + "mood": 5, + "weight": 82.3 + }, + { + "mood": 4, + "weight": 82.2 + }, + { + "mood": 1, + "weight": 82.2 + }, + { + "mood": 3, + "weight": 82.2 + }, + { + "mood": 5, + "weight": 82.1 + }, + { + "mood": 2, + "weight": 82.1 + }, + { + "mood": 4, + "weight": 82 + }, + { + "mood": 1, + "weight": 82 + } + ], + "moodPulseCorrelation": null, + "moodPulseScatterData": [ + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 2, + "pulse": 61 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + }, + { + "mood": 3, + "pulse": 61 + }, + { + "mood": 5, + "pulse": 60 + }, + { + "mood": 2, + "pulse": 59 + }, + { + "mood": 4, + "pulse": 58 + }, + { + "mood": 1, + "pulse": 61 + }, + { + "mood": 3, + "pulse": 60 + }, + { + "mood": 5, + "pulse": 59 + }, + { + "mood": 2, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 61 + }, + { + "mood": 1, + "pulse": 60 + }, + { + "mood": 3, + "pulse": 59 + }, + { + "mood": 5, + "pulse": 58 + }, + { + "mood": 4, + "pulse": 60 + }, + { + "mood": 1, + "pulse": 59 + }, + { + "mood": 3, + "pulse": 58 + }, + { + "mood": 5, + "pulse": 61 + }, + { + "mood": 2, + "pulse": 60 + }, + { + "mood": 4, + "pulse": 59 + }, + { + "mood": 1, + "pulse": 58 + } + ], + "medications": [ + { + "id": "", + "name": "Ramipril", + "dose": "5mg", + "category": "BLOOD_PRESSURE", + "categoryLabel": null, + "compliance7": 100, + "compliance30": 76, + "streak": 0, + "taken7": 6, + "skipped7": 0, + "missed7": 0 + }, + { + "id": "", + "name": "Vitamin D", + "dose": "1000 IU", + "category": "OTHER", + "categoryLabel": null, + "compliance7": 43, + "compliance30": 47, + "streak": 1, + "taken7": 3, + "skipped7": 0, + "missed7": 4 + } + ], + "alerts": [ + { + "level": "info", + "title": "BMI in overweight range", + "message": "Your BMI of 25.9 is in the overweight range. Regular exercise and a balanced diet can help." + }, + { + "level": "warning", + "title": "Blood pressure often outside target range", + "message": "Only 11% of your readings are within the target range." + }, + { + "level": "success", + "title": "Excellent compliance: Ramipril", + "message": "100% compliance over the last 7 days. Keep it up!" + }, + { + "level": "warning", + "title": "Low compliance: Vitamin D", + "message": "Your 7-day compliance for Vitamin D is only 43%. Regular intake is important." + } + ], + "hasProvider": false, + "dataSpanDays": 90, + "totalMeasurements": 541, + "revalidating": false, + "ai": { + "briefing": { + "available": true, + "reason": null, + "onDeviceAllowed": true + }, + "statusText": { + "available": true, + "reason": null, + "onDeviceAllowed": true + } + } + }, + "error": null + }, + "events": [ + { + "status": 200, + "action": { + "name": "insights.comprehensive" + }, + "meta": { + "cache.analytics.key_hash": 3572442229, + "cache.analytics.outcome": "miss", + "insights": { + "slope_source": "rollup", + "anomaly_source": "live", + "regression_source": "rollup" + }, + "insights.sub_bpRaw_ms": "", + "insights.sub_buckets_ms": "", + "insights.sub_coverage_ms": "", + "insights.sub_firstAt_ms": "", + "insights.sub_latests_ms": "", + "insights.sub_narrow_ms": "", + "medications": 2, + "moodEntries": 45, + "totalMeasurements": 541 + }, + "warnings": null, + "error": null + } + ], + "effects": [ + { + "effect": "ensureUserRollupsFresh", + "args": [ + "" + ] + }, + { + "effect": "ensureUserMoodRollupsFresh", + "args": [ + "" + ] + } + ] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.08-read-delegate.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.08-read-delegate.json.snap new file mode 100644 index 000000000..b4e2a65a9 --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.08-read-delegate.json.snap @@ -0,0 +1,26 @@ +{ + "status": 403, + "body": { + "data": null, + "error": "Account access denied", + "meta": { + "errorCode": "sharing.access.denied", + "requestId": "" + } + }, + "events": [ + { + "status": 403, + "action": null, + "meta": { + "sharing_refusal": "insufficient_access" + }, + "warnings": null, + "error": { + "type": "SharingAccessDeniedError", + "message": "Account access denied" + } + } + ], + "effects": [] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.09-rate-limited.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.09-rate-limited.json.snap new file mode 100644 index 000000000..6f6b705b2 --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.09-rate-limited.json.snap @@ -0,0 +1,21 @@ +{ + "status": 429, + "body": { + "data": null, + "error": "Too many analytics requests. Please retry later.", + "meta": { + "errorCode": "http.rate_limited", + "requestId": "" + } + }, + "events": [ + { + "status": 429, + "action": null, + "meta": null, + "warnings": null, + "error": null + } + ], + "effects": [] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.10-sparse.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.10-sparse.json.snap new file mode 100644 index 000000000..d2362f2ef --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.10-sparse.json.snap @@ -0,0 +1,884 @@ +{ + "status": 200, + "body": { + "data": { + "summaries": { + "WEIGHT": { + "count": 47, + "latest": 70.3, + "min": 70, + "max": 71.2, + "mean": 70.63, + "median": null, + "avg7": 70.55, + "avg30": 70.62, + "slope7": { + "slope": 0.043, + "direction": "up", + "confidence": 0.03 + }, + "slope30": { + "slope": -0.004, + "direction": "stable", + "confidence": 0.01 + }, + "anomalyCount": 0, + "avg30LastMonth": 70.63, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_SYS": { + "count": 47, + "latest": 134, + "min": 131, + "max": 163, + "mean": 139.66, + "median": null, + "avg7": 139.67, + "avg30": 139.93, + "slope7": { + "slope": -2.057, + "direction": "down", + "confidence": 0.18 + }, + "slope30": { + "slope": -0.03, + "direction": "down", + "confidence": 0 + }, + "anomalyCount": 4, + "avg30LastMonth": 139.26, + "avg30LastYear": null + }, + "BLOOD_PRESSURE_DIA": { + "count": 47, + "latest": 86, + "min": 84, + "max": 90, + "mean": 87.04, + "median": null, + "avg7": 87.5, + "avg30": 87.07, + "slope7": { + "slope": -0.2, + "direction": "down", + "confidence": 0.04 + }, + "slope30": { + "slope": 0.034, + "direction": "up", + "confidence": 0.02 + }, + "anomalyCount": 0, + "avg30LastMonth": 87, + "avg30LastYear": null + }, + "PULSE": { + "count": 141, + "latest": 93, + "min": 66, + "max": 96, + "mean": 81.67, + "median": null, + "avg7": 81.61, + "avg30": 81.61, + "slope7": { + "slope": 0.186, + "direction": "up", + "confidence": 0 + }, + "slope30": { + "slope": 0.027, + "direction": "up", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": 81.75, + "avg30LastYear": null + } + }, + "bmi": null, + "bmiClassification": null, + "bpClassification": { + "category": "High-normal", + "color": "var(--dracula-yellow)", + "severity": "elevated" + }, + "bpPctInTarget": 0, + "bpTargets": { + "sysLow": 130, + "sysHigh": 139, + "diaLow": 70, + "diaHigh": 79 + }, + "weightBpCorrelation": { + "r": -0.631, + "strength": "moderat", + "n": 47 + }, + "scatterData": [ + { + "weight": 71.2, + "sysBP": 135 + }, + { + "weight": 70.9, + "sysBP": 132 + }, + { + "weight": 70.6, + "sysBP": 140 + }, + { + "weight": 70.3, + "sysBP": 137 + }, + { + "weight": 70, + "sysBP": 156 + }, + { + "weight": 71.2, + "sysBP": 131 + }, + { + "weight": 70.9, + "sysBP": 139 + }, + { + "weight": 70.6, + "sysBP": 136 + }, + { + "weight": 70.3, + "sysBP": 133 + }, + { + "weight": 70, + "sysBP": 163 + }, + { + "weight": 71.2, + "sysBP": 138 + }, + { + "weight": 70.9, + "sysBP": 135 + }, + { + "weight": 70.6, + "sysBP": 132 + }, + { + "weight": 70.3, + "sysBP": 140 + }, + { + "weight": 70, + "sysBP": 159 + }, + { + "weight": 71.2, + "sysBP": 134 + }, + { + "weight": 70.9, + "sysBP": 131 + }, + { + "weight": 70.6, + "sysBP": 139 + }, + { + "weight": 70.3, + "sysBP": 136 + }, + { + "weight": 71.2, + "sysBP": 141 + }, + { + "weight": 70.9, + "sysBP": 138 + }, + { + "weight": 70.6, + "sysBP": 135 + }, + { + "weight": 70.3, + "sysBP": 132 + }, + { + "weight": 70, + "sysBP": 162 + }, + { + "weight": 71.2, + "sysBP": 137 + }, + { + "weight": 70.9, + "sysBP": 134 + }, + { + "weight": 70.6, + "sysBP": 131 + }, + { + "weight": 70.3, + "sysBP": 139 + }, + { + "weight": 70, + "sysBP": 158 + }, + { + "weight": 71.2, + "sysBP": 133 + }, + { + "weight": 70.9, + "sysBP": 141 + }, + { + "weight": 70.6, + "sysBP": 138 + }, + { + "weight": 70.3, + "sysBP": 135 + }, + { + "weight": 70, + "sysBP": 154 + }, + { + "weight": 71.2, + "sysBP": 140 + }, + { + "weight": 70.9, + "sysBP": 137 + }, + { + "weight": 70.6, + "sysBP": 134 + }, + { + "weight": 70.3, + "sysBP": 131 + }, + { + "weight": 70, + "sysBP": 161 + }, + { + "weight": 71.2, + "sysBP": 136 + }, + { + "weight": 70.9, + "sysBP": 133 + }, + { + "weight": 70.3, + "sysBP": 138 + }, + { + "weight": 70, + "sysBP": 157 + }, + { + "weight": 71.2, + "sysBP": 132 + }, + { + "weight": 70.9, + "sysBP": 140 + }, + { + "weight": 70.6, + "sysBP": 137 + }, + { + "weight": 70.3, + "sysBP": 134 + } + ], + "bpMedicationCorrelation": { + "r": -0.941, + "strength": "stark", + "n": 28, + "medicationCount": 1 + }, + "bpMedicationScatterData": [ + { + "continuityPct": 100, + "sysBP": 138 + }, + { + "continuityPct": 100, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 132 + }, + { + "continuityPct": 0, + "sysBP": 159 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 141 + }, + { + "continuityPct": 100, + "sysBP": 135 + }, + { + "continuityPct": 100, + "sysBP": 132 + }, + { + "continuityPct": 0, + "sysBP": 162 + }, + { + "continuityPct": 100, + "sysBP": 134 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 100, + "sysBP": 139 + }, + { + "continuityPct": 100, + "sysBP": 133 + }, + { + "continuityPct": 100, + "sysBP": 141 + }, + { + "continuityPct": 100, + "sysBP": 138 + }, + { + "continuityPct": 0, + "sysBP": 154 + }, + { + "continuityPct": 100, + "sysBP": 140 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 131 + }, + { + "continuityPct": 0, + "sysBP": 161 + }, + { + "continuityPct": 100, + "sysBP": 136 + }, + { + "continuityPct": 100, + "sysBP": 138 + }, + { + "continuityPct": 0, + "sysBP": 157 + }, + { + "continuityPct": 100, + "sysBP": 140 + }, + { + "continuityPct": 100, + "sysBP": 137 + }, + { + "continuityPct": 100, + "sysBP": 134 + } + ], + "moodSummary": { + "count": 29, + "latest": 3, + "min": 1, + "max": 5, + "mean": 3.07, + "median": 3, + "avg7": 3, + "avg30": 3.04, + "slope7": { + "slope": 0.286, + "direction": "up", + "confidence": 0.14 + }, + "slope30": { + "slope": 0, + "direction": "stable", + "confidence": 0 + }, + "anomalyCount": 0, + "avg30LastMonth": 4, + "avg30LastYear": null + }, + "moodBpCorrelation": { + "r": -0.683, + "strength": "moderat", + "n": 28 + }, + "moodBpScatterData": [ + { + "mood": 4, + "sysBP": 141 + }, + { + "mood": 2, + "sysBP": 138 + }, + { + "mood": 5, + "sysBP": 135 + }, + { + "mood": 3, + "sysBP": 132 + }, + { + "mood": 1, + "sysBP": 162 + }, + { + "mood": 4, + "sysBP": 137 + }, + { + "mood": 2, + "sysBP": 134 + }, + { + "mood": 5, + "sysBP": 131 + }, + { + "mood": 3, + "sysBP": 139 + }, + { + "mood": 1, + "sysBP": 158 + }, + { + "mood": 4, + "sysBP": 133 + }, + { + "mood": 2, + "sysBP": 141 + }, + { + "mood": 5, + "sysBP": 138 + }, + { + "mood": 3, + "sysBP": 135 + }, + { + "mood": 1, + "sysBP": 154 + }, + { + "mood": 4, + "sysBP": 140 + }, + { + "mood": 2, + "sysBP": 137 + }, + { + "mood": 5, + "sysBP": 134 + }, + { + "mood": 3, + "sysBP": 131 + }, + { + "mood": 1, + "sysBP": 161 + }, + { + "mood": 4, + "sysBP": 136 + }, + { + "mood": 2, + "sysBP": 133 + }, + { + "mood": 3, + "sysBP": 138 + }, + { + "mood": 1, + "sysBP": 157 + }, + { + "mood": 4, + "sysBP": 132 + }, + { + "mood": 2, + "sysBP": 140 + }, + { + "mood": 5, + "sysBP": 137 + }, + { + "mood": 3, + "sysBP": 134 + } + ], + "moodWeightCorrelation": { + "r": 0.482, + "strength": "moderat", + "n": 28 + }, + "moodWeightScatterData": [ + { + "mood": 4, + "weight": 71.2 + }, + { + "mood": 2, + "weight": 70.9 + }, + { + "mood": 5, + "weight": 70.6 + }, + { + "mood": 3, + "weight": 70.3 + }, + { + "mood": 1, + "weight": 70 + }, + { + "mood": 4, + "weight": 71.2 + }, + { + "mood": 2, + "weight": 70.9 + }, + { + "mood": 5, + "weight": 70.6 + }, + { + "mood": 3, + "weight": 70.3 + }, + { + "mood": 1, + "weight": 70 + }, + { + "mood": 4, + "weight": 71.2 + }, + { + "mood": 2, + "weight": 70.9 + }, + { + "mood": 5, + "weight": 70.6 + }, + { + "mood": 3, + "weight": 70.3 + }, + { + "mood": 1, + "weight": 70 + }, + { + "mood": 4, + "weight": 71.2 + }, + { + "mood": 2, + "weight": 70.9 + }, + { + "mood": 5, + "weight": 70.6 + }, + { + "mood": 3, + "weight": 70.3 + }, + { + "mood": 1, + "weight": 70 + }, + { + "mood": 4, + "weight": 71.2 + }, + { + "mood": 2, + "weight": 70.9 + }, + { + "mood": 3, + "weight": 70.3 + }, + { + "mood": 1, + "weight": 70 + }, + { + "mood": 4, + "weight": 71.2 + }, + { + "mood": 2, + "weight": 70.9 + }, + { + "mood": 5, + "weight": 70.6 + }, + { + "mood": 3, + "weight": 70.3 + } + ], + "moodPulseCorrelation": null, + "moodPulseScatterData": [ + { + "mood": 2, + "pulse": 72 + }, + { + "mood": 5, + "pulse": 71 + }, + { + "mood": 3, + "pulse": 78 + }, + { + "mood": 1, + "pulse": 77 + }, + { + "mood": 4, + "pulse": 76 + }, + { + "mood": 2, + "pulse": 75 + }, + { + "mood": 5, + "pulse": 74 + }, + { + "mood": 3, + "pulse": 73 + }, + { + "mood": 1, + "pulse": 72 + }, + { + "mood": 4, + "pulse": 74 + }, + { + "mood": 2, + "pulse": 73 + }, + { + "mood": 5, + "pulse": 77 + }, + { + "mood": 3, + "pulse": 76 + }, + { + "mood": 1, + "pulse": 75 + }, + { + "mood": 4, + "pulse": 74 + }, + { + "mood": 2, + "pulse": 73 + }, + { + "mood": 5, + "pulse": 75 + }, + { + "mood": 3, + "pulse": 74 + }, + { + "mood": 1, + "pulse": 73 + }, + { + "mood": 4, + "pulse": 72 + }, + { + "mood": 2, + "pulse": 76 + }, + { + "mood": 1, + "pulse": 76 + }, + { + "mood": 4, + "pulse": 75 + }, + { + "mood": 2, + "pulse": 74 + }, + { + "mood": 5, + "pulse": 73 + }, + { + "mood": 3, + "pulse": 72 + } + ], + "medications": [ + { + "id": "", + "name": "Amlodipine", + "dose": "5mg", + "category": "BLOOD_PRESSURE", + "categoryLabel": null, + "compliance7": 67, + "compliance30": 65, + "streak": 4, + "taken7": 4, + "skipped7": 1, + "missed7": 2 + } + ], + "alerts": [ + { + "level": "warning", + "title": "Blood pressure often outside target range", + "message": "Only 0% of your readings are within the target range." + }, + { + "level": "warning", + "title": "Low compliance: Amlodipine", + "message": "Your 7-day compliance for Amlodipine is only 67%. Regular intake is important." + } + ], + "hasProvider": false, + "dataSpanDays": 50, + "totalMeasurements": 282, + "revalidating": false, + "ai": { + "briefing": { + "available": false, + "reason": "no_provider", + "onDeviceAllowed": true + }, + "statusText": { + "available": false, + "reason": "no_provider", + "onDeviceAllowed": true + } + } + }, + "error": null + }, + "events": [ + { + "status": 200, + "action": { + "name": "insights.comprehensive" + }, + "meta": { + "cache.analytics.key_hash": 2016842294, + "cache.analytics.outcome": "miss", + "insights": { + "slope_source": "rollup", + "anomaly_source": "live", + "regression_source": "rollup" + }, + "insights.sub_bpRaw_ms": "", + "insights.sub_buckets_ms": "", + "insights.sub_coverage_ms": "", + "insights.sub_firstAt_ms": "", + "insights.sub_latests_ms": "", + "insights.sub_narrow_ms": "", + "medications": 1, + "moodEntries": 29, + "totalMeasurements": 282 + }, + "warnings": null, + "error": null + } + ], + "effects": [ + { + "effect": "ensureUserRollupsFresh", + "args": [ + "" + ] + }, + { + "effect": "ensureUserMoodRollupsFresh", + "args": [ + "" + ] + } + ] +} diff --git a/tests/integration/routes/parity/__snapshots__/insights-comprehensive.11-empty.json.snap b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.11-empty.json.snap new file mode 100644 index 000000000..ecaa73274 --- /dev/null +++ b/tests/integration/routes/parity/__snapshots__/insights-comprehensive.11-empty.json.snap @@ -0,0 +1,79 @@ +{ + "status": 200, + "body": { + "data": { + "summaries": {}, + "bmi": null, + "bmiClassification": null, + "bpClassification": null, + "bpPctInTarget": null, + "bpTargets": null, + "weightBpCorrelation": null, + "scatterData": [], + "bpMedicationCorrelation": null, + "bpMedicationScatterData": [], + "moodSummary": null, + "moodBpCorrelation": null, + "moodBpScatterData": [], + "moodWeightCorrelation": null, + "moodWeightScatterData": [], + "moodPulseCorrelation": null, + "moodPulseScatterData": [], + "medications": [], + "alerts": [], + "hasProvider": false, + "dataSpanDays": 0, + "totalMeasurements": 0, + "revalidating": false, + "ai": { + "briefing": { + "available": false, + "reason": "no_provider", + "onDeviceAllowed": true + }, + "statusText": { + "available": false, + "reason": "no_provider", + "onDeviceAllowed": true + } + } + }, + "error": null + }, + "events": [ + { + "status": 200, + "action": { + "name": "insights.comprehensive" + }, + "meta": { + "cache.analytics.key_hash": 461242359, + "cache.analytics.outcome": "miss", + "insights.sub_bpRaw_ms": "", + "insights.sub_buckets_ms": "", + "insights.sub_coverage_ms": "", + "insights.sub_heavy_ms": "", + "insights.sub_latests_ms": "", + "medications": 0, + "moodEntries": 0, + "totalMeasurements": 0 + }, + "warnings": null, + "error": null + } + ], + "effects": [ + { + "effect": "ensureUserRollupsFresh", + "args": [ + "" + ] + }, + { + "effect": "ensureUserMoodRollupsFresh", + "args": [ + "" + ] + } + ] +} diff --git a/tests/integration/routes/parity/insights-comprehensive.parity.test.ts b/tests/integration/routes/parity/insights-comprehensive.parity.test.ts new file mode 100644 index 000000000..1518d3c8b --- /dev/null +++ b/tests/integration/routes/parity/insights-comprehensive.parity.test.ts @@ -0,0 +1,471 @@ +/** + * Parity for `GET /api/insights/comprehensive` while the overview builder + * moves out of the route into `src/lib/insights/`. + * + * One account with a full record (see `record-fixture.ts`) walks through the + * cases the route tells apart, in order, each request seeing the cache the + * earlier ones filled: an anonymous call, the overview cold, warm, and stale + * after a measurement write (served while one rebuild runs behind it), the + * `ai` block after the AI analysis opt-out and after the operator's master + * switch (both off the cached body), a delegate with MANAGE access reading + * the record cold, one with READ access refused, and the shared analytics + * read ceiling. A second account in a zone west of UTC carries the sparse + * shapes: mood entries with no rollup tier behind them, pulse without a + * resting series, a medication with no schedule, an as-needed one, and no + * height. An account with no data closes the walk. + * + * The clock is pinned (`Date` only) to noon of the day the test runs. The + * aggregator cuts its 7-, 30- and 60-day windows in SQL against the + * database clock, which the pin cannot reach, so the record's measurements + * on exactly those days back are removed: a reading there would fall in or + * out of a window with the hour the test runs. Every instant and day key in + * the snapshot is written relative to the start of the day. + * + * The rollup refreshes the route starts and does not await are recorded + * instead of run; the record's rollups are built once before the walk. + */ +import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; + +import { GET } from "@/app/api/insights/comprehensive/route"; +import { __resetAllCachesForTests } from "@/lib/cache/server-cache"; +import { invalidateUserMeasurements } from "@/lib/cache/invalidate"; +import { settleBackgroundTasks } from "@/lib/logging/background-tasks"; + +import { anonymous, callRoute, type RouteAuth } from "../../../kit/call-route"; +import { + makeGrant, + makeSession, + makeUser, + type SessionFixture, +} from "../../../kit/factories"; +import { + effectRecorder, + eventFacts, + expectParity, + relativeToAnchor, + stable, + startOfUtcToday, + wideEventRecorder, +} from "../../../kit/parity"; +import { + getPrismaClient, + switchSessionTo, + truncateAllTables, +} from "../../setup"; +import { parityId, seedParityRecord } from "./record-fixture"; + +vi.mock("@/lib/logging/transports", async (importOriginal) => { + const actual = + await importOriginal(); + const { wideEventRecorder: recorder } = await import("../../../kit/parity"); + return { + ...actual, + emitIfSampled: (event: (typeof recorder.events)[number]) => { + recorder.events.push(event); + }, + }; +}); + +vi.mock("@/lib/rollups/measurement-rollups", async (importOriginal) => { + const actual = + await importOriginal(); + const { effectRecorder } = await import("../../../kit/parity"); + return { + ...actual, + ensureUserRollupsFresh: async (...args: unknown[]) => { + effectRecorder.record("ensureUserRollupsFresh", args); + }, + }; +}); + +vi.mock("@/lib/rollups/mood-rollups", async (importOriginal) => { + const actual = + await importOriginal(); + const { effectRecorder } = await import("../../../kit/parity"); + return { + ...actual, + ensureUserMoodRollupsFresh: async (...args: unknown[]) => { + effectRecorder.record("ensureUserMoodRollupsFresh", args); + }, + }; +}); + +const prisma = getPrismaClient(); +const DAY = 86_400_000; +const ANCHOR = startOfUtcToday(); +const NOW = new Date(ANCHOR.getTime() + 12 * 60 * 60 * 1000); +/** Days back on which a SQL window edge falls (see the header). */ +const EDGE_DAYS = [7, 30, 60]; + +const OWNER_ID = parityId("insightscomp", 1); +const SPARSE_ID = parityId("insightscomp", 2); +const EMPTY_ID = parityId("insightscomp", 3); +const MANAGER_ID = parityId("insightscomp", 4); +const READER_ID = parityId("insightscomp", 5); + +let owner: SessionFixture; +let sparse: RouteAuth; +let empty: RouteAuth; +let manager: SessionFixture; +let reader: SessionFixture; + +/** + * Keys of the aggregator's per-phase timings, which the clock and the load + * decide. Their presence is kept, their value is not. + */ +function timingKeys(value: unknown, out = new Set()): Set { + if (Array.isArray(value)) value.forEach((v) => timingKeys(v, out)); + else if (value && typeof value === "object") { + for (const [k, v] of Object.entries(value)) { + if (/_ms$/.test(k)) out.add(k); + timingKeys(v, out); + } + } + return out; +} + +/** + * A stale serve starts one rebuild and returns without waiting for it. The + * rebuild annotates the request's event too, and whether it gets there before + * the event is emitted is a race between two sets of queries. On that case + * only the cache outcome is kept, which the route decides alone. + */ +function cacheFactsOnly(facts: unknown): unknown { + const f = facts as { meta?: Record | null }; + const meta = Object.fromEntries( + Object.entries(f.meta ?? {}).filter(([k]) => k.startsWith("cache.")), + ); + return { ...f, action: "", meta }; +} + +/** + * The aggregator's sub-queries run in parallel and annotate as each one + * finishes, so the order of their keys in the event follows the database, not + * the code. The keys are sorted; what they hold is unchanged. + */ +function sortedMeta(facts: unknown): unknown { + const f = facts as { meta?: Record | null }; + if (!f.meta) return facts; + const meta = Object.fromEntries( + Object.entries(f.meta).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)), + ); + return { ...f, meta }; +} + +async function step( + name: string, + options: { auth?: RouteAuth; raced?: boolean } = {}, +): Promise { + wideEventRecorder.take(); + effectRecorder.take(); + const res = await callRoute(GET, { + method: "GET", + route: "/api/insights/comprehensive", + auth: options.auth ?? owner, + }); + // A stale serve leaves one rebuild running; it finishes before the + // snapshot so the next case starts from the same cache. + await settleBackgroundTasks(); + const events = wideEventRecorder.take(); + expect(events.length).toBeGreaterThan(0); + const facts = events + .map(eventFacts) + .map(sortedMeta) + .map((f) => (options.raced ? cacheFactsOnly(f) : f)); + await expectParity( + `insights-comprehensive.${name}`, + stable( + relativeToAnchor( + { + status: res.status, + body: res.body, + events: facts, + effects: effectRecorder.take(), + }, + ANCHOR, + ), + { since: NOW, volatileKeys: [...timingKeys(facts)] }, + ), + ); +} + +/** Remove the record's measurements on the SQL window edge days. */ +async function dropEdgeDays(userId: string): Promise { + for (const d of EDGE_DAYS) { + await prisma.measurement.deleteMany({ + where: { + userId, + measuredAt: { + gte: new Date(ANCHOR.getTime() - d * DAY), + lt: new Date(ANCHOR.getTime() - (d - 1) * DAY), + }, + }, + }); + } +} + +/** Mood without rollups, pulse without a resting series, odd medications. */ +async function seedSparseRecord(userId: string): Promise { + const at = (d: number, hh: number, mm = 0) => + new Date(ANCHOR.getTime() - d * DAY + (hh * 60 + mm) * 60_000); + const rows = []; + for (let d = 1; d < 50; d++) { + if (EDGE_DAYS.includes(d)) continue; + rows.push( + { + userId, + type: "WEIGHT" as const, + value: 70 + (d % 5) * 0.3, + unit: "kg", + measuredAt: at(d, 3, 30), + }, + { + userId, + type: "BLOOD_PRESSURE_SYS" as const, + // Higher on the days the morning dose was skipped, so the + // continuity correlation has something to find. + value: 131 + ((d * 3) % 11) + (d % 5 === 0 ? 22 : 0), + unit: "mmHg", + measuredAt: at(d, 4, 10), + }, + { + userId, + type: "BLOOD_PRESSURE_DIA" as const, + value: 84 + ((d * 2) % 7), + unit: "mmHg", + measuredAt: at(d, 4, 10), + }, + { + userId, + type: "PULSE" as const, + value: 66 + (d % 9), + unit: "bpm", + measuredAt: at(d, 4, 0), + }, + { + userId, + type: "PULSE" as const, + value: 92 + (d % 5), + unit: "bpm", + measuredAt: at(d, 18, 0), + }, + { + userId, + type: "PULSE" as const, + value: 78 + (d % 7), + unit: "bpm", + measuredAt: at(d, 15, 0), + }, + ); + } + await prisma.measurement.createMany({ data: rows }); + const moods = ["LAUSIG", "SCHLECHT", "OKAY", "GUT", "SUPER_GUT"]; + const moodRows = []; + for (let d = 1; d < 30; d++) { + const loggedAt = at(d, 2, 15); + const score = 1 + ((d * 2) % 5); + moodRows.push({ + userId, + // 02:15 UTC is the evening before in Bogotá. + date: new Date(loggedAt.getTime() - 5 * 60 * 60 * 1000) + .toISOString() + .slice(0, 10), + mood: moods[score - 1], + score, + moodLoggedAt: loggedAt, + tz: "America/Bogota", + createdAt: loggedAt, + }); + } + await prisma.moodEntry.createMany({ data: moodRows }); + const created = new Date(ANCHOR.getTime() - 60 * DAY); + await prisma.medication.create({ + data: { + id: parityId("insightscompmed", 1), + userId, + name: "Amlodipine", + dose: "5mg", + createdAt: created, + schedules: { + create: [ + { + id: parityId("insightscompsch", 1), + windowStart: "07:00", + windowEnd: "09:00", + }, + ], + }, + categoryAssignment: { create: { category: "BLOOD_PRESSURE" } }, + }, + }); + await prisma.medication.create({ + data: { + id: parityId("insightscompmed", 2), + userId, + name: "No schedule", + dose: "1 tab", + createdAt: created, + }, + }); + await prisma.medication.create({ + data: { + id: parityId("insightscompmed", 3), + userId, + name: "Ibuprofen", + dose: "400mg", + asNeeded: true, + createdAt: created, + }, + }); + const intakes = []; + for (let d = 1; d <= 40; d++) { + if (d % 4 === 0 || EDGE_DAYS.includes(d)) continue; + intakes.push({ + id: parityId("insightscompie", d), + userId, + medicationId: parityId("insightscompmed", 1), + scheduledFor: at(d, 12, 0), + takenAt: d % 5 === 0 ? null : at(d, 12, 30), + skipped: d % 5 === 0, + createdAt: at(d, 12, 0), + }); + } + await prisma.medicationIntakeEvent.createMany({ data: intakes }); +} + +beforeAll(async () => { + vi.useFakeTimers({ toFake: ["Date"], now: NOW }); + await truncateAllTables(prisma); + __resetAllCachesForTests(); + const ownerRow = await makeUser({ + id: OWNER_ID, + timezone: "UTC", + locale: "en", + heightCm: 178, + dateOfBirth: new Date("1975-04-02T00:00:00.000Z"), + gender: "male", + aiProvider: "ANTHROPIC", + aiModel: "claude-sonnet-4-6", + // Presence only: the overview never decrypts a key. + aiAnthropicKeyEncrypted: "v1:presence-only", + }); + await prisma.consentReceipt.create({ + data: { + userId: OWNER_ID, + kind: "ai_full", + artefact: "test", + signedAt: NOW, + }, + }); + await seedParityRecord({ userId: OWNER_ID, now: NOW, tz: "UTC", tag: "ic" }); + await dropEdgeDays(OWNER_ID); + const rollups = await vi.importActual< + typeof import("@/lib/rollups/measurement-rollups") + >("@/lib/rollups/measurement-rollups"); + await rollups.ensureUserRollupsFresh(OWNER_ID); + const moodRollups = await vi.importActual< + typeof import("@/lib/rollups/mood-rollups") + >("@/lib/rollups/mood-rollups"); + await moodRollups.ensureUserMoodRollupsFresh(OWNER_ID); + await settleBackgroundTasks(); + owner = await makeSession(ownerRow); + + const sparseRow = await makeUser({ + id: SPARSE_ID, + timezone: "America/Bogota", + locale: "de", + dateOfBirth: new Date("1950-08-20T00:00:00.000Z"), + }); + await seedSparseRecord(SPARSE_ID); + // Measurement rollups only: the mood tier stays empty on purpose. + await rollups.ensureUserRollupsFresh(SPARSE_ID); + await settleBackgroundTasks(); + sparse = await makeSession(sparseRow); + + const emptyRow = await makeUser({ id: EMPTY_ID, timezone: "UTC" }); + empty = await makeSession(emptyRow); + + const managerRow = await makeUser({ id: MANAGER_ID, timezone: "UTC" }); + await makeGrant(ownerRow, managerRow, { access: "MANAGE" }); + manager = await makeSession(managerRow); + await switchSessionTo(manager.sessionId, OWNER_ID); + + const readerRow = await makeUser({ id: READER_ID, timezone: "UTC" }); + await makeGrant(ownerRow, readerRow, { access: "READ" }); + reader = await makeSession(readerRow); + await switchSessionTo(reader.sessionId, OWNER_ID); +}); + +afterAll(() => { + vi.useRealTimers(); +}); + +describe("GET /api/insights/comprehensive parity", () => { + it("01 an anonymous call", async () => { + await step("01-anonymous", { auth: anonymous }); + }); + + it("02 the overview, cold", async () => { + await step("02-cold"); + }); + + it("03 the overview, warm", async () => { + await step("03-warm"); + }); + + it("04 the overview, stale after a measurement write", async () => { + invalidateUserMeasurements(OWNER_ID); + await step("04-stale", { raced: true }); + }); + + it("05 the ai block after the AI analysis opt-out", async () => { + await prisma.user.update({ + where: { id: OWNER_ID }, + data: { modulePreferencesJson: { insights: false } }, + }); + await step("05-ai-analysis-off"); + await prisma.user.update({ + where: { id: OWNER_ID }, + data: { modulePreferencesJson: {} }, + }); + }); + + it("06 the ai block with the operator's master switch off", async () => { + await prisma.appSettings.upsert({ + where: { id: "singleton" }, + create: { id: "singleton", assistantEnabled: false }, + update: { assistantEnabled: false }, + }); + await step("06-operator-off"); + await prisma.appSettings.update({ + where: { id: "singleton" }, + data: { assistantEnabled: true }, + }); + }); + + it("07 a delegate with MANAGE access, cold", async () => { + __resetAllCachesForTests(); + await step("07-manage-delegate", { auth: manager }); + }); + + it("08 a delegate with READ access", async () => { + await step("08-read-delegate", { auth: reader }); + }); + + it("09 the shared analytics read ceiling", async () => { + await prisma.$executeRaw` + INSERT INTO rate_limits (key, count, reset_at) + VALUES (${`analytics-read:${OWNER_ID}`}, 100000, (NOW() AT TIME ZONE 'UTC') + INTERVAL '1 hour') + ON CONFLICT (key) DO UPDATE SET count = 100000`; + await step("09-rate-limited"); + await prisma.$executeRaw`DELETE FROM rate_limits WHERE key = ${`analytics-read:${OWNER_ID}`}`; + }); + + it("10 a sparse record west of UTC", async () => { + await step("10-sparse", { auth: sparse }); + }); + + it("11 an account with no data", async () => { + await step("11-empty", { auth: empty }); + }); +});