Kairo-Jinkendo/backend/routers/workspace.py
Lars 451d62ed46
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Test Suite / pytest-backend (push) Successful in 1m13s
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 15s
AP0.10b: Steering UI Minimum — Next Actions, Heute, Snapshot v2
Workspace beantwortet die Leitfrage mit prominenten Next-Action- und Heute-Widgets sowie erweitertem Steuerungszustand pro Vorhaben.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 15:55:05 +02:00

91 lines
2.9 KiB
Python

"""Workspace read API — delegates to Data Layer (AP0.7)."""
from __future__ import annotations
from typing import Optional
from capabilities import require_capability
from data_layer import actions as dl_actions
from data_layer import actors as dl_actors
from data_layer import attention as dl_attention
from data_layer import initiatives as dl_initiatives
from data_layer import workspace as dl_workspace
from fastapi import APIRouter, Depends, HTTPException, Query
from tenant_context import TenantContext
router = APIRouter(prefix="/api/workspace", tags=["workspace"])
def _require_actor_ctx(ctx: TenantContext) -> TenantContext:
if not ctx.actor_id:
raise HTTPException(status_code=400, detail="Kein Actor im TenantContext")
return ctx
@router.get("/summary")
def workspace_summary(
ctx: TenantContext = Depends(require_capability("kairo.workspace.read")),
):
return dl_workspace.get_workspace_summary(ctx)
@router.get("/actions/open")
def workspace_open_actions(
ctx: TenantContext = Depends(require_capability("kairo.workspace.read")),
):
try:
return dl_actions.get_my_open_actions(_require_actor_ctx(ctx))
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
@router.get("/actions/blocked")
def workspace_blocked_actions(
ctx: TenantContext = Depends(require_capability("kairo.workspace.read")),
):
try:
return dl_actions.get_my_blocked_actions(_require_actor_ctx(ctx))
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
@router.get("/actions/today")
def workspace_today_actions(
limit: Optional[int] = Query(default=15, ge=1, le=50),
ctx: TenantContext = Depends(require_capability("kairo.workspace.read")),
):
try:
return dl_actions.get_my_today_actions(_require_actor_ctx(ctx), limit=limit or 15)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
@router.get("/initiatives/active")
def workspace_active_initiatives(
limit: Optional[int] = Query(default=None, ge=1, le=100),
ctx: TenantContext = Depends(require_capability("kairo.workspace.read")),
):
return dl_initiatives.get_active_initiatives(ctx, limit=limit)
@router.get("/actors/workload")
def workspace_actor_workload(
ctx: TenantContext = Depends(require_capability("kairo.workspace.read")),
):
return dl_actors.get_actor_workload(ctx)
@router.get("/attention")
def workspace_attention(
ctx: TenantContext = Depends(require_capability("kairo.attention.read")),
):
return dl_attention.get_attention_items(ctx)
@router.get("/next-actions")
def workspace_next_actions(
limit: Optional[int] = Query(default=10, ge=1, le=50),
ctx: TenantContext = Depends(require_capability("kairo.attention.read")),
):
return dl_attention.get_next_action_candidates(ctx, limit=limit or 10)