0eefbfd6a4
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 16s
CI / ui (pull_request) Has been skipped
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 2m2s
An account merge blanket-reassigned all of the secondary's identities to the primary, so merging two accounts that each had a confirmed email (or telegram/vk) left the survivor with two identities of one kind — which the profile and the retention dossier both treat as singular (the profile showed an arbitrary one; a later change-email journaled only one). The merge now keeps the primary's identity and journals the secondary's colliding one to retained_identities (reason=merge) before dropping it, so the survivor has one identity per kind and the absorbed credential still lands in the legal dossier. - migration 00008: widen retained_identities.reason CHECK to admit 'merge' (expand-contract — Up only widens the set, so an image rollback stays DB-safe). - accountmerge: dedupeIdentities + retainMergedIdentity before the identity reassign. - inttest TestAccountMergeDedupesEmail; docs ARCHITECTURE §4 + retention.go reason note.
23 lines
1.4 KiB
SQL
23 lines
1.4 KiB
SQL
-- Admit the 'merge' reason into retained_identities. An account merge folds a secondary
|
|
-- account into a primary; when both hold an identity of the same kind (e.g. each has a
|
|
-- confirmed email), the survivor keeps its own and the secondary's is journaled to the
|
|
-- legal dossier and removed — so the survivor never ends up with two identities of one
|
|
-- kind, and the absorbed credential is still retained. That journal row carries reason
|
|
-- 'merge', alongside the existing unlink / change / delete.
|
|
--
|
|
-- Expand-contract: the Up only WIDENS the allowed reason set, so an older backend image
|
|
-- (which writes only unlink/change/delete) still satisfies the constraint — a rollback
|
|
-- stays DB-safe. The Down narrows it again and would reject pre-existing 'merge' rows, so
|
|
-- it is a dev-only convenience, not a production rollback path (image rollback runs old
|
|
-- code against this schema, not the Down migration).
|
|
|
|
-- +goose Up
|
|
ALTER TABLE backend.retained_identities DROP CONSTRAINT retained_identities_reason_chk;
|
|
ALTER TABLE backend.retained_identities ADD CONSTRAINT retained_identities_reason_chk
|
|
CHECK ((reason = ANY (ARRAY['unlink'::text, 'change'::text, 'delete'::text, 'merge'::text])));
|
|
|
|
-- +goose Down
|
|
ALTER TABLE backend.retained_identities DROP CONSTRAINT retained_identities_reason_chk;
|
|
ALTER TABLE backend.retained_identities ADD CONSTRAINT retained_identities_reason_chk
|
|
CHECK ((reason = ANY (ARRAY['unlink'::text, 'change'::text, 'delete'::text])));
|