"""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 portfolio_steering as dl_portfolio_steering from data_layer import workspace as dl_workspace from fastapi import APIRouter, Depends, HTTPException, Query from pydantic import BaseModel, Field from services import initiatives as initiative_service from tenant_context import TenantContext router = APIRouter(prefix="/api/workspace", tags=["workspace"]) class PortfolioReorderRequest(BaseModel): initiative_ids: list[str] = Field(min_length=1) 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) @router.get("/steering") def workspace_steering( limit: Optional[int] = Query(default=30, ge=1, le=100), ctx: TenantContext = Depends(require_capability("kairo.attention.read")), ): """Portfolio-Steuerung — Kernel-Aggregation über alle aktiven Initiativen (K-Ext-5).""" return dl_portfolio_steering.get_portfolio_steering( ctx, total_attention=limit or 30, total_next_work=min(limit or 30, 15), ) @router.post("/portfolio/reorder") def workspace_portfolio_reorder( body: PortfolioReorderRequest, ctx: TenantContext = Depends(require_capability("kairo.initiative.manage")), ): try: return initiative_service.reorder_portfolio( tenant_id=ctx.tenant_id, initiative_ids=body.initiative_ids, user_id=ctx.user_id, ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc