Implement master promotion feature
All checks were successful
Deploy / deploy (push) Successful in 33s

Allows promoting any replica to master with zero document re-downloads.
The sync_map rebuild uses existing DB data only — pure in-memory join.

Changes:
- app/sync/promote.py: preflight() checks (doc count, sync lock, ack
  warnings) and promote() transaction (pause scheduler, rebuild all
  sync_maps, create old-master replica, swap settings, resume scheduler)
- app/api/master.py: GET /api/master/promote/{id}/preflight (dry run)
  and POST /api/master/promote/{id} (execute)
- app/models.py: add promoted_from_master bool field to Replica
- app/database.py: idempotent ALTER TABLE migration for new column
- app/main.py: register master router
- app/templates/replica_detail.html: "Promote to Master" button +
  dialog with pre-flight summary, 3-card stats, ack checkboxes, spinner
- app/ui/routes.py: flash query param on dashboard route
- app/templates/dashboard.html: blue info banner for post-promotion flash

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 21:16:57 +01:00
parent f29a451e55
commit cdc9407ff3
8 changed files with 567 additions and 2 deletions

View File

@@ -142,12 +142,14 @@ def create_app() -> FastAPI:
from .api.logs import router as logs_router
from .api.settings import router as settings_router
from .api.status import router as status_router
from .api.master import router as master_router
app.include_router(replicas_router)
app.include_router(sync_router)
app.include_router(logs_router)
app.include_router(settings_router)
app.include_router(status_router)
app.include_router(master_router)
# ── Health & Metrics (no auth) ────────────────────────────────────────────