
# GDPR & Privacy

Sovrium gives end users self-service control over their personal data, satisfying the core GDPR rights without operator intervention. An authenticated user can download a complete, machine-readable copy of everything Sovrium holds about them, and can schedule an irreversible erasure of their account on a safe, reversible-until-final timeline.

These are end-user endpoints — they act on the caller's own data, scoped exclusively by the authenticated session. No id is ever taken from the request body.

## Data Export (Articles 15 & 20)

`GET /api/account/export` returns the caller's complete personal-data footprint as structured JSON, satisfying the GDPR **right of access** (Art. 15) and **right to data portability** (Art. 20).

```
GET /api/account/export
Cookie: <session cookie>
```

No request body, query, or path parameters — the user id comes only from the session. The response aggregates four sources for the caller:

| Source               | Contents                                                                                                              |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| **Profile**          | The caller's `auth.user` row.                                                                                         |
| **Sessions**         | The caller's `auth.session` rows.                                                                                     |
| **Linked accounts**  | The caller's `auth.account` rows (OAuth providers + email/password credential), **with all secret material omitted**. |
| **Authored records** | Every table record across the app where `created_by = caller`.                                                        |

:::callout
**Secrets are never exported.** Password hashes, OAuth tokens, and other credential material are stripped from the linked-accounts section. The export is a portability artifact, not a credential dump.
:::

## Account Deletion & Erasure (Article 17)

`POST /api/account/delete` lets a user request irreversible erasure of their account, satisfying the GDPR **right to erasure** (Art. 17). Deletion follows a **scheduled-erasure model with a 7-day grace period** — never an immediate destroy.

```
POST /api/account/delete
Cookie: <session cookie>
Content-Type: application/json

{ "confirm": true }
```

| Step            | Request                     | Effect                                                                                                                                                                                                                    |
| --------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1. Schedule** | `{ "confirm": true }`       | Marks `scheduledErasureAt = now + 7 days`, revokes all of the caller's sessions (logged out everywhere), writes an `account.deletion.scheduled` audit event, returns `202 Accepted`. **Does not delete yet.**             |
| **2. Cancel**   | `{ "cancel": true }`        | During the window, the user signs back in and cancels — clears `scheduledErasureAt`, returns `200 OK`.                                                                                                                    |
| **3. Purge**    | _(automatic, after window)_ | A purge job **hard-deletes** the caller's `auth.user`, `auth.session`, `auth.account`, `auth.verification` rows and every table record where `created_by = caller`, then writes an `account.deletion.purged` audit event. |

A bare `POST` with no `confirm`/`cancel` flag is rejected `400` (anti-fat-finger).

## Hard Delete, Not Soft Delete

Erasure performs **physical row removal** — not the soft-delete `deleted_at` tombstone used elsewhere in the platform. After the purge, no recoverable personal data remains, as Art. 17 requires.

This is the deliberate exception to Sovrium's [soft-delete-by-default](/en/docs/records-soft-delete) posture: ordinary deletes are recoverable tombstones, but a GDPR erasure must leave nothing behind. Per-table irreversible deletes via the admin dashboard require the explicit `allowForceDelete: true` opt-in (see [Table Permissions](/en/docs/table-permissions)); the force-delete endpoint returns `404` when force-delete is not allowed.

:::callout
**The audit trail of erasure outlives the user.** The `account.deletion.purged` event survives the deleted user row — the `audit_log.actor_id` foreign key is `ON DELETE SET NULL`, so the entry remains a valid compliance record with a null-ified actor. Deleting the data and proving the data was deleted are two separate obligations.
:::

## Privacy by Design

Beyond the self-service rights, privacy is built into the platform defaults:

- **Cookie-free analytics** — visitors are identified by server-side SHA-256 hashes; no PII or client identifier is stored, and Do Not Track is respected. See [Analytics](/en/docs/analytics).
- **Bounded retention** — soft-deleted rows age out per `ECO_RETENTION_PURGE_DAYS` (see [Ecoconception](/en/docs/ecoconception)); less stored data is both a privacy and a frugality win.
- **No external services** — all personal data stays on your server; nothing is shipped to a third party.

## Related Pages

- [Activity Monitoring](/en/docs/activity-monitoring) — the audit trail of deletion and access events.
- [Soft Delete](/en/docs/records-soft-delete) — the recoverable tombstone model erasure deliberately bypasses.
- [Table Permissions](/en/docs/table-permissions) — `allowForceDelete` and field-level access.
- [Security Hardening](/en/docs/security-hardening) — auth, CSRF, anti-enumeration.
- [Analytics](/en/docs/analytics) — cookie-free, privacy-first tracking.
- [Ecoconception](/en/docs/ecoconception) — data retention and minimisation.
