"""DNS gate logic — Spec 019.""" from __future__ import annotations import os from typing import Any from app.migration import store GATE_MIN_RATIO = float(os.getenv("MIGRATION_GATE_MIN_RATIO", "0.99")) def evaluate_job(conn, job_id: int) -> dict[str, Any]: job = store.get_job(conn, job_id) if not job: return {"gate": "blocked", "reason": "job_not_found"} mailboxes = job.get("mailboxes") or [] checks: list[tuple[str, str, str]] = [] if not mailboxes: checks.append(("mailboxes_present", "fail", "Nenhuma mailbox no job")) gate = "blocked" else: ratios = [] for mb in mailboxes: src = max(mb.get("messages_source") or 0, 1) dst = mb.get("messages_dest") or 0 ratio = dst / src if src else 0.0 ratios.append(ratio) if ratio < GATE_MIN_RATIO: checks.append( ( f"sync_{mb['email']}", "warn" if ratio >= 0.9 else "fail", f"{mb['email']}: {ratio * 100:.1f}% sincronizado", ) ) avg = sum(ratios) / len(ratios) if ratios else 0.0 checks.append(("count_ratio", "pass" if avg >= GATE_MIN_RATIO else "warn", f"Média {avg * 100:.1f}%")) if job.get("approved_by"): checks.append(("manual_approval", "pass", f"Aprovado por {job['approved_by']}")) gate = "ready_for_dns" if avg >= GATE_MIN_RATIO else "warning" elif avg >= GATE_MIN_RATIO: checks.append(("manual_approval", "fail", "Aguarda aprovação ops_lead")) gate = "warning" elif avg >= 0.9: gate = "warning" else: gate = "blocked" for check_id, status, message in checks: store.add_gate_check(conn, job_id, check_id, status, message) store.update_job(conn, job_id, migration_gate=gate, phase=job.get("phase") or "cutover_ready") return {"gate": gate, "checks": [{"check_id": c[0], "status": c[1], "message": c[2]} for c in checks]} def approve_gate(conn, job_id: int, approved_by: str) -> dict[str, Any]: from datetime import datetime, timezone now = datetime.now(timezone.utc).isoformat() store.update_job(conn, job_id, approved_by=approved_by, approved_at=now, phase="cutover_ready") result = evaluate_job(conn, job_id) if result["gate"] in ("warning", "ready_for_dns"): store.update_job(conn, job_id, migration_gate="ready_for_dns") result["gate"] = "ready_for_dns" return result