"""API endpoints for master promotion.""" from fastapi import APIRouter, HTTPException from pydantic import BaseModel router = APIRouter(prefix="/api/master", tags=["master"]) class PromoteRequest(BaseModel): old_master_name: str acknowledge_pending: bool = False acknowledge_errors: bool = False @router.get("/promote/{replica_id}/preflight") async def preflight_endpoint(replica_id: int): """Dry-run pre-flight check. No state is modified.""" from ..sync.promote import preflight result = await preflight(replica_id) return { "can_promote": result.can_promote, "error": result.error, "detail": result.detail, "pending_entries": result.pending_entries, "error_entries": result.error_entries, "ok_entries": result.ok_entries, "missing_doc_count": result.missing_doc_count, "replica_doc_count": result.replica_doc_count, "master_doc_count": result.master_doc_count, } @router.post("/promote/{replica_id}") async def promote_endpoint(replica_id: int, body: PromoteRequest): """Execute promotion. Pauses scheduler, runs transaction, resumes scheduler.""" from ..sync.promote import promote try: result = await promote( replica_id=replica_id, old_master_name=body.old_master_name, acknowledge_pending=body.acknowledge_pending, acknowledge_errors=body.acknowledge_errors, ) except ValueError as exc: error_code = exc.args[0] if exc.args else "UNKNOWN" detail_msg = exc.args[1] if len(exc.args) > 1 else str(exc) status = 409 if error_code == "SYNC_RUNNING" else 422 raise HTTPException(status_code=status, detail={"error": error_code, "detail": detail_msg}) return { "ok": result.ok, "new_master": {"url": result.new_master_url, "name": result.new_master_name}, "old_master_replica_id": result.old_master_replica_id, "sync_map_rebuilt": { "replicas_affected": result.replicas_affected, "entries_mapped": result.entries_mapped, "entries_skipped": result.entries_skipped, }, }