Kairo-Jinkendo/backend/data_layer/workspace.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

71 lines
2.3 KiB
Python

"""Workspace summary read-model — tenant-scoped KPIs for current actor."""
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_workspace_summary(ctx: TenantContext) -> dict[str, Any]:
"""
Summary for workspace dashboard.
Personal counts (current actor): open, blocked, recently done.
Tenant-wide: active initiatives count.
"""
if not ctx.actor_id:
return {
"open_actions_count": 0,
"blocked_actions_count": 0,
"active_initiatives_count": 0,
"done_actions_recent_count": 0,
}
conn = get_connection()
try:
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute(
"""
SELECT
COUNT(*) FILTER (
WHERE a.status IN ('open', 'in_progress')
) AS open_actions_count,
COUNT(*) FILTER (
WHERE a.status = 'blocked'
) AS blocked_actions_count,
COUNT(*) FILTER (
WHERE a.status = 'done'
AND a.updated_at >= NOW() - INTERVAL '7 days'
) AS done_actions_recent_count
FROM actions a
JOIN action_assignments aa
ON aa.action_id = a.id AND aa.tenant_id = a.tenant_id
WHERE a.tenant_id = %s AND aa.actor_id = %s
""",
(ctx.tenant_id, ctx.actor_id),
)
row = dict(cur.fetchone())
cur.execute(
"""
SELECT COUNT(*) AS active_initiatives_count
FROM initiatives
WHERE tenant_id = %s AND status IN ('active', 'paused')
""",
(ctx.tenant_id,),
)
initiatives_row = dict(cur.fetchone())
finally:
conn.close()
return {
"open_actions_count": int(row["open_actions_count"] or 0),
"blocked_actions_count": int(row["blocked_actions_count"] or 0),
"active_initiatives_count": int(initiatives_row["active_initiatives_count"] or 0),
"done_actions_recent_count": int(row["done_actions_recent_count"] or 0),
}