diff --git a/central/app/web.py b/central/app/web.py index 9c175e4..e92ae15 100644 --- a/central/app/web.py +++ b/central/app/web.py @@ -109,7 +109,25 @@ def router(session_factory): def blockers(request: Request, page: int = 1, blocker_type: str | None = None): session, auth_data, redirect = page_auth(request) if redirect: return redirect - try: return render(request, "blockers.html", {"result": list_blockers(session, page=page, page_size=50, blocker_type=blocker_type), "auth": auth_data}) + try: return render(request, "blockers.html", {"result": list_blockers(session, page=page, page_size=50, blocker_type=blocker_type), "auth": auth_data, "csrf_token": request.cookies.get("gti_csrf", "")}) + finally: session.close() + + @routes.post("/blockers/{blocker_id}/resolve") + async def resolve_blocker(request: Request, blocker_id: int): + session, auth_data, redirect = page_auth(request) + if redirect: return redirect + try: + values = await form_values(request); web_session, admin = auth_data + require_csrf(web_session, values.get("csrf_token")) + if values.get("confirm") != "yes" or not values.get("context", "").strip(): return HTMLResponse("confirmation and context required", status_code=400) + from .models import BlockedProduct + blocker = session.get(BlockedProduct, blocker_id) + if not blocker: return HTMLResponse("Blocker not found", status_code=404) + from datetime import datetime, timezone + 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": values["context"]}) + session.commit() + return RedirectResponse("/blockers", status_code=303) finally: session.close() @routes.get("/jobs", response_class=HTMLResponse) diff --git a/central/templates/blockers.html b/central/templates/blockers.html index 5e00dec..ae844c2 100644 --- a/central/templates/blockers.html +++ b/central/templates/blockers.html @@ -1 +1 @@ -{% extends "base.html" %}{% block title %}Blockers | GTI Fiscal{% endblock %}{% block content %}
FILA FISCAL
| Cliente | Produto | Campo | Tipo | Motivo | Última ocorrência | Retries |
|---|---|---|---|---|---|---|
| {{ item.client or item.tenant_id }} | {{ item.product_code }}{{ item.description or "" }} | {{ item.field }} | {{ item.blocker_type }} | {{ item.reason }} | {{ item.last_seen_at }} | {{ item.retry_count }} |
| Nenhum blocker aberto. | ||||||
FILA FISCAL
| Cliente | Produto | Campo | Tipo | Motivo | Última ocorrência | Ação |
|---|---|---|---|---|---|---|
| {{ item.client or item.tenant_id }} | {{ item.product_code }}{{ item.description or "" }} | {{ item.field }} | {{ item.blocker_type }} | {{ item.reason }} | {{ item.last_seen_at }}{{ item.retry_count }} retries | |
| Nenhum blocker aberto. | ||||||