-- Account deletion as legal retention (not erasure). Two additive pieces. -- -- retained_identities is an append-only journal of every credential detached from an -- account — on unlink, email change, or account deletion (reason). It preserves the legal -- dossier (which email/vk/tg was linked, and when) while the live identities row is -- removed, so the (kind, external_id) frees for a new account to reuse. No unique -- constraint and no kind CHECK: the same credential may recur across accounts and events, -- and the log stays robust to future identity kinds. detached_at drives the retention TTL. -- -- accounts gains: last_login_at / last_login_ip (stamped on a cold app-load, throttled), -- deleted_at (the tombstone marker), and deleted_display_name (the real name retained for -- the admin dossier after the live display_name is scrubbed to the anonymised label). -- -- Expand-contract: everything is additive (a new table plus nullable columns), so a -- backend image rollback stays DB-safe — older code simply ignores them. The accounts -- table shape changes, so its generated go-jet model is regenerated. -- +goose Up CREATE TABLE backend.retained_identities ( retained_id uuid NOT NULL, account_id uuid NOT NULL, kind text NOT NULL, external_id text NOT NULL, confirmed boolean DEFAULT false NOT NULL, linked_at timestamp with time zone NOT NULL, detached_at timestamp with time zone DEFAULT now() NOT NULL, reason text NOT NULL, CONSTRAINT retained_identities_pkey PRIMARY KEY (retained_id), CONSTRAINT retained_identities_reason_chk CHECK ((reason = ANY (ARRAY['unlink'::text, 'change'::text, 'delete'::text]))) ); CREATE INDEX retained_identities_account_id_idx ON backend.retained_identities (account_id); CREATE INDEX retained_identities_detached_at_idx ON backend.retained_identities (detached_at); ALTER TABLE backend.accounts ADD COLUMN last_login_at timestamp with time zone, ADD COLUMN last_login_ip text, ADD COLUMN deleted_at timestamp with time zone, ADD COLUMN deleted_display_name text; -- +goose Down ALTER TABLE backend.accounts DROP COLUMN last_login_at, DROP COLUMN last_login_ip, DROP COLUMN deleted_at, DROP COLUMN deleted_display_name; DROP TABLE backend.retained_identities;