fix(data): defer FK checks so tenant import survives cyclic schema #442
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/PMS-648-deferrable-fk-import"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Fixes the tenant data import (
POST /api/v1/data/import) so wipe-and-replace works over the schema's cyclic, self-referential, and NOT-NULL foreign keys. Root cause: FK checks fire at statement end, so no single wipe/load order satisfies FK cycles (companies.primary_contact_id <-> contacts.company_id), self-refs (tasks.parent_task_id), or the excluded secret/audit/token tables that reference load tables. The round-trip integration test surfaced this twice (first thetenants->companiesRESTRICT FK, then thework_types <- rate_card_itemscycle).How
migrations/088_deferrable_fk_constraints.sqlmakes every public FKDEFERRABLE INITIALLY IMMEDIATE(idempotent; per-statement checking unchanged for all normal operations - only a transaction that explicitly runsSET CONSTRAINTS ALL DEFERREDdefers them). The import now:SET CONSTRAINTS ALL DEFERREDinside its transaction,users,user_sessions, which are referenced BY business rows rather than referencing them), which clears both the load tables and the excluded secret/audit/token tables that FK-reference load rows so nothing non-reloaded dangles at commit,jsonb_populate_recordset,tenants -> load-tablereferences (own_company_id) to the new ids.All FK checks fire once at COMMIT, so order no longer matters. This deletes the
topo_orderKahn sort (+ its unit test) and the pre-wipe tenants-FK-NULL workaround from #441.Testing
just pre-commitgreen (fmt / clippy -D warnings / compile --all-targets / unit / doc).tests/data_transfer.rs(removes the#[ignore]); the export/import round-trip now runs in the Integration job, which is the only runtime validator of the import path. Integration must go green before merge.Note: wiping the excluded secret/audit/token tables on import is intentional wipe-and-replace semantics - the operator re-enters secrets after a restore; the export never contained them.
#PMS-648