feat: add operational eligibility and scheduled follow-up

This commit is contained in:
plx
2026-08-15 07:56:06 +00:00
parent 71452b1e5c
commit ee8e2de606
13 changed files with 812 additions and 26 deletions

View File

@@ -16,6 +16,8 @@ from app.admin_ui.guidance import item_requires_fiscal_customer, work_item_block
# Legacy label kept for regression context: Ambíguas.
OPERATION_FILTERS = [
("all", "A fazer", "/operations?scope=all", "/operations/partials/work-items?scope=all"),
("waiting", "Aguardar", "/operations?scope=waiting", "/operations/partials/work-items?scope=waiting"),
("backlog", "Backlog", "/operations?scope=backlog", "/operations/partials/work-items?scope=backlog"),
("bloqueadas", "Bloqueadas", "/operations?scope=bloqueadas", "/operations/partials/work-items?scope=bloqueadas"),
("ambiguas", "Associações por confirmar", "/operations?scope=ambiguas", "/operations/partials/work-items?scope=ambiguas"),
("atrasadas", "Atrasadas", "/operations?scope=atrasadas", "/operations/partials/work-items?scope=atrasadas"),
@@ -168,6 +170,8 @@ def is_scheduled_for_future(item: dict[str, Any]) -> bool:
def is_overdue(item: dict[str, Any]) -> bool:
if str(item.get("operational_queue") or "").lower() in {"waiting", "backlog", "not_current"}:
return False
due_dt = _parse_dt(item.get("due_at"))
if due_dt is not None:
return due_dt < datetime.now(timezone.utc)
@@ -241,6 +245,9 @@ def is_high_priority(item: dict[str, Any]) -> bool:
action_code = str(item.get("action_code") or "").upper()
priority = str(item.get("priority") or "").lower()
if str(item.get("operational_queue") or "").lower() in {"waiting", "backlog", "not_current"}:
return False
if is_ambiguous(item):
return True
if source == "outbox" and status in {"failed", "blocked", "stale"}:
@@ -312,7 +319,12 @@ def build_operations_view_model(scope: str = "all", *, limit: int = 30) -> dict[
counts = data.get("counts") or {}
scope = str(scope or "all").strip().lower()
work_items = list(data.get("work_items") or [])
visible_items = [item for item in work_items if operation_item_matches_scope(item, scope)]
if scope == "waiting":
visible_items = list(data.get("waiting_items") or [])
elif scope == "backlog":
visible_items = list(data.get("backlog_items") or [])
else:
visible_items = [item for item in work_items if operation_item_matches_scope(item, scope)]
high_items = [item for item in visible_items if is_high_priority(item)]
normal_items = [item for item in visible_items if not is_high_priority(item)]
review_total = int(counts.get("review_tasks", 0) or 0) + int(counts.get("communications_needs_review", 0) or 0)