feat(gdpr): fullständig raderingsflöde med pseudonym-retention, residual-test och hushållshantering

- Implementerar eraseUser() i packages/database/src/gdpr-erasure.ts som
  raderar/anonymiserar/pseudonymiserar alla personliga tabeller.
- DELETE /v1/me orkestrerar nu plan + transaktion + lagringsrensning.
- Enpersonshushåll raderas automatiskt; publika recept anonymiseras;
  draft/private-recept raderas.
- Finansiella poster (subscriptions/store_transactions/subscription_events)
  behålls under retention med slumpmässig pseudonym från
  gdpr_retention_pseudonyms.
- audit_logs/domain_events anonymiseras; kvitton i kvarvarande hushåll
  strippas på bild och OCR-text.
- Lägger till permanent residual-test (me.residual.test.ts) med
  schema-diff-assertion mot information_schema.
- Uppdaterar docs/23 och docs/29 med implementerad mekanism.
- Migration 0021 för gdpr_retention_pseudonyms och nullable
  cooking_sessions.started_by_user_id.
This commit is contained in:
Sven (AAMOS AI)
2026-08-08 05:45:49 +07:00
parent 1d78dbcad0
commit ddd6b736ba
14 changed files with 11183 additions and 79 deletions
+28
View File
@@ -54,6 +54,34 @@ Uppgifter lagras inom EU/EES ({REGION}). Automatisk gallring: säkerhetstokens
7 dagar, återkallade sessioner 30 dagar, skanningsjobb och notiser 90 dagar,
tillfälliga bilder 7 dagar. Backuper roteras enligt driftpolicy.
### GDPR-radering och bokföringsretention
När en användare begär radering (`DELETE /v1/me`) raderas eller anonymiseras
allt personligt innehåll omedelbart. Undantag görs endast för uppgifter som
måste bevaras enligt lag, särskilt bokföringslagen och skatterättsliga krav:
- **Prenumerationer, betaltransaktioner och prenumerationshändelser** behålls
under retentionstiden (7 år), men `user_id` ersätts med en slumpmässig
pseudonym i tabellen `gdpr_retention_pseudonyms`. Mappningen mellan
pseudonym och användaridentitet raderas automatiskt när retentionstiden
löper ut.
- **Audit logs** behålls i 2 år för säkerhets- och spårbarhetsskäl, men
aktörsidentitet (`actor_user_id`) och IP-adress anonymiseras.
- **Domänevent** behålls för event-sourcing, men `user_id` anonymiseras och
payload skrubbas.
- **Kvitton i kvarvarande hushåll** (flerpersonshushåll) behålls för
hushållsbudgeten, men kvittobilder raderas och radernas OCR-text töms.
Pseudonymiseringen innebär att posterna inte längre är direkt hänförbara till
en fysisk person utan att separat register konsulteras. Endast behöriga
administratörer med bokföringssyfte kan, under strikt åtkomstkontroll,
återsöka den ursprungliga användaren under retentionstiden. Efter retentionstid
förvandlas pseudonymen till en permanent icke-identifierbar etikett.
> **Fastställ med jurist:** exakt retentionstid per jurisdiktion, krav på
> åtkomstloggning för `gdpr_retention_pseudonyms`, och om pseudonymisering
> räcker som "så långt som möjligt" åtgärd enligt art. 25.
### Mottagare
Driftleverantörer (AWS {REGION}), AI-drift (AAMOS) samtliga under
+1 -1
View File
@@ -2,7 +2,7 @@
> **Syfte:** identifiera varje tabell som bär `user_id` eller annan persondata, klassa den enligt GDPR, hitta luckor mot nuvarande `DELETE /v1/me`, och designa ett permanent residual-test.
>
> **Status:** audit-dokument. **Ingen kodändring** är gjord i denna leverans. Väntar på godkännande av klassningen innan implementation.
> **Status:** ✅ Implementerad i efterföljande commits. Residual-testet `apps/api/test/me.residual.test.ts` ingår permanent i `pnpm test` och failar automatiskt om nya `user_id`-liknande kolumner läggs till utan klassning.
>
> **Audit gjord mot:**
> - `packages/database/src/schema/*.ts`