Wundklar ships on v1. A nurse photographs the wound with the app's own camera, does the structured T.I.M.E. assessment, follows progress and sends a PDF/A report via KIM or an encrypted link so the doctor can issue the next prescription. The product rules — document, don't diagnose; photos never touch the gallery; everything at the bedside works without network; records are immutable; the share link is zero-knowledge; EU hosting and Art. 9 BDSG — outrank the template's defaults and are each pinned by a decision record.
A care service is a Better Auth Organization with the extra row care_service and five care roles (owner/admin as PDL, wound_expert, nurse, aide); member is read as nurse (ADR-0015). Every clinical procedure, sync handler, key delivery, object path and job runs through one authorization boundary (ADR-0031) that checks session assurance, AVV, access state, device, role and patient scope. Clinical records are insert-only; a correction is a new version with a reason (ADR-0028).
The sync protocol carries mutations with dependsOn, a per-kind resolution policy (insert-only, field-merge, conflicting, terminal-monotonic) and a durable ledger with permanent and transient refusals (ADR-0020). Encrypted bytes are staged before their referencing clinical row and attached atomically (ADR-0025). The clinical trail is hash-chained per Organization, sealed every tick and verified daily (ADR-0021). Background work stays in the one cron tick (ADR-0022).
Photos are born encrypted on the device under KEK → ODK + OIK → per-object DEKs (ADR-0017); intimate full frames stay under a separate key opened only with a logged reason. The share link stays zero-knowledge: the server stores only the ciphertext and an Argon2id password hash, the fragment and the password live only in the creating device's link vault, and the ciphertext is deleted after five wrong tries (ADR-0018). Reports are PDF/A-2b in JavaScript, shared by device and Worker and gated by veraPDF (ADR-0023); KIM goes through the service's own client module with a fake transport for dev and SMTP for production (ADR-0024). MD and Art. 15 exports are built on leased, checkpointed jobs that resume after the tick deadline (ADR-0030).
The mobile app runs today on Expo web with an IndexedDB local store behind the shared LocalStore interface (ADR-0019); native-only capabilities (SQLCipher, Keychain, native camera, widgets, Live Activity, iOS gallery count) sit behind the interfaces of ADR-0026 and are tracked under "Pending — native build" in docs/STATUS.md. The UI language default is German ("Sie") with English and Portuguese alongside (ADR-0027). Payments stay disabled: trial, read-only and cancellation are modelled as access states on the care_service row (ADR-0032). Data is EU-resident on Neon aws-eu-central-1 and R2 EU jurisdiction (ADR-0016). The retention purge is scoped and verifiable (ADR-0033).
Developers run the whole stack through the local harness: pnpm wk:harness --slot NN --seed demo boots a disposable Postgres, MinIO, the API and Expo web for a numbered slot so parallel tickets never collide. The product package — Vision Board, PRD, flows, stories, ARD, screens and tokens — lives at docs/wundklar.