# CMP-02 – Prüfprotokoll: DSGVO-/Datenschutz-Berichte Voraussetzung RET-01 – bereits Fertig. ## Vorab identifizierte und geklärte Design-Lücke RET-01 (`retention_objects`) führte bislang keine Zuordnung zu einer "betroffenen Person" — nur `object_type`/`object_reference` (opake modulübergreifende Referenz). Ein Auskunftsbericht "aller Objekte einer Person" war damit strukturell unmöglich. Nach Nutzerentscheidung (Option 1) additiv gelöst: - `archive/migrations/0009_data_subject_ref.up.sql` — nullable Spalte `retention_objects.data_subject_ref` + Index. - `archive/internal/retention.RegisterObjectForSubject` — NEUE, additive Funktion. `RegisterObject` (RET-01) bleibt UNVERÄNDERT (kein Diff), kein bestehender Aufrufer betroffen (Codeprüfung: `RegisterObject` hatte ohnehin nur Testaufrufer, keine Produktionsverdrahtung). - Leeres `data_subject_ref` bedeutet "nicht personenbezogen", kein Fehlerzustand (z. B. Systemkonfigurationsobjekte). ## Umsetzung - `archive/internal/dpreport.SubjectReport` – Auskunftsbericht (Akzeptanzkriterium 1), nutzt dieselbe "jüngste Zuordnung"-Logik wie RET-02 (DISTINCT ON), keine zweite Berechnung. - `archive/internal/dpreport.ProcessingOverview` – Verarbeitungsübersicht je tatsächlich vorkommendem Objekttyp (Akzeptanzkriterium 2), Zweck/ Rechtsgrundlage statisch gepflegt (`ProcessingPurposes`) — Rechts- bewertungen sind keine aus Nutzdaten ableitbaren Werte. - `archive/internal/dpreport.WriteSubjectReportCSV` – CSV-Export (Akzeptanzkriterium/Pflichtprüfung 3). - **Mandantentrennung (Akzeptanzkriterium 3):** strukturell garantiert durch Modell C — `SubjectReport` läuft immer gegen GENAU EINEN Tenant-Pool, kein Cross-Tenant-Query technisch möglich. ## Prüfungen | # | Prüfung | Ergebnis | |---|---|---| | 1 | Auskunftsbericht für Testperson mit bekanntem Datenbestand stimmt mit erwarteter Liste überein | **bestanden** – `TestSubjectReport_MatchesKnownDataset`: 3 Objekte für 2 Personen angelegt, Bericht für Person A liefert exakt die 2 erwarteten Objekte (nicht das dritte, das Person B gehört), inkl. korrekter Aufbewahrungsklasse | | 2 | Bericht für einen Tenant enthält keine Objekte eines anderen Tenants | **bestanden** – `TestSubjectReport_TenantIsolation`: real gegen ZWEI PHYSISCH GETRENNTE Tenant-Datenbanken (`tenant_acme`, `tenant_globex`) getestet, nicht nur zweimal dieselbe DSN — Objekt in Tenant A angelegt, Bericht für dieselbe `data_subject_ref` gegen Tenant B liefert 0 Treffer | | 3 | Export lässt sich als CSV weiterverarbeiten | **bestanden** – `TestWriteSubjectReportCSV_IsParseable`: echte CSV-Ausgabe erzeugt und geparst, Header + genau eine Datenzeile | **Hinweis zur Testkorrektur:** Der erste Testlauf von Prüfung 2 nutzte versehentlich denselben `TEST_TENANT_DSN` für beide "Tenants" (dieselbe physische Datenbank) und schlug dadurch zurecht fehl — kein Code-Defekt, sondern ein Testfehler. Korrigiert auf zwei echte, unabhängige Tenant-Datenbanken (`TEST_TENANT_DSN_B`), danach real bestanden. ## Build/Test-Ergebnis (192.168.1.131) ``` go build ./... -> clean go vet ./... -> clean golangci-lint run ./... -> 0 issues go test ./... -p 1 -> alle Archive-Pakete bestanden (inkl. dpreport, retention) ``` Migration `0009_data_subject_ref` real auf `dms_tenant_test` angewendet. ## Gesamtergebnis **Bestanden.** Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt, inklusive einer vorab identifizierten und mit dem Nutzer geklärten strukturellen Lücke (fehlende Personen-Zuordnung in RET-01), additiv und ohne Änderung an bestehendem Verhalten geschlossen.