feat(healthkit): list the accepted sample types on the integration read

GET /api/integrations/healthkit carries acceptedTypes, the quantity and
category identifiers the batch route maps today. The list is derived from
APPLE_HEALTH_TYPE_MAP alone, so a deferred type is never in it and the
client no longer needs a release to follow a mapping change.

Refs #1340
This commit is contained in:
Marc-André Bombeck committed 2026-11-04 21:18:30 +01:00
1 parent 66533497de
commit 59434cd463
7 files changed
+117

No files matched your search

@@ -45,6 +45,10 @@ import { getSession } from "@/lib/auth/session";
import { listLiveMeasurementTypes } from "@/lib/measurements/live-types";
import { APPLE_HEALTH_DATA_STALE_AFTER_MS } from "@/lib/integrations/sync-verdict";
import { auditLog } from "@/lib/auth/audit";
import {
APPLE_HEALTH_TYPE_MAP,
HK_QUANTITY_TYPE_DEFERRED,
} from "@/lib/measurements/apple-health-mapping";
const SESSION_OK = {
session: { id: "sess-1", expiresAt: new Date(Date.now() + 3_600_000) },
@@ -110,6 +114,23 @@ describe("GET /api/integrations/healthkit", () => {
const bodyMass = body.data.entries.find((e) => e.id === "bodyMass");
expect(bodyMass?.direction).toBe("bidirectional");
});
it("lists the sample types the batch route maps, never a deferred one", async () => {
vi.mocked(getSession).mockResolvedValue(
SESSION_OK as Awaited<ReturnType<typeof getSession>>,
);
const res = await callGet(makeGetReq());
const body = (await res.json()) as { data: { acceptedTypes: string[] } };
expect(body.data.acceptedTypes).toEqual(
Object.keys(APPLE_HEALTH_TYPE_MAP).sort(),
);
expect(body.data.acceptedTypes).toContain(
"HKCategoryTypeIdentifierSleepAnalysis",
);
for (const id of HK_QUANTITY_TYPE_DEFERRED) {
expect(body.data.acceptedTypes).not.toContain(id);
}
});
});
describe("PATCH /api/integrations/healthkit", () => {
@@ -21,6 +21,7 @@ import { annotate } from "@/lib/logging/context";
import { prisma, toJson } from "@/lib/db";
import { auditLog } from "@/lib/auth/audit";
import { getAppleHealthSyncProgress } from "@/lib/integrations/apple-health-progress";
import { acceptedHealthKitTypes } from "@/lib/measurements/healthkit-accepted-types";
import {
getHealthKitTypeArrivals,
healthKitWriteBackTypes,
@@ -241,6 +242,8 @@ export const GET = apiHandler(async () => {
),
syncProgress,
health,
// #1340 — what the batch route maps, so the app asks only for those.
acceptedTypes: acceptedHealthKitTypes(),
});
});