feat: add safe blocker resolution workflow

This commit is contained in:
gti
2026-09-22 18:47:04 -03:00
parent 25af5cf0f0
commit 5180725238
7 changed files with 430 additions and 22 deletions
+9 -8
View File
@@ -6,6 +6,7 @@ from fastapi import APIRouter, Depends, HTTPException, Request
from sqlalchemy import select
from .audit import record_audit
from .blocker_resolution import resolve_blocker_with_context
from .control_plane import dashboard_summary, installation_view, list_blockers, list_installations, list_jobs, list_panel_events
from .human_auth import require_csrf, require_human
from .models import Agent, AgentSnapshot, BlockedProduct, Installation, Job, Tenant
@@ -109,19 +110,19 @@ def router(session_factory):
return {"job_id": job.id, "status": job.status}
finally: session.close()
@routes.post("/blockers/{blocker_id}/resolve-context")
@routes.post("/blockers/{blocker_id}/resolve-human")
def resolve_blocker(blocker_id: int, payload: dict, request: Request, identity=Depends(identity)):
session, web_session, admin = identity
try:
require_csrf(web_session, payload.get("csrf_token"))
if payload.get("confirm") is not True or not str(payload.get("context", "")).strip(): raise HTTPException(400, "confirmation and explicit context required")
blocker = session.get(BlockedProduct, blocker_id)
if not blocker: raise HTTPException(404, "blocker not found")
if blocker.resolved_at is None:
blocker.resolved_at = datetime.now(timezone.utc); blocker.resolution_source = "HUMAN_PANEL"
record_audit(session, admin_user_id=admin.id, tenant_id=blocker.tenant_id, action="RESOLVE_BLOCKER", target_type="blocker", target_id=str(blocker_id), context={"context": payload["context"]})
session.commit()
return {"resolved": True, "blocker_id": blocker_id}
entry_payload = {key: payload.get(key) for key in ("scope", "scope_key", "key", "value", "reason")}
try:
return resolve_blocker_with_context(session, blocker_id, admin, entry_payload, request_ip=request.client.host if request.client else None)
except LookupError as error:
raise HTTPException(404, str(error)) from error
except ValueError as error:
raise HTTPException(422, str(error)) from error
finally: session.close()
return routes