Zuordnung & Sync
Ausstehende Imports & Verknüpfung (manuell, im Portal)
Es gibt kein automatisches Matching in der API — ohne PII kann der Server Pseudonyme nicht auf Personen abbilden. Das geschieht im Portal:
- Erste Uploads (
first_visit) sammeln sich als ausstehende Einträge an, gruppiert nachdevicePseudonym. - Ein Mitarbeiter verknüpft ein Pseudonym mit einem echten Patientendatensatz im Portal. Dabei wird das Mapping
devicePseudonym → clientId(die Device-Pseudonym-Tabelle) und einpersistentTokenfür diesen Patienten angelegt. - Ab dann liefert der Mapping-Sync (siehe unten) dem Client die
mkClientIdfür das Pseudonym, und der Client sendet danach alsfollow_up/token— direkt zugeordnet.
GET /api/v1/imports/list — Pending-Übersicht (für Portal/Debugging)
Query: ?status=pending|rejected|all (Standard: pending), optional &countOnly=1.
Vollständige Liste:
{
"success": true,
"data": {
"pseudonyms": [
{ "devicePseudonym": "a1b2…", "initialsHint": "AB", "dobMonthYearHint": "1985-03",
"status": "pending", "measurementCount": 5, "newestMeasuredAt": "2026-07-15T10:30:00.000Z" }
],
"count": 50,
"total": 120
}
}
Nur Zähler (countOnly=1):
{ "success": true, "data": {
"pendingPseudonyms": 12, "pendingMeasurements": 48,
"rejectedPseudonyms": 3, "rejectedMeasurements": 7 } }
Mapping-Sync — GET /api/v1/practice/mappings?since=<ISO-8601>
Authentifiziert. Der Client pollt inkrementell (typischerweise 1×/h) und cacht lokal, welche Pseudonyme verknüpft (→ follow_up) oder widerrufen sind.
since ist Pflicht (ISO-8601; beim ersten Sync z.B. 1970-01-01T00:00:00.000Z). Fehlt oder ungültig → 400 VALIDATION_ERROR.
Response 200 (Cache-Control: no-store):
{
"success": true,
"data": {
"mappings": [
{ "devicePseudonym": "a1b2…", "mkClientId": "<uuid>", "revoked": false },
{ "devicePseudonym": "f5e6…", "mkClientId": null, "revoked": true, "revokedAt": "2026-07-14T09:00:00.000Z" }
],
"nextSince": "2026-07-15T10:30:00.001Z"
}
}
- Aktive Verknüpfung:
mkClientIdgesetzt,revoked: false. - Tombstone:
revoked: true(+revokedAt,mkClientId: null) ⇒ Mapping lokal ungültig machen, Uploads für dieses Pseudonym stoppen. Auslöser: manuelle Rückgabe der Verknüpfung, Löschung des Patienten oder Widerruf der Einwilligung. nextSincealssincebeim nächsten Poll verwenden (Cursor). Der Cursor ist deterministisch (sekundäre Sortierung nach Pseudonym), sodass gleiche Timestamps keine Endlosschleife verursachen.
Abgelehnte Pseudonyme — GET /api/v1/rejected-clients
Authentifiziert. Gibt die vollständige, deduplizierte Liste aller aktuell abgelehnten Pseudonyme der Praxis zurück. Der Client cacht sie und überspringt diese Pseudonyme beim nächsten Export.
Response 200:
{ "rejected": [ { "pseudonym": "a1b2…" }, { "pseudonym": "f5e6…" } ] }
Leere Liste = nichts abgelehnt (kein 404). Der Inhalt ist identisch mit skip_pseudonyms[] aus der Import-Response — beide beziehen sich auf dieselbe Quelle.
Ablehnungs-Lifecycle (portalseitig): Ein Mitarbeiter lehnt ein Pseudonym ab → dessen vorhandene Pending-Einträge werden rejected, und neu eingehende Messungen für dieses Pseudonym werden automatisch als rejected gepuffert (nicht pending). Reaktivierung setzt sie auf pending zurück.