← all branches

feat/sites-1n

needs attentionviewing older commit
8fa38b5 · incrementalpre-PRreviewed 2026-07-08 01:45 UTC2H · 4M · 5L · 1I
The branch
Purpose
Fix the Site↔RPU relationship: stop fusing unrelated RPUs onto one site (dedup only when internal ID AND name match; never default site name to service name). Provide UX to see and manage the 1:N relationship.
Goal
Make the Site↔RPU relationship correct, visible, and manageable with a one-shot remediation script to fix existing merged sites post-merge.
Sub-goals
  • SG-1: Shared site-resolution decision + rewire both coordinators (composite dedup)
  • SG-2: Site match/search extended with internal ID match + contractCount
  • SG-3: createFromWizard accepts existingSitePublicId
  • SG-4: Drawer match-driven Crear/Usar-existente with picker
  • SG-5: Site cell pencil → SiteEditModal (edit/move/split)
  • SG-6: Agrupar-por-sitio toggle with site rows
  • SG-7: Batch preview grouped by (internal id + name) with existing-site flags
  • SG-8: 4 typed analytics events + cross-domain CLAUDE.md
  • Remediation: split-merged-sites.ts one-shot script (authored on-branch, executed post-merge)
The changes (whole branch)
What
This commit adds pre-execution validation to split-merged-sites.ts: (1) per-org census printout from the live DB, (2) durable JSON snapshot to CWD for audit/rollback, (3) interactive 'type split' confirmation gate with --yes bypass. Runbook doc updated to describe the snapshot artifact.
Why
Operators need to validate current DB state before executing the irreversible 1→N site split. The snapshot provides an audit trail and rollback complement (split_from complement field); the confirmation gate prevents accidental execution.
Areas
scripts+3570apps/platform+1192163domains/cross-domain+352129domains/core+331domains/utility+615packages/api + analytics+634docs/development+3241
Blast
26 files, +2,228/−471 branch-wide. Incremental window (this commit): 2 files, +84/−1 in scripts + docs only.
one-shot irreversible script high-stakes prod operation snapshot timing concern stale count in confirmation prompt
CI (no PR yet)· Branch has no open PR — CI status not availableCodeRabbit· No .coderabbit.yaml in repo

Findings · 12

correctness2

medium

Snapshot mode:'execute' written before confirmation — misleads on aborted runs

scripts/split-merged-sites.ts:280

Snapshot JSON written before the interactive prompt. If operator runs --execute but declines at 'type split', the file already has mode:'execute'. An auditor sees a misleading record.

low

Snapshot silently overwritten on same-second re-run

scripts/split-merged-sites.ts:274

Two invocations within the same second produce the same filename; writeFileSync overwrites without warning.

security3

medium

Snapshot written to CWD — full org/site/RPU inventory may be exposed on shared hosts

scripts/split-merged-sites.ts:283

Relative path anchored to process.cwd(). On a shared EC2 host the file is world-readable by default. Fix: writeFileSync(path, data, { mode: 0o600 }).

low

--yes bypasses TTY check and confirmation with no audit trail in snapshot

scripts/split-merged-sites.ts:318

If injected into a CI invocation, the irreversible split runs silently. Snapshot should record that --yes was used.

low

Snapshot written unconditionally on dry-runs — full inventory disclosed without --execute

scripts/split-merged-sites.ts:287

Any dry-run produces a JSON with complete site/org/RPU data. Consider writing only when --execute is confirmed, or adding to .gitignore.

improvement7

high

Snapshot written before dry-run exit — accumulates files on repeated invocations

scripts/split-merged-sites.ts:274

writeFileSync runs before the !EXECUTE guard. Per-org pilot dry-runs leave many snapshot files; the last may not reflect the final execute state if RPUs enrolled between runs. Write the snapshot only when --execute is confirmed.

high

Confirmation count is stale — derived from pre-query targets, not live DB at execute time

scripts/split-merged-sites.ts:320

'About to split N sites into M new sites' from outer findSuspiciousSites. splitSite re-reads inside FOR UPDATE. If RPUs added between query and confirmation, displayed count underestimates. Qualify as 'at least M'.

medium

Aborting via wrong confirmation answer exits with code 0 — pipelines cannot detect abort

scripts/split-merged-sites.ts:324

The 'confirmation not given' return path exits 0. Only the no-TTY path sets exitCode=1. Wrapper scripts cannot distinguish abort from success.

medium

--yes accepted without evidence a dry-run snapshot was reviewed first

scripts/split-merged-sites.ts:91

Header says --yes is for 'piped runs after reviewing a dry-run + snapshot' but nothing enforces this. Emit a WARNING line when --yes is used.

low

writeFileSync has no error handling — read-only CWD throws opaque FS error

scripts/split-merged-sites.ts:275

If CWD is not writable, the script throws EACCES before showing any census output.

low

orgRollup keyed by org_name (mutable) — two orgs with same name collide in census

scripts/split-merged-sites.ts:256

org_name is user-editable. Key by org_id and display the name alongside.

info

Post-run verify uses filtered query — misleading 'OK' for partial runs

scripts/split-merged-sites.ts:344

With --org or --limit, 'no multi-RPU sites remain' shows even when other orgs are unprocessed.

History · 8 commits

  1. 7b5ff24needs attentionincremental0H · 2M · 3L2026-07-09 00:58
  2. 6231fe5needs attentionincremental0H · 2M · 4L2026-07-08 22:34
  3. 8fa38b5needs attentionincremental2H · 4M · 5L2026-07-08 01:45current
  4. 83fd5a0needs attentionincremental3H · 8M · 11L2026-07-08 01:37
  5. 23c04fcneeds attentionincremental3H · 3M · 2L2026-07-07 20:30
  6. e70f9f5blockedincremental6H · 11M · 6L2026-07-07 19:28
  7. 499b1a5blockedincremental6H · 9M · 5L2026-07-07 18:26
  8. ff23301needs attentionincremental2H · 6M · 5L2026-07-07 01:05