62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
|
|
"""Actor workload read-models — tenant-scoped aggregation."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
from psycopg2.extras import RealDictCursor
|
||
|
|
|
||
|
|
from db import get_connection
|
||
|
|
from tenant_context import TenantContext
|
||
|
|
|
||
|
|
|
||
|
|
def get_actor_workload(ctx: TenantContext) -> list[dict[str, Any]]:
|
||
|
|
"""Open/blocked/in_progress action counts per active actor in tenant."""
|
||
|
|
conn = get_connection()
|
||
|
|
try:
|
||
|
|
with conn.cursor(cursor_factory=RealDictCursor) as cur:
|
||
|
|
cur.execute(
|
||
|
|
"""
|
||
|
|
SELECT
|
||
|
|
a.id AS actor_id,
|
||
|
|
a.name AS display_name,
|
||
|
|
a.actor_type,
|
||
|
|
COUNT(*) FILTER (WHERE act.status = 'open') AS open_actions,
|
||
|
|
COUNT(*) FILTER (WHERE act.status = 'blocked') AS blocked_actions,
|
||
|
|
COUNT(*) FILTER (WHERE act.status = 'in_progress') AS in_progress_actions
|
||
|
|
FROM actors a
|
||
|
|
LEFT JOIN action_assignments aa
|
||
|
|
ON aa.actor_id = a.id AND aa.tenant_id = a.tenant_id
|
||
|
|
LEFT JOIN actions act
|
||
|
|
ON act.id = aa.action_id
|
||
|
|
AND act.tenant_id = aa.tenant_id
|
||
|
|
AND act.status IN ('open', 'in_progress', 'blocked')
|
||
|
|
WHERE a.tenant_id = %s AND a.is_active = TRUE
|
||
|
|
GROUP BY a.id, a.name, a.actor_type
|
||
|
|
ORDER BY
|
||
|
|
CASE a.actor_type
|
||
|
|
WHEN 'human' THEN 0
|
||
|
|
WHEN 'working_group' THEN 1
|
||
|
|
WHEN 'agent' THEN 2
|
||
|
|
ELSE 3
|
||
|
|
END,
|
||
|
|
a.name
|
||
|
|
""",
|
||
|
|
(ctx.tenant_id,),
|
||
|
|
)
|
||
|
|
result = []
|
||
|
|
for row in cur.fetchall():
|
||
|
|
result.append(
|
||
|
|
{
|
||
|
|
"actor_id": str(row["actor_id"]),
|
||
|
|
"display_name": row["display_name"],
|
||
|
|
"actor_type": row["actor_type"],
|
||
|
|
"open_actions": int(row["open_actions"] or 0),
|
||
|
|
"blocked_actions": int(row["blocked_actions"] or 0),
|
||
|
|
"in_progress_actions": int(row["in_progress_actions"] or 0),
|
||
|
|
}
|
||
|
|
)
|
||
|
|
return result
|
||
|
|
finally:
|
||
|
|
conn.close()
|