|
| 1 | +# Controller UI Configuration Implementation Blueprint |
| 2 | + |
| 3 | +## Meta |
| 4 | + |
| 5 | +- **Design Doc:** N/A |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +Allow an authenticated operator to configure every setting used by controller-managed preflight, run, and verification from the embedded dashboard. Controller bootstrap settings remain process-owned, credentials remain write-only and memory-only, and cutover and sequence advancement remain CLI-only. |
| 10 | + |
| 11 | +### Cross-Cutting Requirements |
| 12 | + |
| 13 | +- The controller must continue to start idle and must not create migration state or connect to either database on startup. |
| 14 | +- Controller token, listen address, and migration directory remain startup-only. |
| 15 | +- Source and target DSNs are never returned by an API, logged, written to state, or stored in browser storage. |
| 16 | +- Configuration updates are rejected while a migration or verification operation is active. |
| 17 | +- Existing CLI behavior and lifecycle guards remain unchanged. |
| 18 | +- All new code passes `go vet ./...`, `go test ./...`, and `go test -race ./...`. |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +## Tasks |
| 23 | + |
| 24 | +### Task 1: Add an authenticated mutable configuration API |
| 25 | +**Type:** code |
| 26 | + |
| 27 | +**Subtasks:** |
| 28 | +- Add a concurrency-safe controller configuration store initialized from CLI/environment defaults. |
| 29 | +- Add authenticated `GET /api/config` and `PUT /api/config` routes covering every configuration field used by preflight, run, and verify, excluding status-only, cutover/sequence, directory, listener, and token settings. |
| 30 | +- Make source and target DSNs write-only: GET reports only whether each is configured, and an omitted/blank PUT value retains the current DSN. |
| 31 | +- Parse human-readable durations and numeric settings, validate the complete candidate configuration, and atomically replace it only when no operation is active. |
| 32 | +- Snapshot the current configuration when an action starts so an in-flight action cannot observe later mutations. |
| 33 | +- Add handler and concurrency tests for authentication, redaction, validation, update locking, default preservation, and action snapshots. |
| 34 | + |
| 35 | +**Acceptance Criteria:** |
| 36 | +- AC1.1: An authenticated client can configure source, target, and every preflight/run/verify option after controller startup. |
| 37 | +- AC1.2: Neither config GET nor status responses contain either DSN. |
| 38 | +- AC1.3: Invalid configuration returns HTTP 400 without changing the active configuration. |
| 39 | +- AC1.4: Configuration updates during active migration or verification return HTTP 409. |
| 40 | +- AC1.5: Controller and CLI unit tests pass under the race detector. |
| 41 | + |
| 42 | +--- |
| 43 | + |
| 44 | +### Task 2: Add complete configuration forms to the embedded UI |
| 45 | +**Type:** code |
| 46 | + |
| 47 | +**Subtasks:** |
| 48 | +- Add database connection, migration, copy, tuning, and verification form sections with basic settings visible and advanced settings collapsible. |
| 49 | +- Load non-secret defaults from the config API after authentication without placing DSNs in the DOM or browser storage. |
| 50 | +- Save configuration through the authenticated API, clearly report validation errors, and show configured/not-configured connection state. |
| 51 | +- Keep controls disabled until a valid configuration is saved and preserve all existing lifecycle, confirmation, progress, and stop behavior. |
| 52 | +- Add static UI regression assertions for the configuration form, write-only DSNs, and absence of DSN browser persistence. |
| 53 | +- Update README controller documentation with configuration security and lifecycle behavior. |
| 54 | + |
| 55 | +**Acceptance Criteria:** |
| 56 | +- AC2.1: Every preflight/run/verify configuration field can be edited from the dashboard. |
| 57 | +- AC2.2: Source/target inputs are password fields, remain empty after reload, and are never stored in localStorage or sessionStorage. |
| 58 | +- AC2.3: Bootstrap settings and CLI-only cutover/sequences are not editable from the dashboard. |
| 59 | +- AC2.4: Existing progress and action controls remain functional and accessible. |
| 60 | +- AC2.5: Controller tests and `git diff --check` pass. |
| 61 | + |
| 62 | +--- |
| 63 | + |
| 64 | +### Task 3: Prove UI-supplied configuration end to end |
| 65 | +**Type:** go-tests |
| 66 | + |
| 67 | +**Subtasks:** |
| 68 | +- Change the controller E2E driver to start without source/target DSNs and populate the complete action configuration through the authenticated config API. |
| 69 | +- Exercise authenticated preflight, run, live verification, final verification, CLI-only cutover, cleanup checks, and independent source/target comparison. |
| 70 | +- Add focused coverage that controller startup alone leaves the migration directory untouched. |
| 71 | +- Validate the dashboard in a browser from unauthenticated state through configuration save, action enablement, progress rendering, and completed-state locking. |
| 72 | + |
| 73 | +**Acceptance Criteria:** |
| 74 | +- AC3.1: `make controller-e2e` passes while supplying both DSNs through the controller config API. |
| 75 | +- AC3.2: Independent table inventory, row counts, and canonical source/target digests match after cutover. |
| 76 | +- AC3.3: Starting the controller without taking an action creates no migration state and opens no database connection. |
| 77 | +- AC3.4: `go vet ./...`, `go test ./...`, and `go test -race ./...` pass. |
| 78 | + |
| 79 | +## Files to Modify |
| 80 | + |
| 81 | +- `internal/controller/controller.go` - mutable config API and action snapshots. |
| 82 | +- `internal/controller/controller_test.go` - API, redaction, locking, and startup regression tests. |
| 83 | +- `internal/controller/ui.html` - complete configuration dashboard. |
| 84 | +- `test/e2e/scripts/run-migration.sh` - configure controller through API. |
| 85 | +- `README.md` and `test/README.md` - operator and E2E documentation. |
| 86 | + |
| 87 | +## References |
| 88 | + |
| 89 | +- Current controller server: `internal/controller/controller.go` |
| 90 | +- Current embedded dashboard: `internal/controller/ui.html` |
| 91 | +- CLI configuration flags: `internal/cli/cli.go` |
| 92 | +- Shared configuration model: `internal/config/config.go` |
0 commit comments