2.1 KiB
2.1 KiB
S4.4 — JSON-to-relational importer
Date: 2026-08-15 Status: local importer complete; production apply/cutover blocked and not performed
Scope
- Added
backend/scripts/migrate_json_to_postgres.py. - Added
backend/tests/test_json_import.py. - Added
docs/runbooks/json-to-postgres.md.
The importer covers orgs, users, groups/personas, sessions/messages, and legacy my_personas converted into deterministic owner-private groups. A non-empty audit/audit.jsonl is rejected rather than silently dropped; audit migration remains part of the S4.6 PostgreSQL audit-store gate.
Safety behavior
- Dry-run is the default.
--applyrequires an explicit target database URL and a new backup directory.- Full source graph is validated before target writes.
- Existing identical rows are unchanged; conflicting target rows abort without overwrite.
- Source JSON remains untouched; backup is created before the target transaction.
- Cross-tenant references, duplicate IDs/uniqueness keys, malformed scalars, invalid timestamps, oversized files, and symlinks fail closed.
- Output is metadata-only: mode, source checksum, counts, and backup status. Password hashes and payloads are never printed.
TDD / verification
- RED: importer test collection failed before the script existed (
ModuleNotFoundError). - GREEN: importer tests
6 passed. - Direct CLI smoke:
python scripts/migrate_json_to_postgres.py --helppassed after adding standalone backend-path bootstrap. - Covered: dry-run no-write, apply counts, deterministic private group conversion, second-run idempotency, payload redaction, backup creation, cross-tenant rejection, non-empty audit rejection, malformed scalar rejection, and target-conflict no-overwrite.
- Full backend suite after the packet:
193 passed. - Compileall, diff-check, and added-line security scan passed (
added_line_findings=[]).
Explicit blockers
- PostgreSQL service and real target migration are unavailable/unverified locally.
- Audit/rate-limit PostgreSQL/Redis storage is not implemented.
- Importer apply is not production approval; no live data, credentials, deploy, or cutover was touched.