Files
Cibello-app/packages/connectors/src/health.ts
T
2026-08-05 19:21:11 +07:00

61 lines
2.1 KiB
TypeScript

import type { Connector, ConnectorContext, ConnectorHealth, ImportResult } from "./types.js";
/**
* Hälsointegrationer (spec §42). Själva datainsamlingen sker i mobilappen
* (HealthKit/Health Connect körs på enheten); backend-connectorn tar emot
* det appen skickar och normaliserar. Kräver separat samtycke
* (consent kind: health_integration) och datan hålls i hälsodomänen (spec §56).
*/
export interface HealthSample {
type: "weight_kg" | "steps" | "active_kcal" | "workout" | "sleep_minutes" | "water_ml";
value: number;
unit: string;
startedAt: string;
endedAt: string;
sourceDevice?: string | undefined;
}
abstract class DeviceHealthConnector implements Connector<HealthSample> {
abstract readonly id: "apple-health" | "health-connect";
abstract readonly nameSv: string;
readonly legalBasis = "user_consent_platform_api" as const;
async connect(): Promise<void> {
/* Godkännande sker på enheten. */
}
async authenticate(ctx: ConnectorContext): Promise<boolean> {
return Boolean(ctx.userId);
}
async importData(
_ctx: ConnectorContext,
params?: Record<string, unknown>,
): Promise<ImportResult<HealthSample>> {
// Appen POST:ar samples till /v1/health-data; denna metod normaliserar dem.
const samples = Array.isArray(params?.samples) ? (params.samples as HealthSample[]) : [];
return {
items: samples,
source: this.id,
importedAt: new Date().toISOString(),
warnings: [],
};
}
async sync(ctx: ConnectorContext): Promise<ImportResult<HealthSample>> {
return this.importData(ctx);
}
async disconnect(): Promise<void> {}
async healthCheck(): Promise<ConnectorHealth> {
return { ok: true, detail: "device-side connector", checkedAt: new Date().toISOString() };
}
}
export class AppleHealthConnector extends DeviceHealthConnector {
override readonly id = "apple-health" as const;
override readonly nameSv = "Apple Health";
}
export class HealthConnectConnector extends DeviceHealthConnector {
override readonly id = "health-connect" as const;
override readonly nameSv = "Android Health Connect";
}