feat/sites-1n
needs attention7b5ff24 · incrementalPR #279reviewed 2026-07-09 00:58 UTC0H · 2M · 3L- Purpose
- Stop the razón-social mass-merge where CFE RPUs sharing a service name were fused onto one site (the Pilgrim's Pride incident: editing one RPU's site changed unrelated RPUs).
- Goal
- Make the Site ↔ RPU relationship correct (dedup = internal ID AND name, never name alone), visible (grouped-by-site toggle, site cell with pencil), and manageable (SiteEditModal: edit / move / split; one-shot remediation script for pre-fix merges).
- Sub-goals
- SG-1: Shared resolveSiteForRpu decision; rewired both coordinators; composite findByOrgInternalIdAndName; idempotent re-enroll
- SG-2: sites.list search matches metadata.customer_id; response gains contractCount
- SG-3: createFromWizard accepts existingSitePublicId; move op reuses setLinkedContract
- SG-4: Drawer — segmented Crear/Usar-existente, debounced search, exact-match auto-switch, SitePicker with RPU-count badges
- SG-5: Site cell pencil → SiteEditModal (edit details, move RPU, split to new site); OCC on move
- SG-6: 'Agrupar por sitio' toggle — full-width site rows, RPU rows keep columns minus Sitio
- SG-7: Batch preview — rows grouped by (internal id + name), existing-site flags, summary chips
- SG-8: 4 typed analytics events; cross-domain CLAUDE.md updated; design doc status; i18n inline-es
- What
- This incremental commit is cleanup-only: deletes transient .branch/ tracking docs, updates 5 dead doc references (docs/development/site-contract-relationship.md → domains/cross-domain/CLAUDE.md), refreshes prod stats in CLAUDE.md (264→379 sites, 1,088→1,583 RPUs), adds supabase-staging to .mcp.json, and expands the split-merged-sites.ts prod runbook from a one-liner to a 7-step ordered guide.
- Why
- The previous loop-review flagged that the .branch/ files leaked implementation iteration history into the PR and that the doc reference target no longer exists. This commit consolidates durable content into CLAUDE.md and removes the ephemeral files.
- Areas
- apps/platform/src+1462−197domains/cross-domain/src+854−141scripts/split-merged-sites.ts+436−0domains/utility/src+70−6packages/analytics/src+45−0packages/api/src+29−4domains/core/src+28−24.github/workflows+31−19
- Blast
- 30 files changed, +2983/−588 across apps/platform UI (SitePicker, SiteEditModal, ContractsTable grouped view, BatchContractForm), domains/cross-domain (coordinators, resolver, tests), domains/utility (SUC move), packages/api, packages/analytics, scripts (remediation), and CI workflows.
Findings · 5
correctness1
Contradictory re-run guidance: 'no-op' vs 'NEVER re-run'
scripts/split-merged-sites.ts:99
Step 5 says 'an immediate re-run is a no-op for completed sites' then immediately says 'NEVER re-run later (one-shot)'. The verify error message (line ~419) also says 'Re-run (idempotent) or inspect manually'. The code's idempotency guard (`if (rows.length <= 1) return 0`) makes a re-run after partial failure safe. The 'NEVER' is the outlier — replace with 'do not schedule repeated cron runs; a manual re-run after partial failure is safe for already-split sites'.
security2
Staging Supabase project ref hardcoded in version-controlled .mcp.json
.mcp.json:49
The staging project ref `xrgglyfbginnqgqoqirz` is committed into `.mcp.json`. While not a credential on its own, it permanently encodes a stable staging-environment identifier in git history. If a service-role key or anon key is ever accidentally leaked, the ref provides a direct target. Consider moving environment-specific refs to a gitignored `.mcp.local.json`, or document explicitly that this ref is intentionally public and security rests entirely on the token layer.
Customer org names embedded in git-permanent script comment
scripts/split-merged-sites.ts:103
Step 4 names 'Pilgrim's Pride' and 'Tiendas Neto' directly in the source. These names will persist in git history. If the repo is audited externally, this may be a data-handling concern under customer contracts or privacy regulations. Recommend replacing with a generic description: 'orgs with labeled site groups — identify via the category-D census output at runtime'.
conventions2
MCP server auth config absent from .mcp.json entry
.mcp.json:49
The new supabase-staging entry contains only the URL. If mcp.supabase.com requires a bearer token or API key, that config is absent. Verify the MCP client picks up auth from the environment automatically (e.g. SUPABASE_ACCESS_TOKEN) — and document that expectation in a comment or the README if so.
Runbook duplication risk between script header and CLAUDE.md
scripts/split-merged-sites.ts:82
The 7-step runbook is now fully inlined in the script header. domains/cross-domain/CLAUDE.md also references the script. If the runbook evolves post-merge, the two locations can diverge. Low risk for a one-shot script; consider adding 'see also domains/cross-domain/CLAUDE.md (Site Resolution)' as a cross-reference rather than repeating the full sequence.
History · 8 commits
- 7b5ff24needs attentionincremental0H · 2M · 3L2026-07-09 00:58current
- 6231fe5needs attentionincremental0H · 2M · 4L2026-07-08 22:34
- 8fa38b5needs attentionincremental2H · 4M · 5L2026-07-08 01:45
- 83fd5a0needs attentionincremental3H · 8M · 11L2026-07-08 01:37
- 23c04fcneeds attentionincremental3H · 3M · 2L2026-07-07 20:30
- e70f9f5blockedincremental6H · 11M · 6L2026-07-07 19:28
- 499b1a5blockedincremental6H · 9M · 5L2026-07-07 18:26
- ff23301needs attentionincremental2H · 6M · 5L2026-07-07 01:05