feat(01-19): expose privacy-safe ECG import outcomes

- return and render bounded ECG result counters with partial-failure wording
- document archive limits, encrypted storage, and exact WHOOP constraints
This commit is contained in:
Marc-André Bombeck committed 2026-07-29 14:47:22 +02:00
1 parent a686c7200b
commit 4b64556b38
3 files changed
+118 -11

No files matched your search

@@ -30,6 +30,13 @@ interface JobStatus {
totals?: { recordsRead?: number; rowsUpserted?: number };
clinical?: { skipped?: number };
cumulativeEstimates?: { days?: number; rows?: number };
ecg?: {
discovered?: number;
imported?: number;
updated?: number;
skipped?: number;
failed?: number;
};
} | null;
failureReason: string | null;
}
@@ -152,6 +159,8 @@ export function AppleHealthImportCard() {
const isFailed = status?.status === "failed";
const busy = uploading || isRunning;
const percent = status?.progress?.percent ?? null;
const ecg = status?.result?.ecg;
const ecgWritten = (ecg?.imported ?? 0) + (ecg?.updated ?? 0);
return (
<ImportCardShell
@@ -241,7 +250,7 @@ export function AppleHealthImportCard() {
{isDone && (
<WrittenOutcomeLine
outcome={classifyWrittenOutcome({
written: status?.result?.totals?.rowsUpserted ?? 0,
written: (status?.result?.totals?.rowsUpserted ?? 0) + ecgWritten,
// The clinical count is a documented, deliberate exclusion
// (electrocardiograms, lab documents), not a refused row — it
// must not tip the archive into a warning. Only "nothing
@@ -262,6 +271,17 @@ export function AppleHealthImportCard() {
testId="import-apple-health-result"
/>
)}
{isDone && (ecg?.discovered ?? 0) > 0 && (
<p
data-testid="import-apple-health-ecg-result"
className="text-muted-foreground text-xs"
>
ECGs: {ecg?.discovered ?? 0} discovered, {ecg?.imported ?? 0}{" "}
imported, {ecg?.updated ?? 0} updated, {ecg?.skipped ?? 0} skipped,{" "}
{ecg?.failed ?? 0} failed. ECG failures do not discard supported
records imported from export.xml.
</p>
)}
{isDone && (status?.result?.cumulativeEstimates?.days ?? 0) > 0 && (
<AppleHealthEstimateWarning
days={status?.result?.cumulativeEstimates?.days ?? 0}