Compliance- & Sicherheits-Matrix (Schweizer Kontext)
Querschnitts-Dokument, kein Fachmodul. Diese Matrix bündelt alle rechtlichen und sicherheitstechnischen Anforderungen an Caja aus Schweizer Sicht und ordnet jeder Anforderung eine konkrete technische Umsetzung in der App zu. Sie ist die normative Referenz, auf die sich die
## 8. Compliance-/Sicherheits-Hinweise-Abschnitte der einzelnen Module beziehen. Wo ein Modul „revisionssicher", „10 Jahre aufbewahren" oder „besonders schützenswert" sagt, ist hier das Wie definiert — verankert in den geteilten Kern-Entitäten (movements,audit_log,monthly_closings,storage_objects,contacts,kyc_scans,notifications).Geltungsbereich & Haftungsabgrenzung. Caja ist ein operatives Vorsystem, kein Rechts- oder Steuerberater-Ersatz. Es speist die formale Buchhaltung (Treuhänder-Export), ersetzt aber weder den rechtsgültigen Jahresabschluss noch die finale MWST-Abrechnung noch eine juristische DSG-Prüfung. Punkte, die mit Treuhänder/Rechtsberatung final zu klären sind, sind als 🔲 markiert.
Datenschutz-Audit-Stand (2026-06-28). Die zentralen revDSG-Pflichten sind als Best-Practice-Defaults entschieden und in diesem Dokument instanziiert (jeweils ✅, finale juristische Abnahme durch revDSG-Spezialist ausstehend): EU-Datenregion verbindlich (Supabase Frankfurt
eu-central-1, Vercelfra1; §4.4.2), DPA-Checkliste der Auftragsbearbeiter (§4.3), gepflegtes Bearbeitungsverzeichnis (Art. 12, §5), durchgeführte DSFA (Art. 22, §12) und Incident-Runbook (Art. 24, §11). Die Rechtsgrundlagen/Quellen sind als Markdown-Links zu den massgeblichen revDSG-Artikeln (Fedlex) und EDÖB-Leitfäden hinterlegt.Rechtsträger: Dominicano Express GmbH (Schweiz), gegründet 2026, Familien-GmbH (Marcel = Geschäftsführer, Markus = Operations, Mariela = Administration, Arkys = Fahrer/Logistik). Geschäftstätigkeit: See-Fracht Schweiz → Dominikanische Republik. Daraus folgt unmittelbar ein Drittland-Datentransfer (CH → DR, Zoll-/Zustelldaten) plus die Nutzung von US-/EU-Auftragsverarbeitern (Supabase, Vercel, Resend, WhatsApp/Meta). Das OCR der Ausweisdaten läuft self-hosted auf eigener Proxmox-Infra (Entscheid 2026-06-28 Teil 3) → kein OCR-Auftragsbearbeiter und kein Drittland-/Cloud-Transfer der Ausweisbilder fürs OCR; der Drittland-Transfer betrifft damit nur noch Zoll-/Zustelldaten in die DR, nicht den OCR-Dienst.
0. Regulatorischer Rahmen — Überblick
| Regelwerk | Betrifft | Caja-Relevanz | Pflicht ab |
|---|---|---|---|
| OR 957–963b (Obligationenrecht, Geschäftsbücher) | Buchführungs- & Rechnungslegungspflicht, 10 Jahre Aufbewahrung | Ledger movements, Belege, Rechnungen, Abschluss | sofort (GmbH ist buchführungspflichtig nach OR 957 Abs. 1) |
| GeBüV (V über die Führung und Aufbewahrung der Geschäftsbücher, SR 221.431) | Integrität, Unveränderbarkeit, Verfügbarkeit, Lesbarkeit elektronischer Aufzeichnungen | audit_log, Periodensperre, Backup, Export-Migrierbarkeit | sofort |
| MWSTG / MWSTV (Mehrwertsteuergesetz) | Abrechnung, Methodenwahl (Saldo vs. effektiv), Einfuhrsteuer/eVV, Rechnungsanforderungen | vat_rates, vat_code, Treuhänder-/MWST-Export | bei Eintritt Steuerpflicht (Umsatz ≥ CHF 100'000) — schema-ready, inaktiv |
| revDSG / DSV (revidiertes Datenschutzgesetz, in Kraft seit 01.09.2023) | Personendaten, besonders schützenswerte Daten, Bearbeitungsverzeichnis, Auftragsbearbeitung, Drittland-Transfer, Betroffenenrechte | contacts, kyc_scans (Ausweise), Empfänger-DR, alle Provider | sofort |
| ZG / ZV (Zollgesetz; nur mittelbar) | Identifikation Versender/Empfänger, Begleitdokumente | KYC-Zweckbindung, Dokumenten-Archiv Zolldossier | je Sendung |
Schwellen-Hinweis (zu bestätigen): 🔲 Ob/ab wann MWST-Pflicht und Revisionspflicht (ordentliche Revision erst ab OR-820-Schwellen, sonst opting-out möglich) effektiv greifen, ist mit dem Treuhänder festzulegen. Caja ist so gebaut, dass beide ohne Schema-Migration aktivierbar sind.
1. OR 957–963b — Buchführung & Aufbewahrung (10 Jahre)
Owner-Entitäten: movements (Ledger), storage_objects (Belege/Rechnungen), monthly_closings, audit_log.
| # | Gesetzliche Anforderung (OR) | Konkrete technische Umsetzung in Caja |
|---|---|---|
| 1.1 | OR 957a Abs. 2 Ziff. 1–5: Ordnungsmässigkeit — vollständige, wahrheitsgetreue, systematische Erfassung; Beleg-Nachweis; Klarheit; Zweckmässigkeit; Nachprüfbarkeit. | Jeder Geldfluss landet genau einmal als Zeile in movements (Single Source of Truth, ersetzt Erfassung_Digitar). Belegnachweis über storage_objects (doc_class='receipt'/'invoice_pdf', owner_type='movement'/'invoice'). Abgeleitete Grössen sind berechnet (Views v_movements, v_kasse, v_dashboard), nicht doppelt gespeichert → keine Inkonsistenz. |
| 1.2 | OR 957a Abs. 4 / 958f: Beleg-Bezug — jede Buchung muss auf einen Beleg zurückführbar sein. | movements.reference + Verknüpfung zu storage_objects (Beleg-Scan) und bei Zahlungen explizit payment_links (Zahlung → Rechnung/Depot, statt String-Match). |
| 1.3 | OR 958c Abs. 1 Ziff. 2 + Abs. 2: Vollständigkeit/Verlässlichkeit, keine nachträgliche unkenntliche Änderung. | Kein hartes DELETE auf movements (RLS-Policy for delete using (false)); Korrektur ausschliesslich via voided_at-Storno + Neubuchung. Quellen-erzeugte Buchungen (source_type ≠ 'manual') sind im Ledger read-only, nur der operative Ursprung wird editiert (Upsert auf unique(source_type, source_id)). |
| 1.4 | OR 958f Abs. 1: Aufbewahrung 10 Jahre — Geschäftsbücher, Buchungsbelege, Geschäftskorrespondenz. | storage_objects.retain_until = Ablage-Datum + 10 Jahre für documents/receipts-Buckets (Rechnungen, Belege, Liefernachweise). movements-Zeilen werden nie gelöscht (Storno statt Delete). Lösch-/Lifecycle-Jobs respektieren retain_until und löschen nie vor Fristablauf (Guard, siehe §6). |
| 1.5 | OR 958f Abs. 2: Geschäftsbericht & Revisionsbericht schriftlich + unterzeichnet aufbewahren. | Perioden-/Jahresreport als PDF-Export (Edge-Function → storage_objects, doc_class='other', retain_until=+10J). Caja erzeugt das Vorsystem-Material; der unterzeichnete rechtsgültige Abschluss bleibt beim Treuhänder (Abgrenzung, siehe §7). |
| 1.6 | OR 958f Abs. 3: elektronische Aufbewahrung zulässig, sofern GeBüV-konform (→ §2). | Supabase Postgres + Storage als elektronischer Datenträger; Integrität/Unveränderbarkeit über §2 abgesichert; jederzeitige Lesbarmachung via Treuhänder-Export (CSV/Excel/PDF). |
| 1.7 | OR 957a Abs. 5: Landeswährung oder wesentliche Währung; Landessprache. | Beträge numeric(12,2) in CHF (Default-Währung). Mehrwährung (DOP/USD) ist aktuell out of scope 🔲 (siehe Modul 6 offene Punkte). Sprache: dreisprachig DE/ES/EN über locale_strings + label_<locale>; Buchungslogik nutzt stabile Codes, nie übersetzte Begriffe. |
| 1.8 | OR 958 Abs. 2: zeitnahe Buchung (ordnungsgemäss = zeitgerecht). | movements.entry_date (fachliches Datum) getrennt von created_at (Systemzeit); period_key als GENERATED-Spalte to_char(entry_date,'MM/YYYY') → keine Free-Text-Parsing-Fehler. Auto-Posting bucht synchron mit dem operativen Event. |
Aufbewahrungs-Fristenmatrix (10-Jahres-Regel, konkret pro Objekt):
Objekt / doc_class | Bucket / Tabelle | Frist | Default retain_until | Quelle |
|---|---|---|---|---|
| Buchungen (Ledger) | movements | 10 J (nie löschen) | — (Storno statt Delete) | OR 958f Abs. 1 |
| Rechnungen (PDF) | documents / invoice_pdf | 10 J | Ausstellung + 10 J | OR 958f Abs. 1 |
| Belege/Quittungen | receipts / receipt | 10 J | Ablage + 10 J | OR 958f Abs. 1 |
| Offerten (PDF) | documents / quote_pdf | 10 J (Geschäftskorrespondenz) | Versand + 10 J | OR 958f Abs. 1 |
| Liefernachweise | documents / delivery_proof | 10 J | Ablage + 10 J | OR 958f Abs. 1 |
| Perioden-/Jahresreport | documents / other | 10 J | Erstellung + 10 J | OR 958f Abs. 2 |
| Audit-Journal | audit_log | ≥ 10 J (append-only, nie löschen) | — | OR 958f + GeBüV |
| Ausweis-Scans (KYC) | kyc / id_scan | 24 Monate nach letzter Interaktion (entschieden, siehe §4.6) | last_interaction + 24 M | revDSG-Zweckbindung (Geschäftsentscheid 2026-06-28) |
Konflikt-Hotspot (KYC) — entschieden: Ausweis-Rohbilder sind nicht zwingend Buchungsbeleg im Sinn von OR 958f — die Identifikation der Vertragspartei kann fristrelevant sein, das Lichtbild selbst unterliegt der revDSG-Minimierung. Caja trennt deshalb extrahierte Pflichtfelder (
contacts.cedula_number, fristrelevant, OR-10-J soweit Buchungsbeleg) vom Rohbild + KYC-Detailfeldern (kyc-Bucket /kyc_scans). Geschäftsentscheid 2026-06-28: KYC-Daten (Rohbild + extrahierte Felder) werden max. 24 Monate nach der letzten Interaktion mit dem Kontakt gelöscht (siehe §4.6). Damit ist OE-11/F-21 entschieden; ein gesondertes Rechtsgutachten zur Frist ist nicht mehr nötig. Aussenwirkung:46-datenschutz.md§8.
2. GeBüV — Revisionssichere, unveränderbare Aufzeichnungen
Owner-Entitäten: audit_log (append-only Journal), monthly_closings (Periodensperre), Backup/Export-Infrastruktur.
GeBüV verlangt für elektronisch geführte Bücher: Integrität (Art. 3), Verfügbarkeit/Lesbarkeit über die ganze Frist (Art. 6), Dokumentation der Verfahren (Art. 4) und bei veränderbaren Datenträgern den Nachweis der Unveränderbarkeit durch technische Massnahmen (Art. 9) — inkl. Zeitstempel und lückenlosem Änderungsnachweis.
| # | GeBüV-Anforderung | Konkrete technische Umsetzung in Caja |
|---|---|---|
| 2.1 | Art. 3: Integrität / Echtheit & Unverfälschtheit. | audit_log als append-only Journal: jede Mutation an revisionsrelevanten Tabellen erzeugt genau eine Zeile (Trigger fn_audit() an movements, invoices, quotes, orders, deposit_*, contacts, boxes, shipments, affiliates, referral_codes, user_roles, kyc_scans). |
| 2.2 | Art. 9: Unveränderbarkeit bei veränderbaren Datenträgern (Postgres ist veränderbar → technische Sperre nötig). | audit_log ist hart gegen Mutation gesperrt: revoke update, delete on public.audit_log from authenticated, anon, service_role plus SQL-Rules audit_log_no_update/audit_log_no_delete (do instead nothing). Damit kann selbst ADMIN und service_role keine Zeile ändern/löschen. Geschrieben wird nur via SECURITY DEFINER-Trigger. |
| 2.3 | Art. 9 lit. b: Zeitpunkt unverfälschbar feststellbar (Zeitstempel). | audit_log.at timestamptz default now() (DB-seitig gesetzt, nicht vom Client); PK bigint generated always as identity = monotone, sortierstabile, lückenlose Sequenz → nachträgliches „Einschieben" erkennbar. |
| 2.4 | Art. 3 + 9: Änderungen müssen als solche erkennbar bleiben (alt→neu). | Jede Zeile trägt old_data/new_data (JSONB-Vollzustand) + diff (nur geänderte Felder {feld:{old,new}}) + actor_user_id + denormalisiertes actor_email (Journal bleibt lesbar, auch wenn der Nutzer später deaktiviert/umbenannt wird). |
| 2.5 | Korrekturen nach Abschluss müssen ersichtlich bleiben (keine stille Rückdatierung). | Periodensperre monthly_closings.status='closed' + Guard-Trigger fn_guard_closed_period() blockt jede Mutation finanzrelevanter Zeilen einer geschlossenen Periode. Wiedereröffnen nur ADMIN, schreibt action='reopen_period' ins Journal → Korrekturspur bleibt sichtbar; danach Neubuchung + erneuter Abschluss. |
| 2.6 | Art. 6: Verfügbarkeit & Lesbarkeit über die gesamte Aufbewahrungsfrist, jederzeitige Lesbarmachung. | Daten in Supabase Postgres + Storage; Migrierbarkeit garantiert durch offene Formate (SQL-Dump, CSV/Excel/PDF-Export) → keine proprietäre Bindung. Treuhänder-Export-Dialog (Modul 6) macht jede Periode jederzeit lesbar/druckbar. |
| 2.7 | Art. 4: Dokumentation von Organisation & Verfahren (Verfahrensdokumentation). | Diese Spec (cajaspec.dominicanoexpress.com) ist Teil der Verfahrensdokumentation: sie beschreibt Datenmodell, Auto-Posting-Logik, Sperr-/Audit-Mechanik und Aufbewahrung. Ergänzend: Migrations-/DDL-Historie in Git + Supabase-Migrations als versionierter Nachweis der Schema-Entwicklung. |
| 2.8 | Trennung Beleg ↔ Buchung nachvollziehbar. | storage_objects (owner_type, owner_id) verknüpft Beleg eindeutig mit Buchung/Rechnung; payment_links macht Zahlungszuordnung prüfbar statt heuristisch. |
Unveränderbarkeits-Kern (zur Illustration, normativ aus Modul 8):
-- audit_log: niemand darf ändern/löschen — auch ADMIN/service_role nicht
revoke update, delete on public.audit_log from authenticated, anon, service_role;
create rule audit_log_no_update as on update to public.audit_log do instead nothing;
create rule audit_log_no_delete as on delete to public.audit_log do instead nothing;
-- Schreiben ausschliesslich via SECURITY DEFINER-Trigger fn_audit(),
-- RLS-SELECT nur für interne Rollen (is_internal()), Affiliate: kein Zugriff.
GeBüV-Grenze (ehrlich benannt): SQL-Rules + Grant-Entzug erfüllen die Unveränderbarkeit „durch technische Massnahmen" auf Applikations-/DB-Ebene. Ein Datenbank-Superuser (Supabase-Projekt-Owner mit direktem Postgres-Zugriff) könnte theoretisch tiefer eingreifen. Kompensierende Kontrollen: (a) Supabase-Service-Key/DB-Passwort streng zugriffsbeschränkt (nur Marcel), (b) WORM-/immutable Backups (§6) als unabhängige zweite Spur, (c) Supabase-eigenes Audit/Logging der Infrastruktur. 🔲 zu bestätigen, ob für die Revision eine zusätzliche externe Unveränderbarkeits-Bestätigung (z. B. periodischer Hash-Anker/Export-Siegel) verlangt wird.
3. MWSTG — Abrechnung, Methodenwahl, eVV/Einfuhrsteuer
Owner-Entitäten: vat_rates (effektiv-datiert, active-Flag), movements.vat_code/vat_amount_chf, Treuhänder-/MWST-Export. Status: schema-ready, default inaktiv (vat_rates.active=false, Feature-Flag vat_enabled=false) → keine falschen Steuerkennzahlen vor Scharfschaltung.
| # | MWSTG-Anforderung | Konkrete technische Umsetzung in Caja |
|---|---|---|
| 3.1 | Steuerpflicht / Eintritt (Umsatz-Schwelle CHF 100'000). | Caja trackt den steuerbaren Umsatz über v_dashboard/v_monatskontrolle → Schwellen-Monitoring möglich (KPI). MWST bleibt deaktiviert, bis Steuerpflicht eintritt; Aktivierung = vat_rates.active=true + vat_enabled ohne Schema-Migration. |
| 3.2 | Korrekte Steuersätze (CH, effektiv-datiert). | vat_rates mit rate_pct, valid_from/valid_to: Seeds Normalsatz 8.1 %, reduziert 2.6 %, Beherbergung/Sonder 3.8 %, befreit/Export 0 % (ab 2024). Effektiv-Datierung erlaubt korrekte Sätze auch rückwirkend/bei Satzänderung. |
| 3.3 | Methodenwahl: Saldosteuersatz vs. effektive Methode. | Konfigurierbar als Settings-Flag vat_method ∈ {effective, flat_rate}. Effektiv: vat_amount_chf pro Buchung aus vat_code, Vorsteuerabzug über Aufwands-Buchungen (EXPENSE/SUPPLIER_PAYMENT, eVV-Vorsteuer). Saldosatz (SSS): ein/zwei bewilligte Branchen-Sätze auf den Bruttoumsatz, kein detaillierter Vorsteuerabzug → Caja rechnet die SSS-Kennzahl aus dem Umsatz. 🔲 Methode + bewilligte(r) SSS-Satz/-Sätze mit Treuhänder/ESTV festzulegen. |
| 3.4 | Brutto- vs. Netto-Konvention (ist total_chf inkl. oder exkl. MWST?). | 🔲 zu bestätigen (Modul 6 offener Punkt): empfohlen total_chf = brutto (inkl.), vat_amount_chf herausgerechnet beim Speichern wenn vat_code gesetzt. Konvention wird als Settings-Konstante fixiert, damit Auto-Posting und Export konsistent bleiben. |
| 3.5 | Einfuhrsteuer / eVV (elektronische Veranlagungsverfügung Import). | Eigener movement_type (z. B. IMPORT_TAX / „Einfuhrsteuer") und/oder vat_code='ZERO' mit Vorsteuer-Charakter; eVV-Beleg als storage_objects (doc_class='receipt') am betreffenden movement archiviert. Bei See-Fracht CH→DR ist die Schweizer Einfuhrsteuer auf Importe in die CH relevant (z. B. Retouren/Material), nicht der Export selbst (Export = 0 % / befreit). 🔲 finale eVV-Abbildung mit Treuhänder. |
| 3.6 | Export-Lieferungen = von der Steuer befreit (echte Befreiung, Art. 23 MWSTG). | Die Kern-Dienstleistung (Fracht in die DR) ist exportbezogen → vat_code='ZERO'/befreit, mit Ausfuhrnachweis (Frachtdokument) als storage_objects. So erscheint der Hauptumsatz korrekt als 0 %/befreit statt 8.1 %. |
| 3.7 | Rechnungsanforderungen (Art. 26 MWSTG) — MWST-Nr., Satz, Betrag, Leistung, Datum, Parteien. | Rechnungs-PDF (Modul 4/6) trägt bei aktiver MWST: UID/MWST-Nr. der GmbH, Satz je Position, MWST-Betrag, Leistungsbeschrieb, Datum, Empfänger. Datenquelle: movements + vat_rates + contacts. |
| 3.8 | MWST-Abrechnung (quartalsweise/halbjährlich) als Kennzahlen. | MWST-Export liefert die Abrechnungs-Kennzahlen (Umsatz nach Satz, geschuldete Steuer, Vorsteuer bei effektiver Methode) je Abrechnungsperiode — als Vorbereitung für die ESTV-Abrechnung des Treuhänders, nicht als direkte ESTV-Einreichung. |
| 3.9 | Keine falschen Steuerwerte vor Freigabe. | Solange vat_enabled=false: alle Bestandsbewegungen vat_code=NULL, vat_amount_chf=NULL → MWST-neutral; Export blendet MWST-Spalten aus. Aktivierung wirkt nur prospektiv (Bestand bleibt neutral). |
MWST-Abgrenzung: Caja erzeugt MWST-Kennzahlen und -belege, reicht aber nichts bei der ESTV ein und ersetzt die fachliche Abrechnung des Treuhänders nicht. Methodenwahl (Saldo vs. effektiv) und der konkrete Saldosteuersatz sind Geschäfts-/Treuhänderentscheide (🔲), die Caja per Settings abbildet.
4. revDSG / DSG — Personendaten & besonders schützenswerte Ausweisdaten
Owner-Entitäten: contacts (Parteien: Kunde/Lead/Lieferant/Affiliate/Empfänger-DR), kyc_scans + kyc-documents-Bucket (Ausweise = besonders schützenswert), storage_objects (is_sensitive), notifications (Kommunikationsdaten).
4.1 Daten-Klassifizierung
| Datenkategorie | Wo in Caja | revDSG-Einstufung | Schutzniveau |
|---|---|---|---|
| Stammdaten (Name, Adresse, Tel., E-Mail) | contacts | normale Personendaten (Art. 5 lit. a) | RLS interne Rollen; Affiliate nur Eigenes |
| Ausweisdaten (Cédula/Pass-Nr., Geburtsdatum, Lichtbild, Nationalität) | kyc_scans.extracted_fields, kyc-Bucket, contacts.cedula_number/birth_date/nationality | besonders schützenswert (Art. 5 lit. c — Identifikationsmerkmale/biometrieartig) | strengste RLS (is_sensitive=true); nur ADMIN/OPERATIONS/BUCHHALTUNG; READONLY/AFFILIATE kein Zugriff |
| Empfänger-DR-Daten | recipients (über shipments.recipient_id), optional recipients.contact_id → contacts | Personendaten Dritter (oft nicht der Vertragspartner) | zweckgebunden Zoll/Zustellung; RLS interne Rollen |
| Kommunikationsdaten | notifications, whatsapp_inbound | normale Personendaten | interne Rollen; Affiliate nur an ihn adressierte |
| Finanzdaten je Person | movements (contact_id) | normale Personendaten | RLS Finanz-/Leitungsrollen; Affiliate keine |
4.2 Kern-Pflichten → Umsetzung
| # | revDSG-Pflicht | Konkrete technische Umsetzung in Caja |
|---|---|---|
| 4.1 | Art. 6 Abs. 1–3: Rechtmässigkeit, Zweckbindung, Verhältnismässigkeit. | Jede Datenkategorie hat genau einen dokumentierten Zweck (CRM-Vertragsabwicklung; KYC = Zoll-/Empfänger-Matching; Affiliate-Abrechnung). KYC-Scan dient ausschliesslich Identitäts-/Zoll-/Empfänger-Matching — kein Weiterverkauf, kein Tracking. |
| 4.2 | Art. 6 Abs. 3 + Art. 5 lit. c: Datenminimierung, v. a. besonders schützenswerte. | OCR extrahiert nur die fachlich nötigen Felder; ocr_raw_response (Voll-Antwort des Providers) wird nach 90 Tagen per Cron auf NULL gesetzt (Felder bleiben). Rohbild im kyc-Bucket so kurz wie möglich (§4.6). Exporte enthalten nur das fachlich Nötige. |
| 4.3 | Art. 8/Art. 25 DSV: Datensicherheit (technisch & organisatorisch). | Verschlüsselung at-rest (Supabase AES-256) + in-transit (TLS 1.2+); kyc/documents/receipts-Buckets privat (kein Public-Read); Pre-Signed URLs max. 60 min für Review; signierte Upload-URLs (Client sieht nie den Service-Key); RLS deny-by-default als zweite Verteidigungslinie unabhängig von der UI; passwortlose Auth (Magic-Link/OTP) eliminiert Passwort-Leaks. |
| 4.4 | Art. 12: Bearbeitungsverzeichnis (Verzeichnis der Bearbeitungstätigkeiten). | ✅ Pflicht bejaht & instanziiert (Best-Practice-Default, finale juristische Abnahme ausstehend). Die KMU-Ausnahme (< 250 Mitarbeitende) nach Art. 24 DSV greift hier nicht, weil Dominicano Express besonders schützenswerte Ausweisdaten bearbeitet — sobald dies «umfangreich» geschieht, entfällt die Ausnahme. Konservativ wird das Verzeichnis daher unabhängig vom Volumen geführt. Konkretes, gepflegtes Verzeichnis siehe §5 (Tabelle pro Bearbeitung). Caja liefert die technischen Fakten dazu aus dem Schema. |
| 4.5 | Art. 19–21: Informationspflicht bei Beschaffung. | Datenschutzerklärung Website (/datenschutz) + In-App-KYC-Hinweis nennen Zweck, Kategorien, Empfänger (inkl. DR-Zoll), Auftragsbearbeiter und Drittland-Transfer. Entwurf liegt vor: 46-datenschutz.md (revDSG-konform, inkl. KYC-/Caja-Verarbeitung, Auftragsbearbeiter, Auslandtransfer). 🔲 Verbleibend: anwaltliche Schlussprüfung (revDSG-Spezialist) + Platzhalter füllen + Publikation. |
| 4.6 | Art. 25–27: Betroffenenrechte (Auskunft, Berichtigung, Löschung/„Vergessen"). | Auskunft: contacts-Detail + Scan-Verlauf je Person abrufbar. Berichtigung: Felder editierbar (auditiert via kyc_field_corrections/audit_log). Löschung: ADMIN kann kyc_scans + Storage-Datei löschen und contacts.cedula_number/birth_date separat leeren, ohne die buchführungsrelevante Vertragspartei-Historie zu zerstören (Lösch-Guard prüft retain_until, siehe §6). Jede Löschung erzeugt audit_log-Eintrag mit Grund. |
| 4.7 | Art. 24: Meldepflicht Datensicherheitsverletzung (an EDÖB), „so rasch als möglich". | ✅ Incident-Runbook ausformuliert (Best-Practice-Default, finale juristische Abnahme ausstehend) → siehe §11. Erkennung über Supabase/Vercel-Logs + Auth-Anomalien → Risiko-Bewertung → EDÖB-Meldung bei voraussichtlich hohem Risiko → Information Betroffener nur „wenn zu deren Schutz erforderlich oder vom EDÖB verlangt" (Art. 24 Abs. 4). audit_log + Provider-Logs liefern Forensik (wer/was/wann). |
| 4.8 | Art. 22: Datenschutz-Folgenabschätzung (DSFA) bei hohem Risiko (umfangreiche Bearbeitung besonders schützenswerter Daten). | ✅ Schwellenprüfung durchgeführt → DSFA erstellt (Best-Practice-Default, finale juristische Abnahme ausstehend) → siehe §12. Befund: KYC-Ausweisdaten (besonders schützenswert) plus Drittland-Transfer (DR) → Risiko vorsorglich als hoch eingestuft → DSFA erforderlich. Caja-Schutzmassnahmen (Minimierung, self-hosted OCR, Verschlüsselung, RLS, kurze Aufbewahrung) sind die mitigierenden Faktoren; Restrisiko nach Massnahmen = nicht hoch → keine EDÖB-Vorabkonsultation nach Art. 23 nötig. |
4.3 Auftragsbearbeiter (Art. 9 revDSG) — Provider-Matrix
Pflicht: Auftragsbearbeitung nur, wenn der Bearbeiter dieselbe Datensicherheit gewährleistet → Auftragsbearbeitungsvertrag (DPA/AVV) mit jedem Provider; Unterbeauftragung nur mit Genehmigung; Drittland nur mit Garantien (siehe §4.4).
| Auftragsbearbeiter | Verarbeitet (Caja-Bezug) | Sitz / Datenregion | DPA/AVV | Massnahme in Caja | Status |
|---|---|---|---|---|---|
| Supabase (Postgres/Auth/Storage) | alle Personendaten inkl. KYC | US-Firma; ✅ Projekt-Region verbindlich EU — Frankfurt (eu-central-1) (§4.4.2) | Supabase DPA (Standard) → zu zeichnen (§4.7) | Region fix eu-central-1; Service-Key nur serverseitig; RLS+Verschlüsselung | ✅ Region entschieden; 🔲 DPA gegenzeichnen |
| Vercel (Hosting/Edge/Web Analytics) | Request-Metadaten, Server-Logs, Env-Secrets | US-Firma; ✅ Functions-Region EU (Frankfurt fra1) | Vercel DPA → zu zeichnen (§4.7) | Functions-Region EU; keine Personendaten in Logs roh; Web Analytics cookie-/IP-schonend prüfen | ✅ Region entschieden; 🔲 DPA gegenzeichnen; Analytics-Datenumfang prüfen |
| Resend (E-Mail) | Empfänger-E-Mail, Betreff/Body, Provider-Message-ID | US-Firma | Resend DPA → zu zeichnen (§4.7) | Absender …@dominicanoexpress.com (verifiziert); echte Fehler nur in Server-Logs, nie roh im Client | 🔲 DPA gegenzeichnen |
| WhatsApp / Meta (Cloud API o. Deep-Link) | Telefonnummer, eingehende Medien (Ausweis!), Nachrichtentext | Meta, US (Cloud API) | Meta/WABA-Terms + DPA (bzw. via BSP) → zu zeichnen (§4.7) | Heute Deep-Link (manuell, +41 79 199 93 93); bei Cloud-API: HMAC-Webhook, Medien sofort in eigenen kyc-Bucket, WA-URL verfällt 24 h | 🔲 Direkt-API vs. BSP (Twilio/360dialog) entscheiden; DPA |
| Revolut (Business) (Zahlungs-/Finanzdaten) | Name, IBAN/Konto-Referenz, Zahlungsbeträge, Transaktions-Metadaten | UK/EU (Revolut Bank UAB, LT) | Revolut DPA / Datenschutzbestimmungen → zu zeichnen/akzeptieren (§4.7) | nur abrechnungsrelevante Felder; keine Karten-Vollnummern in Caja; Zuordnung Zahlung→Rechnung via payment_links | 🔲 DPA/Terms gegenzeichnen; Datenumfang Schnittstelle prüfen |
| OCR (Ausweis-Extraktion) | Ausweis-Bild + extrahierte Felder (besonders schützenswert!) | self-hosted, eigene Proxmox-Infra (CH/in-house) — kein externer Auftragsbearbeiter | kein DPA nötig (in-house) | Entscheid 2026-06-28 Teil 3: self-hosted Open-Source-Vision/OCR (ocr_provider='SELF_HOSTED'); Ausweisbild verlässt die eigene Infra fürs OCR nicht → kein Drittland-Transfer fürs OCR (Compliance-Plus) | ✅ entschieden; konkretes Open-Source-Modell 🔲 TBD |
| DR-Zollbehörde (Empfänger) | Identifikations-/Empfängerdaten | Dominikanische Republik (Drittland) | gesetzliche Übermittlung (keine klassische Auftragsbearbeitung) | nur das zollrechtlich Nötige; dokumentierte Bekanntgabe ins Ausland (§4.4) | 🔲 rechtliche Grundlage Bekanntgabe DR bestätigen |
DPA-Checkliste (zu zeichnen, Best-Practice-Default — finale juristische Abnahme ausstehend): Mit jedem externen Auftragsbearbeiter ist vor Produktivbetrieb ein Auftragsbearbeitungsvertrag (DPA/AVV) nach Art. 9 revDSG abzuschliessen. OCR entfällt (self-hosted, in-house — kein Auftragsbearbeiter).
- Supabase — Standard-DPA akzeptieren/gegenzeichnen; Region
eu-central-1fixieren; SCC für US-Mutterkonzern enthalten.- Vercel — DPA gegenzeichnen; Functions-/Region EU; SCC enthalten.
- Resend — DPA gegenzeichnen; SCC (US) enthalten.
- Meta/WhatsApp (bzw. BSP wie Twilio/360dialog) — WABA-Terms + DPA; SCC (US) bzw. EU-BSP-Vertrag.
- Revolut Business — DPA/Datenschutzbestimmungen akzeptieren/gegenzeichnen.
4.4 Drittland-Transfer (Art. 16–18 revDSG)
| # | Anforderung | Umsetzung / Status |
|---|---|---|
| 4.4.1 | Bekanntgabe ins Ausland nur mit angemessenem Schutz (Länderliste des Bundesrats) oder geeigneten Garantien (SCC/Standardvertragsklauseln, Einwilligung, Vertragserfüllung). | USA (Supabase/Vercel/Resend/Meta): kein genereller Angemessenheitsbeschluss → Garantien via SCC in den jeweiligen DPAs. OCR: entfällt als Auslandtransfer — läuft self-hosted (Proxmox, in-house), Ausweisbild verlässt die Infra fürs OCR nicht (Entscheid 2026-06-28 Teil 3). DR (Empfänger/Zoll): Drittland ohne Angemessenheit → Stützung auf Art. 17 lit. a/b: Bekanntgabe zur Vertragserfüllung (Frachtvertrag) bzw. Einwilligung; nur zollrechtlich Nötiges. |
| 4.4.2 | Datenresidenz minimieren. | ✅ Verbindliche Vorgabe (Best-Practice-Default, finale juristische Abnahme ausstehend): Supabase-Projekt-Region = EU — Frankfurt (eu-central-1); Vercel-Functions-Region = EU (Frankfurt fra1); OCR self-hosted auf eigener Proxmox-Infra (besonders schützenswerte Ausweisbilder bleiben vollständig in-house, kein Cloud-/Drittland-Transfer fürs OCR). So liegen Primärdaten und native Backups in der EU. Ehrlich benannte Grenze (Schrems-II-Logik): Supabase Inc. und AWS sind US-Mutterkonzerne und damit potenziell dem US-CLOUD-Act unterworfen — die EU-Region löst die Datenresidenz, nicht die volle Datensouveränität; deshalb zusätzlich SCC in den DPAs (§4.4.1) als geeignete Garantie. |
| 4.4.3 | Transparenz im Bearbeitungsverzeichnis & in der Datenschutzerklärung. | Drittland-Transfers (US-Provider, DR-Empfänger) werden im Verzeichnis (§5) und in der Datenschutzerklärung benannt; das OCR ist in-house und damit kein Drittland-/Auftragsbearbeiter-Transfer. Datenschutzerklärung-Entwurf liegt vor: 46-datenschutz.md §6 (Auslandtransfer) + §7 (Auftragsbearbeiter). 🔲 Verbleibend: anwaltliche Schlussprüfung. |
4.5 Affiliate-Mandantentrennung (Datenschutz-relevant)
Ein Affiliate ist datenschutzrechtlich ein Externer → er darf keine fremden Personen-/Finanzdaten sehen. Technisch hart über RLS: current_affiliate_id()-Helfer + Policies stellen sicher, dass ein Affiliate ausschliesslich seine vermittelten Sendungen/Offerten/Abrechnungen sieht (kein Kunden-Gesamtzugriff, kein Finanz-Gesamtzugriff, kein audit_log- und kein kyc-Zugriff). Beispiel-Policy siehe Modul 8 §3.12.
4.6 KYC-Aufbewahrung — das DSG ⇄ OR-Spannungsfeld (Löschkonzept)
| Schicht | Inhalt | Aufbewahrung | Mechanik |
|---|---|---|---|
Pflichtfelder (contacts.cedula_number, Identifikation Vertragspartei) | minimal nötige Identifikation | OR-fristrelevant, soweit Buchungsbeleg (bis 10 J); sonst 24 M nach letzter Interaktion | bleibt, solange Vertrags-/Buchführungsbezug; separat löschbar |
Extrahierte Detailfelder (kyc_scans.extracted_fields) | Restfelder | max. 24 Monate nach letzter Interaktion | Lifecycle-Job leert/löscht nach Fristablauf (auditiert) |
OCR-Rohantwort (ocr_raw_response) | Voll-Provider-Antwort | 90 Tage, dann NULL | Cron-Job (Datenminimierung) |
Rohbild (kyc-Bucket) | Ausweis-Lichtbild | max. 24 Monate nach letzter Interaktion mit dem Kontakt | Storage-Lifecycle-Job löscht Datei nach Fristablauf + markiert storage_objects gelöscht; audit_log-Eintrag der Löschung bleibt |
✅ Entschieden (Geschäftsentscheid 2026-06-28, löst OE-11 / F-21): Die KYC-Aufbewahrungsfrist für Rohbild und extrahierte Felder beträgt max. 24 Monate nach der letzten Interaktion mit dem Kontakt; danach Löschung. Das bestimmt den
kyc-retain_until-Default alslast_interaction_at + 24 Monate(rollierend — jede neue Interaktion verschiebt das Lösch-Datum). Rechtsgrundlage: Zweckbindung/Verhältnismässigkeit nach revDSG; die Bearbeitung selbst stützt sich auf die Einwilligung im Onboarding-Vertrag (Ausweisbearbeitung + Auslandtransfer + OCR) sowie auf Vertragserfüllung. Ein gesondertes Rechtsgutachten zur Frist ist damit nicht mehr nötig. Abgrenzung OR: Soweit eine KYC-Information zwingender Buchungsbeleg ist (z. B. Identität der Vertragspartei auf einem Beleg), gilt dort weiterhin die 10-Jahres-Frist (§1.4); das ist eine andere Schicht als das Ausweis-Lichtbild. Querverweise: OCR §8.1 (Open Point 6) und Design §8.1 ziehen denselben Entscheid nach; Aussenwirkung in46-datenschutz.md§8.
5. Bearbeitungsverzeichnis (Art. 12 revDSG) — gepflegtes Verzeichnis
✅ Instanziiert (Best-Practice-Default, finale juristische Abnahme ausstehend). Dominicano Express GmbH führt dieses Verzeichnis der Bearbeitungstätigkeiten als Verantwortliche nach Art. 12 revDSG. Caja liefert die technischen Fakten aus dem Schema; die laufende Pflege (neue Bearbeitungen, geänderte Empfänger) liegt bei der GmbH (RACI §10). Pflicht-Begründung: Die KMU-Ausnahme nach Art. 24 DSV (< 250 Mitarbeitende) entfällt, sobald umfangreich besonders schützenswerte Daten bearbeitet werden — KYC-Ausweisdaten sind genau das; das Verzeichnis wird daher konservativ unabhängig vom Volumen geführt.
Kopfangaben (Art. 12 Abs. 2 lit. a):
| Feld | Inhalt |
|---|---|
| Verantwortlicher | Dominicano Express GmbH, [Strasse/Nr., PLZ Ort], Schweiz |
| Kontakt | Marcel (Geschäftsführer), [datenschutz@dominicanoexpress.com] |
| Datenschutzberater/-in | freiwillig (keine Pflicht für CH-KMU) — 🔲 Geschäftsentscheid, ob benannt |
| Stand / letzte Revision | bei jeder Schema-/Prozessänderung nachzuführen (Versionierung via Git/Spec) |
Bearbeitungstätigkeiten (Art. 12 Abs. 2 lit. b–e + DSV): Spalten = Zweck · Betroffene Personen · Datenkategorien · Empfänger · Auslandtransfer (+ Garantie) · Aufbewahrung · Rechtsgrundlage.
| # | Bearbeitung | Zweck | Betroffene | Datenkategorien | Empfänger | Auslandtransfer (+ Garantie) | Aufbewahrung | Rechtsgrundlage (revDSG) |
|---|---|---|---|---|---|---|---|---|
| V1 | Kundenstamm / CRM (contacts) | Vertragsanbahnung & -abwicklung, Kommunikation | Kunden, Leads, Lieferanten | Name, Adresse, Tel./WhatsApp, E-Mail, Sprache | Supabase (Hosting), Vercel; intern | USA via Supabase/Vercel (US-Mutter) → SCC (DPA) | Dauer Geschäftsbeziehung; buchhaltungsrelevante Stammdaten 10 J (OR) | Vertragserfüllung (Art. 31 Abs. 2 lit. a); berechtigtes Interesse |
| V2 | KYC / Ausweis-Identifikation (kyc_scans, kyc-Bucket, contacts.cedula_number/birth_date/nationality) | Identitäts- & Empfänger-Matching für Zoll DR; gesetzl. Sorgfalt | Kunden, Empfänger DR | besonders schützenswert: Cédula/Pass-Nr., Geburtsdatum, Nationalität, Ausweis-Lichtbild | Supabase (Storage); DR-Zollbehörde (extrahierte Pflichtfelder); OCR self-hosted = kein externer Empfänger | DR (Drittland, kein Angemessenheitsbeschluss) → Einwilligung (Onboarding) + Vertragserfüllung (Art. 17 lit. a/b); USA (Supabase) → SCC; OCR: kein Transfer | max. 24 Monate nach letzter Interaktion (Rohbild + Felder, §4.6); OCR-Rohantwort 90 Tage; Pflichtfeld-Identität bis 10 J soweit Buchungsbeleg | Einwilligung für besonders schützenswerte Daten + Auslandtransfer (Art. 6 Abs. 6/7, Art. 17 lit. b); Vertragserfüllung |
| V3 | Versand / Logistik (shipments, recipients, boxes) | Frachtabwicklung, Zoll, Zustellung in DR | Kunden, Empfänger in DR (Dritte) | Empfänger-Name, -Adresse, -Tel., Cédula; Sendungs-/Boxdaten | DR-Zollbehörde; Empfänger; Logistikpartner; intern | DR (Drittland) → Vertragserfüllung + Einwilligung (Art. 17); nur zollrechtlich Nötiges | Dauer Abwicklung + Nachweisfristen; Belege 10 J (OR) | Vertragserfüllung (Art. 31 Abs. 2 lit. a); gesetzliche Pflicht (Zoll) |
| V4 | Zahlungen / Finanzen / Buchhaltung (movements, invoices, payment_links) | Rechnungsstellung, Zahlungsabwicklung, Buchführung | Kunden, Lieferanten, Affiliates | Beträge, Zahlungsmethode, IBAN/Konto-Ref., offene Posten, Belege | Treuhänder (Export); Revolut (Zahlung); Supabase | UK/EU via Revolut (angemessen/SCC); USA via Supabase → SCC | 10 Jahre (OR 957a/958f, GeBüV §1.4) | gesetzliche Pflicht (OR/GeBüV); Vertragserfüllung |
| V5 | WhatsApp-Kommunikation (notifications, whatsapp_inbound) | Kundenservice, Status, Onboarding-Medien (Ausweis) | Kunden, Leads | Telefonnummer, Nachrichtentext/-Metadaten, eingehende Medien (ggf. Ausweis) | Meta/WhatsApp (bzw. BSP); intern | USA via Meta → SCC (DPA/WABA-Terms) | für Bearbeitung/Geschäftsbeziehung nötige Zeit; Ausweis-Medien → KYC-Frist (V2) | Vertragserfüllung; berechtigtes Interesse; Einwilligung (KYC-Medien) |
| V6 | Affiliate-Abrechnung (affiliates, referral_codes) | Vermittlungsprovision, Mandantentrennung | Affiliates; vermittelte Kunden (eingeschränkt) | Affiliate-Stammdaten, vermittelte Sendungen/Beträge | Supabase; intern; Treuhänder (Provisions-Buchung) | USA via Supabase → SCC | abrechnungs-/buchhaltungsrelevant 10 J (OR) | Vertragserfüllung; berechtigtes Interesse |
| V7 | Betrieb / Sicherheit / Audit (audit_log, Server-Logs) | Nachvollziehbarkeit, Missbrauchsabwehr, Forensik | alle Nutzer/Betroffenen | Aktions-Protokolle, Zeitstempel, Actor-E-Mail, techn. Logs | Supabase; Vercel; intern | USA via Supabase/Vercel → SCC | append-only, ≥ 10 J (OR/GeBüV §2) | gesetzliche Pflicht (GeBüV); berechtigtes Interesse |
Allgemeine TOM (techn./org. Massnahmen, für alle Bearbeitungen): RLS deny-by-default, AES-256 at-rest, TLS 1.2+ in-transit, passwortlose Auth + 2FA/MFA (Entra/TOTP), private Buckets + kurzlebige Pre-Signed URLs, append-only Audit, Backup/PITR + WORM-Cold-Storage, RTO/RPO (§6, §8).
Pflege-Hinweis: Jede neue Tabelle/jeder neue Provider, der Personendaten berührt, ist als Zeile zu ergänzen (Review-Gate analog RLS-Policy-Pflicht, §8.2). Querverweis Drittland-Garantien §4.4, Auftragsbearbeiter §4.3.
6. Aufbewahrung, Löschkonzept, Backup & RTO
6.1 Lösch-Guard (OR-Aufbewahrung schlägt DSG-Löschung, solange Frist läuft)
DSG-Löschbegehren und OR-Aufbewahrung können kollidieren. Caja löst das deterministisch: ein Lösch-/Lifecycle-Job darf ein fristrelevantes Objekt nie vor retain_until löschen.
-- Konzept-Guard: blockt Löschung fristrelevanter Storage-Objekte vor Fristablauf.
create or replace function public.fn_guard_retention()
returns trigger language plpgsql security definer set search_path = public as $$
begin
if old.retain_until is not null and old.retain_until > current_date then
raise exception 'Objekt % unterliegt Aufbewahrung bis % (OR 958f) — Löschung blockiert.',
old.id, old.retain_until using errcode = 'P0001';
end if;
return old;
end; $$;
-- KYC-Rohbild (is_sensitive, kein Buchungsbeleg): retain_until = last_interaction_at + 24 Monate
-- (Entscheid 2026-06-28, rollierend). Lifecycle-Job löscht NACH Fristablauf (revDSG-Zweckbindung),
-- der Guard schützt es bis dahin wie jedes fristrelevante Objekt; Audit-Eintrag der Löschung bleibt.
6.2 Löschkonzept je Objektklasse
| Objektklasse | Löschregel | Trigger |
|---|---|---|
movements (Ledger) | nie hart löschen → voided_at-Storno | manuell (RPC, ADMIN/BUCHHALTUNG) |
Rechnungen/Belege/Reports (documents/receipts) | nach retain_until (= +10 J) | Lifecycle-Job; Guard §6.1 |
KYC-Rohbild (kyc) + extrahierte Felder | max. 24 M nach letzter Interaktion (retain_until = last_interaction_at + 24 M, rollierend) | Lifecycle-Job; DSG-Zweckbindung (Entscheid 2026-06-28) |
OCR-Rohantwort (ocr_raw_response) | nach 90 Tagen → NULL | Cron |
| Kontakt-Personendaten (DSG-Löschbegehren) | leeren der Personendaten ohne Vertrags-/Buchhistorie zu zerstören; harte Löschung nur wenn keine Frist offen | ADMIN; Guard §6.1 |
audit_log | nie (append-only) | — |
Anonymisierung statt Löschung dort, wo OR-Frist und DSG-Löschwunsch kollidieren: Personenbezug im Kontakt entfernen, die buchhalterische Bewegung (betragsmässig, fristrelevant) bleibt erhalten. So sind beide Pflichten erfüllbar.
6.3 Backup & Recovery (GeBüV Art. 6 — Verfügbarkeit über die Frist)
| # | Anforderung | Umsetzung |
|---|---|---|
| 6.3.1 | Regelmässige Sicherung, Wiederherstellbarkeit über 10 J. | Supabase PITR (Point-in-Time-Recovery) + tägliche automatisierte Backups (Plan-abhängig 🔲). Zusätzlich periodischer logischer Export (SQL-Dump + CSV) in unabhängiges Cold-Storage → unabhängig von Supabase-Verfügbarkeit, GeBüV-Lesbarkeit langfristig gesichert. |
| 6.3.2 | Unveränderbarkeit auch der Sicherung (kompensierende Kontrolle zu §2). | Cold-Storage als WORM/immutable (versioniert, Lösch-/Überschreibschutz) → zweite, unabhängige Unveränderbarkeitsspur neben audit_log. 🔲 Zielspeicher festlegen. |
| 6.3.3 | RTO / RPO (Wiederanlauf-Ziele). | Vorschlag (🔲 zu bestätigen): RPO ≤ 24 h (tägliches Backup) bzw. ≤ Minuten mit PITR; RTO ≤ 4 h für DB-Restore. Begründung: kleines Festteam, kein 24/7-Echtzeitbetrieb, aber operativ am Depot auf die App angewiesen → Tagesausfall tolerierbar, Mehrtages-Ausfall nicht. |
| 6.3.4 | Offline-Toleranz Feldteam (Verfügbarkeit am Container/Depot). | PWA installierbar + offline-tolerant: Cache + Queue (z. B. KYC-Bild/Quick-Entry werden lokal in IndexedDB gehalten und bei Reconnect synchronisiert) → kurzfristige Netzausfälle blockieren die Erfassung nicht; keine Datenverlust-Lücke. |
| 6.3.5 | Restore-Test. | 🔲 periodischer Restore-Probelauf (mind. jährlich) als Teil der Verfahrensdokumentation (GeBüV Art. 4) — bestätigt, dass Backups tatsächlich lesbar/wiederherstellbar sind. |
7. Buchhaltungs-Abgrenzung (was Caja ist — und was nicht)
| Anforderung | Umsetzung / Abgrenzung |
|---|---|
| Caja = operatives Vorsystem, nicht der rechtsgültige Abschluss. | Cash-Basis (Einnahmen/Ausgaben + Offene Posten), keine doppelte Buchführung. Caja speist die formale Buchhaltung über den Treuhänder-Export (CSV/Excel/PDF + MWST-Kennzahlen + Monats-/Jahresreport). Der rechtsgültige, unterzeichnete Jahresabschluss entsteht beim Treuhänder. |
| Klare Schnittstelle statt „fertige Buchhaltung". | Treuhänder-Export ist die einzige offizielle Ausgabe; verhindert die falsche Gewissheit, der App-Stand sei der finale Abschluss. Exportformat (Bexio/Abacus/Banana-CSV, Kontenrahmen KMU) 🔲 mit Treuhänder festzulegen. |
| MWST schema-ready, aktivierbar. | Siehe §3 — keine MWST-Werte vor Scharfschaltung; Methodenwahl ist Treuhänderentscheid. |
8. Sicherheits-Querschnitt (technische Härtung)
| # | Bereich | Massnahme in Caja |
|---|---|---|
| 8.1 | Authentifizierung | Internes Team via Azure Entra ID (SSO/OIDC, M365-Tenant) mit MFA; Affiliates/extern passwortlos (Supabase Magic-Link/E-Mail-OTP) → keine Passwort-Leaks; abgelaufene Links (Default 1 h) mit OTP-Fallback. 2FA aktiv (Entra-MFA bzw. TOTP für ADMIN/BUCHHALTUNG, Entscheid 2026-06-28 Teil 3; Modul 8 §4.1). |
| 8.2 | Autorisierung | RLS deny-by-default auf allen Tabellen; modulübergreifende „RLS-Grammatik" has_role()/is_internal()/current_affiliate_id(); jede neue Tabelle bringt ihre Policy mit (Review-Gate). |
| 8.3 | Least Privilege / Server-Trennung | service_role nur serverseitig (Edge-/Server-Functions) für Auto-Posting, Notifications, OCR-Download; nie im Client. Privilegierte Writes laufen nie über Client-Keys → Clients können quellen-erzeugte Buchungen nicht fälschen/löschen. |
| 8.4 | Secrets-Management | RESEND_API_KEY/RESEND_FROM/Supabase-Service-Key/OCR-Keys nur in Vercel-/Supabase-Env, nie im Repo; Key-Rotation erfordert Redeploy (Vercel snapshottet Env pro Deployment). |
| 8.5 | Fehler-Hygiene | Echte Provider-Fehler (Resend/Storage/OCR) bleiben in Server-Logs / notifications.error, nie roh im Client (gleiches Prinzip wie heutiges send-contact) → keine Leak-Oberfläche. |
| 8.6 | Storage-Sicherheit | Buckets privat (ausser public-assets); Pre-Signed URLs ≤ 60 min; signierte Upload-URLs; serverseitige mime_type/byte_size/bucket/doc_class-Validierung vor Persistenz (kein verwaister Storage). |
| 8.7 | Transport & At-Rest | TLS 1.2+ in-transit; AES-256 at-rest (Supabase) für DB + Storage. |
| 8.8 | Webhook-Integrität | WhatsApp-Cloud-API-Webhook validiert X-Hub-Signature-256 (HMAC); wa_message_id UNIQUE verhindert Doppelverarbeitung bei Retries. |
| 8.9 | Idempotenz / Anti-Duplikat | movements unique(source_type, source_id) (eine Buchung pro Event); notifications.dedupe_key unique (eine Mail pro Anlass) → kein Doppel-Posting/Doppel-Versand bei Races/Retries. |
| 8.10 | Audit-Abdeckung | fn_audit() an allen revisionsrelevanten Tabellen; zusätzlich action='login'/'export' protokolliert (wer hat wann exportiert/zugegriffen) → Forensik-Basis für Incident/Meldepflicht (§4.2 / 4.7). |
| 8.11 | CSP / Web-Härtung (Bestand) | Bestehende Website-Härtung (CSP, verifizierte Domain) wird in die App übernommen; sensible Aktionen serverseitig. |
9. Konsolidierte offene Punkte (🔲 zu bestätigen)
| # | Punkt | Bezug | Priorität | Klärung mit |
|---|---|---|---|---|
| 9.1 | ✅ ENTSCHIEDEN (2026-06-28, Teil 3) — OCR self-hosted auf eigener Proxmox-Infra (ocr_provider='SELF_HOSTED'): kein Cloud-/Drittland-Transfer der Ausweisbilder fürs OCR, kein OCR-DPA, Compliance-Plus. Verbleibend nur: konkrete Open-Source-Vision/OCR-Lösung 🔲 TBD (Betriebs-/Genauigkeits-Entscheid, keine Datenschutz-Frage mehr). | §4.3 / §4.4 | erledigt (Modell-Wahl offen) | GF |
| 9.2 | ✅ ENTSCHIEDEN (2026-06-28) — KYC-Aufbewahrungsfrist (Rohbild + Felder) = 24 Monate nach letzter Interaktion (kyc-retain_until = last_interaction_at + 24 M, rollierend); Rechtsgrundlage = Onboarding-Vertrag (Einwilligung) + Vertragserfüllung. Löst OE-11/F-21, kein Rechtsgutachten zur Frist mehr nötig. | §1.4 / §4.6 | — | erledigt |
| 9.3 | Datenschutzerklärung (KYC/Caja-Verarbeitung, Auftragsbearbeiter, Drittland) + In-App-Hinweis — Entwurf liegt vor: 46-datenschutz.md (revDSG). 🔲 Verbleibend: anwaltliche Schlussprüfung (revDSG-Spezialist), Platzhalter füllen, Publikation /datenschutz | §4.2 (4.5) / 46-datenschutz.md | Hoch | Rechtsberatung |
| 9.4 | ✅ ENTSCHIEDEN (2026-06-28) — Bearbeitungsverzeichnis instanziiert (Art. 12): gepflegtes Verzeichnis mit 7 Bearbeitungen (V1–V7) in §5 (Best-Practice-Default, finale juristische Abnahme ausstehend). Verbleibend: laufende Pflege durch GF bei Prozess-/Schemaänderungen. | §5 | erledigt (Pflege laufend) | GF |
| 9.5 | ✅ ENTSCHIEDEN (2026-06-28) — EU-Region verbindlich (Supabase eu-central-1 Frankfurt, Vercel fra1); DPA-Checkliste für Supabase/Vercel/Resend/Meta/Revolut in §4.3 (Best-Practice-Default). OCR entfällt (self-hosted). Verbleibend: DPAs physisch gegenzeichnen vor Produktivbetrieb. | §4.3 / §4.4.2 | erledigt (Zeichnung ausstehend) | GF |
| 9.6 | MWST: Methodenwahl (Saldosteuersatz vs. effektiv) + bewilligte(r) SSS-Satz/Sätze; Brutto/Netto-Konvention total_chf | §3.3 / §3.4 | Mittel (bis MWST-Eintritt) | Treuhänder/ESTV |
| 9.7 | Einfuhrsteuer/eVV-Modellierung (eigener movement_type und/oder vat_code=ZERO mit Vorsteuer) + Export-Kennzahlen | §3.5 | Mittel | Treuhänder |
| 9.8 | Treuhänder-Exportformat (Bexio/Abacus/Banana-CSV, Kontenrahmen KMU) + verlangte MWST-Kennzahlen | §7 | Mittel | Treuhänder |
| 9.9 | Backup-Ziele final: Supabase-Plan (PITR/Backup-Retention), Cold-Storage-WORM-Ziel, RTO/RPO bestätigen, jährlicher Restore-Test | §6.3 | Mittel | GF |
| 9.10 | GeBüV-Unveränderbarkeit extern bestätigen? (zusätzlicher Hash-Anker/Export-Siegel über App-Sperren hinaus) | §2 (Grenze) | Mittel | Revision/Treuhänder |
| 9.11 | Drittland-DR-Rechtsgrundlage der Empfänger-/Zoll-Datenbekanntgabe final dokumentieren (Vertragserfüllung vs. Einwilligung) | §4.4.1 | Mittel | Rechtsberatung |
| 9.12 | ✅ ENTSCHIEDEN (2026-06-28) — DSFA durchgeführt (Art. 22): Schwellenprüfung → KYC + Drittland = hohes Risiko → DSFA erstellt in §12; Restrisiko nach Massnahmen nicht hoch → keine EDÖB-Vorabkonsultation (Art. 23). Best-Practice-Default, finale juristische Abnahme ausstehend. | §4.2 (4.8) / §12 | erledigt | Rechtsberatung |
| 9.13 | ✅ 2FA ENTSCHIEDEN (2026-06-28, Teil 3): aktiv — internes Team via Entra ID SSO + MFA, mindestens TOTP für ADMIN/BUCHHALTUNG. Auth-Provider: Entra ID (intern) + Supabase Auth (extern/Affiliate). | §8.1 / Modul 8 §4.1 | erledigt | — |
| 9.14 | ✅ ENTSCHIEDEN (2026-06-28) — Incident-Runbook ausformuliert (Art. 24, EDÖB): Schritt-für-Schritt Erkennung→Bewertung→Meldung→Betroffene→Doku in §11 (Best-Practice-Default, finale juristische Abnahme ausstehend). Verbleibend: jährlicher Tabletop-Test + Anwalts-Review. | §4.2 (4.7) / §11 | erledigt | GF + Rechtsberatung |
| 9.15 | MWST-/Revisionspflicht-Schwelle effektiv: ab wann scharf? (Umsatz, opting-out Revision) | §0 | Mittel | Treuhänder |
10. Compliance-Verantwortlichkeiten (RACI, knapp)
| Aufgabe | Marcel (GF/ADMIN) | Mariela (Buchhaltung) | Treuhänder | Rechtsberatung |
|---|---|---|---|---|
| Periodensperre setzen/reopen | R/A | C | I | — |
| Treuhänder-Export erzeugen | A | R | C | — |
| MWST-Methodenwahl | A | C | R | C |
| Bearbeitungsverzeichnis pflegen | R/A | C | — | C |
| DPAs gegenzeichnen | R/A | I | — | C |
KYC-Löschungen freigeben (ADMIN) | R/A | I | — | C |
| Datenschutzerklärung | A | I | — | R |
| Incident/EDÖB-Meldung | R/A | I | I | C |
| Backup/Restore-Test | R/A | I | I | — |
R = Durchführung, A = Rechenschaft, C = beizuziehen, I = informiert. Operative Tagesarbeit (Buchungen, Scans, Sendungen) erzeugt die Compliance-Artefakte automatisch (Auto-Posting →
movements, Mutation →audit_log, Beleg →storage_objects); die menschliche Verantwortung konzentriert sich auf Abschluss, Freigaben und die rechtliche Pflege (Verzeichnis, DPAs, Datenschutzerklärung).
11. Incident-Runbook — Meldung Datensicherheitsverletzung (Art. 24 revDSG)
✅ Ausformuliert (Best-Practice-Default, finale juristische Abnahme ausstehend). Operatives Runbook für eine Verletzung der Datensicherheit (unbefugter Zugriff/Verlust/Offenlegung von Personendaten) nach Art. 24 revDSG und dem EDÖB-Leitfaden zur Meldung von Datensicherheitsverletzungen. Kern-Regel: Meldung an den EDÖB „so rasch als möglich", wenn die Verletzung voraussichtlich zu einem hohen Risiko für die Persönlichkeit oder die Grundrechte der betroffenen Personen führt. Anders als die DSGVO kennt das revDSG keine fixe 72-Stunden-Frist — Massstab ist das Ausmass der Gefährdung (je grösser, desto schneller). Meldeportal: databreach.edoeb.admin.ch.
Rollen: Incident-Lead = Marcel (GF/ADMIN) (R/A), Beizug Rechtsberatung (C) bei Risiko-Einstufung/Meldung, Mariela (I).
11.1 Schritt-für-Schritt
| Phase | Schritt | Wer | Zeitziel |
|---|---|---|---|
| 1 · Erkennung | Quelle: Supabase-/Vercel-Logs, Auth-Anomalien (fehlgeschlagene Logins, ungewöhnliche Exporte via action='export'/'login' im audit_log), Provider-Sicherheitswarnung, Hinweis Betroffener/Dritter. Jeder Verdacht wird sofort an den Incident-Lead eskaliert. | alle / Lead | sofort |
| 2 · Eindämmung & Sicherung | Zugang sperren (Key-Rotation Supabase-Service-Key/Resend/OCR; Session-Invalidierung; ggf. betroffene Buckets sperren). Forensik sichern: relevante audit_log-Zeilen + Provider-Logs exportieren und WORM-ablegen (Beweissicherung, unveränderbar). | Lead | unmittelbar |
| 3 · Bewertung (Triage) | Feststellen: Was (Datenkategorien — sind besonders schützenswerte Ausweisdaten betroffen?), wie viele Betroffene, Eintrittswahrscheinlichkeit eines Schadens, Schweregrad. Daraus die Schlüsselfrage: „voraussichtlich hohes Risiko"? Hilfsmatrix §11.2. | Lead + Recht (C) | Stunden |
| 4 · EDÖB-Meldung | Wenn hohes Risiko bejaht: Meldung so rasch als möglich über databreach.edoeb.admin.ch mit Mindestinhalt (Art. 24 Abs. 2): (a) Art der Verletzung, (b) Folgen für die Betroffenen, (c) ergriffene/vorgesehene Massnahmen. Unvollständige Erstmeldung ist zulässig → Nachmeldung, sobald mehr bekannt. | Lead | so rasch als möglich |
| 5 · Information Betroffener | Betroffene informieren nur, wenn es zu ihrem Schutz erforderlich ist oder der EDÖB es verlangt (Art. 24 Abs. 4) — z. B. wenn sie selbst Schutzmassnahmen ergreifen müssen. Klartext-Info: was passiert ist, welche Daten, was zu tun ist, Kontaktstelle. | Lead | nach EDÖB-Meldung / auf Verlangen |
| 6 · Dokumentation & Lessons Learned | Alle Verletzungen (auch nicht meldepflichtige) intern dokumentieren: Hergang, Bewertung, Entscheid (gemeldet/nicht — mit Begründung), Massnahmen. Ablage WORM. Anschliessend Massnahmen härten (Ursachenbehebung). | Lead | innert Tagen |
11.2 Risiko-Triage (Hilfsmatrix — „voraussichtlich hohes Risiko"?)
| Indikator | Eher kein hohes Risiko | Hohes Risiko (→ EDÖB melden) |
|---|---|---|
| Datenkategorie | nur verschlüsselte/pseudonyme oder rein technische Daten | besonders schützenswerte Ausweisdaten (Cédula/Pass, Lichtbild), Finanzdaten im Klartext |
| Verschlüsselung | exfiltrierte Daten stark verschlüsselt, Schlüssel nicht kompromittiert | Daten im Klartext / Schlüssel ebenfalls betroffen |
| Umfang | Einzelfall, eng begrenzt | viele Betroffene / ganzer Bucket / Datenbank |
| Schadenpotenzial | kein realistischer Nachteil | Identitätsmissbrauch, Diskriminierung, finanzieller Schaden möglich |
Default bei Unsicherheit: Im Zweifel eher melden und Rechtsberatung beiziehen. Verschlüsselung at-rest (AES-256) ist ein risikomindernder Faktor, entbindet aber nicht automatisch von der Meldung, wenn Schlüssel/Zugang ebenfalls betroffen sein könnten.
Selbstbelastungs-Schutz (Art. 24 Abs. 6): Eine Meldung an den EDÖB darf in einem Strafverfahren gegen die meldepflichtige Person nur mit deren Einverständnis verwendet werden — die Meldepflicht schafft also kein Selbstbelastungsrisiko und ist ohne Zögern zu erfüllen.
Auftragsbearbeiter (Art. 24 Abs. 3): Auftragsbearbeiter (Supabase/Vercel/Resend/Meta/Revolut) müssen Dominicano Express eine Verletzung „so rasch als möglich" melden → diese Pflicht ist in den DPAs (§4.3) sicherzustellen; danach läuft obiges Runbook.
12. Datenschutz-Folgenabschätzung (DSFA) — KYC-Ausweisbearbeitung (Art. 22 revDSG)
✅ Schwellenprüfung durchgeführt + DSFA erstellt (Best-Practice-Default, finale juristische Abnahme ausstehend). Grundlage: Art. 22 revDSG und die DSFA-Information des EDÖB.
12.1 Schwellenprüfung (ist eine DSFA nötig?)
Eine DSFA ist erforderlich, wenn eine Bearbeitung voraussichtlich ein hohes Risiko für Persönlichkeit/Grundrechte mit sich bringt. Art. 22 Abs. 2 nennt als Regelbeispiel u. a. die umfangreiche Bearbeitung besonders schützenswerter Personendaten.
| Kriterium | Befund Caja |
|---|---|
| Besonders schützenswerte Daten? | Ja — Ausweisdaten (Cédula/Pass, Geburtsdatum, Nationalität, Lichtbild) = Art. 5 lit. c |
| Umfang/Volumen | wachsende Kundenbasis, KYC für jede Vertragspartei → potenziell umfangreich |
| Risikoerhöhende Umstände | Drittland-Transfer in die DR (kein Angemessenheitsbeschluss); Identifikationsmerkmale (Missbrauchspotenzial) |
| Neue Technologien | OCR/automatisierte Extraktion aus Ausweisbild |
➡️ Ergebnis: DSFA erforderlich (vorsorglich bejaht — Best-Practice-Default).
12.2 Beschreibung der Bearbeitung (Art. 22 Abs. 3)
KYC-Onboarding: Kunde übermittelt Ausweis (WhatsApp/Upload) → self-hosted OCR extrahiert Pflichtfelder → Speicherung in kyc_scans/kyc-Bucket (Supabase EU) → für Zoll/Empfänger-Matching genutzt; zollrechtlich nötige Felder werden in die DR bekanntgegeben. Details: 11-whatsapp-ocr.md, Verzeichnis §5 (V2).
12.3 Risikobewertung & Massnahmen
| Risiko | Inhärentes Risiko | Mitigierende Massnahme (Caja) | Restrisiko |
|---|---|---|---|
| Unbefugter Zugriff auf Ausweisdaten | hoch | RLS deny-by-default (nur ADMIN/OPERATIONS/BUCHHALTUNG); AES-256 at-rest; private Buckets; Pre-Signed URLs ≤ 60 min; 2FA/MFA | tief |
| Drittland-Transfer DR (kein Angemessenheitsbeschluss) | hoch | Einwilligung (Onboarding) + Vertragserfüllung (Art. 17); nur zollrechtlich Nötiges; keine Lichtbild-Weitergabe an Zoll | mittel (durch Einwilligung/Datenminimierung getragen) |
| OCR-Verarbeitung in Drittland/Cloud | hoch | self-hosted (Proxmox, in-house) → kein Transfer des Ausweisbildes; OCR-Rohantwort nach 90 Tagen NULL | tief |
| Übermässige Aufbewahrung | mittel | 24-Monate-Frist nach letzter Interaktion (rollierend, §4.6); Lifecycle-Job + Lösch-Guard | tief |
| Datenminimierung | mittel | OCR extrahiert nur Pflichtfelder; Rohbild kürzestmöglich; Exporte minimal | tief |
| US-Auftragsbearbeiter (Supabase) | mittel | EU-Region (eu-central-1); SCC in DPA; Service-Key serverseitig | tief |
12.4 Befund & EDÖB-Konsultation (Art. 23)
✅ Gesamtbefund: Nach Umsetzung der Massnahmen ist das Restrisiko nicht mehr hoch. Damit ist keine Vorabkonsultation des EDÖB nach Art. 23 revDSG erforderlich (diese wäre nur bei verbleibend hohem Restrisiko trotz Massnahmen nötig; alternativ entfällt sie ohnehin, wenn eine Datenschutzberatung konsultiert wurde). Die DSFA ist lebend zu halten und bei wesentlichen Änderungen (z. B. Wechsel zu Cloud-OCR, neuer Empfänger, massive Volumensteigerung) zu aktualisieren. Finale juristische Abnahme durch revDSG-Spezialist ausstehend.