Kairo-Jinkendo/backend/data_layer/actors.py
Lars db06af0489
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Test Suite / pytest-backend (push) Successful in 42s
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 12s
AP0.7: Tenant Hardening, Actor Directory und Data Layer Minimum
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 07:25:01 +02:00

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()