Files
summercms/.planning/phases/15-cutover/15-DISCUSSION-LOG.md
2026-10-04 14:30:25 +02:00

124 lines
5.7 KiB
Markdown

# Phase 15: Cutover - Discussion Log
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md. This log preserves the alternatives considered.
**Date:** 2026-10-04
**Phase:** 15-cutover
**Areas discussed:** MariaDB → Postgres data move, production switch and rollback, the "all routes green" gate, daily-use acceptance
Before the discussion started, the scout found that production runs on MariaDB (with a Redis queue), not Postgres. It also found that the parity manifest holds 175 routes (172 ported, 3 pending), not 154, and that Phases 14.1 and 12.1 have not started.
---
## MariaDB → Postgres data move
| Option | Description | Selected |
|--------|-------------|----------|
| Go import command | Reads MariaDB via DSN and writes into the migrated schema. Re-encrypts inline, testable with testcontainers, adds a MySQL driver | ✓ |
| pgloader + Go fix-up pass | Staging schema copy, then a Go transform. Needs an external tool and runs in two steps | |
| mariadb-dump → SQL rewrite | Dump, rewrite the dialect, load. The most fragile option | |
| Option | Description | Selected |
|--------|-------------|----------|
| Framework capability + per-plugin mappers | Generic `summer import:winter` runner, plus `HasWinterImport` per plugin | ✓ |
| App-only command in fonoteka.go | One-off command that knows every table | |
**Not carried over (multi-select):** transient queue/job state ✓, sessions/caches/JWT blacklist ✓, Typesense index (reindex instead) ✓, old notifications ✓
| Option | Description | Selected |
|--------|-------------|----------|
| Rehearse on a prod dump + verify | Counts, checksums, decrypt round-trip and file existence, then a timed dress rehearsal | ✓ |
| Rehearse + replay Nuxt/MCP flows on imported data | Adds a manual click-through before the switch | |
| Unit/integration tests only | The first real-data run is the cutover itself | |
---
## Production switch and rollback
| Option | Description | Selected |
|--------|-------------|----------|
| Freeze, import, swap upstream | Maintenance page, final dump, import, then repoint the nginx API locations on the same origin | ✓ |
| Staging subdomain first, then swap | Needs a second Nuxt build | |
| Shadow/mirror then swap | nginx mirror, which only validates GET requests | |
| Option | Description | Selected |
|--------|-------------|----------|
| Keep PHP+MariaDB frozen; rollback window, no reverse sync | Rollback swaps nginx back; Go-side writes are lost | ✓ |
| Reverse export Go→MariaDB | Doubles the import work | |
| No rollback path | Fix forward only | |
| Option | Description | Selected |
|--------|-------------|----------|
| Supervisor, serve + worker as two programs | Matches the 11.2 deploy and `albumy-queue` | ✓ |
| Supervisor, single process | Simpler, but a deploy restarts jobs mid-flight | |
| systemd units | A new pattern on rome | |
| Option | Description | Selected |
|--------|-------------|----------|
| User runs a runbook; Claude writes it | CUTOVER.md plus per-step scripts, with output pasted back as evidence | ✓ |
| Claude runs it over SSH | Needs SSH access to rome | |
---
## "All routes green" gate
| Option | Description | Selected |
|--------|-------------|----------|
| Every manifest route, zero pending | 175 entries; API-09/QA-05 reworded | ✓ |
| Exactly the 154 fonoteka routes.php routes | The literal requirement | |
| Option | Description | Selected |
|--------|-------------|----------|
| Existing corpus + a fresh PHP re-record | Re-record before the freeze, with a drift report | ✓ |
| Existing committed corpus only | Could miss PHP changes made after recording | |
| Option | Description | Selected |
|--------|-------------|----------|
| Hard prerequisites (14.1, 12.1, Phase 14 UAT) | A preflight gate in the first plan; 12.1 is added to depends-on | ✓ |
| Only 14.1 is a prerequisite | 12.1 can land after cutover | |
| Fold the remaining work into Phase 15 | 14.1 would be removed | |
| Option | Description | Selected |
|--------|-------------|----------|
| Yes, a read-only smoke run on the rehearsal import | PHP on MariaDB against Go on imported Postgres from the same dump, diffed | ✓ |
| No, the seeded corpus is enough | | |
---
## Daily-use acceptance
| Option | Description | Selected |
|--------|-------------|----------|
| 7 days of normal household use | The scheduled jobs each run at least once, plus a CSV import and a Discogs match | ✓ |
| 48 hours | | |
| 14 days | | |
**Scripted session (multi-select):** Nuxt core session ✓, MCP + OAuth ✓, Sharing & invitations (not selected), Admin & ops (not selected)
| Option | Description | Selected |
|--------|-------------|----------|
| Stop & archive, delete later | | |
| Leave PHP running but unrouted | Keep it up for a late rollback | ✓ |
| Full removal in-phase | | |
| Option | Description | Selected |
|--------|-------------|----------|
| Yes, a pg_dump timer replaces the MariaDB one | Installed at the swap, with a restore drill | ✓ |
| No, handle separately | | |
**PHP scheduler/queue worker follow-up:** the user wrote: "I'll manage php sign off / stopping cron / workers, outside the plans, don't mind it."
---
## Claude's Discretion
- The runner's internals (batching, FK ordering, the coercion table, the interface naming) and the verify-report format.
- How the runbook is split into scripts and how evidence is laid out; the supervisor program names.
- Whether the smoke diff reuses tide replay or adds a new `parity:*` subcommand.
## Deferred Ideas
- The WinterCMS vs SummerCMS benchmark (existing todo) can reuse the rehearsal dump and the dual-backend setup.
- PHP/MariaDB decommission: the user handles it outside the plans.