feat(data): tenant data import - envelope validation + id-remap core (PMS-648) #439
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/PMS-648-data-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?
Backend import for PMS-646, sibling of the PMS-647 export (#438). Built in two commits so each piece is verified at the level it can be:
Stacking
This branch is stacked on
feat/PMS-647-data-export(#438); it reuses that module's exclude/redaction consts. Until #438 merges, this PR shows the export commits too; it auto-cleans to just the import diff once #438 lands. Merge #438 first.Commit 1 (this) - validated, locally verified
POST /api/v1/data/import(admin-only): 25 MB body cap (413 over-size), validatesschema_version, rejects any unexpected/excluded table, checks the tenant-name confirmation, and computes the global old-id -> new-id remap over every row (so a malformed file fails during validation). Returns a dry-run summary and performs NO mutation.The security-relevant, order-independent core is pure and unit-tested (
build_id_map,remap_row): fresh id per row, pk/FK/tenant rewrite, and unrelated UUIDs left untouched.just pre-commitgreen (271 tests).Commit 2 (next, this branch) - DB load, CI-verified
The destructive wipe-and-replace load: derive the FK-dependency topological order from the catalog, wipe the tenant's in-scope tables, load the remapped rows in dependency order (with self-referential-FK and dangling user-reference handling), emit the
importaudit action, and return the per-table summary - all in one transaction. This can only be exercised against Postgres, so it is validated by a round-trip integration test (tests/*.rs, run by CIintegration.yml): export a seeded tenant (PMS-647) -> import -> assert structure matches and no secret substrings appear in the exported bytes.#PMS-648