Some checks failed
Test Suite / pytest-backend (push) Failing after 2s
Test Suite / k6 /api/health Baseline (push) Has been skipped
Test Suite / playwright-smoke (push) Has been skipped
Test Suite / lint-backend (push) Successful in 3s
Test Suite / compose-smoke (push) Has been skipped
Deploy Development / deploy (push) Failing after 50s
Method-Profiles-API und Auswahl beim Anlegen/Profil; Steuerungs-Meta in Listen und Plan; Projekt-Archetyp-Spiegel, Next-Action-Links und Umlaut-Fix fuer testbare Guidance. Co-authored-by: Cursor <cursoragent@cursor.com>
105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
"""Steering API — methods, profiles and context (AP1.1 / AP2.0)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Optional
|
|
|
|
from capabilities import require_capability
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from pydantic import BaseModel, Field
|
|
from method_profiles.registry import list_method_profiles
|
|
from services import initiatives as initiative_service
|
|
from services import steering_context as sc_service
|
|
from steering.context import get_steering_context_dto
|
|
from steering.methods.registry import list_methods
|
|
from tenant_context import TenantContext
|
|
|
|
router = APIRouter(prefix="/api/steering", tags=["steering"])
|
|
|
|
|
|
class SteeringContextUpdateRequest(BaseModel):
|
|
method_key: Optional[str] = Field(default=None, min_length=1)
|
|
method_profile_key: Optional[str] = Field(default=None, min_length=1)
|
|
clear_method_profile: bool = False
|
|
|
|
|
|
@router.get("/methods")
|
|
def list_steering_methods(
|
|
ctx: TenantContext = Depends(require_capability("kairo.initiative.read")),
|
|
):
|
|
_ = ctx
|
|
return [
|
|
{
|
|
"key": m.key,
|
|
"version": m.version,
|
|
"label": m.label,
|
|
"description": m.description,
|
|
"next_action_strategy_key": m.next_action_strategy_key,
|
|
}
|
|
for m in list_methods()
|
|
]
|
|
|
|
|
|
@router.get("/method-profiles")
|
|
def list_steering_method_profiles(
|
|
initiative_archetype_key: Optional[str] = Query(default=None),
|
|
ctx: TenantContext = Depends(require_capability("kairo.initiative.read")),
|
|
):
|
|
_ = ctx
|
|
return [
|
|
{
|
|
"key": p["key"],
|
|
"label": p["label"],
|
|
"description": p["description"],
|
|
"initiative_archetype_key": p["initiative_archetype_key"],
|
|
"method_key": p["method_key"],
|
|
}
|
|
for p in list_method_profiles(initiative_archetype_key=initiative_archetype_key)
|
|
]
|
|
|
|
|
|
@router.patch("/initiatives/{initiative_id}/context")
|
|
def patch_initiative_steering_context(
|
|
initiative_id: str,
|
|
body: SteeringContextUpdateRequest,
|
|
ctx: TenantContext = Depends(require_capability("kairo.initiative.manage")),
|
|
):
|
|
initiative = initiative_service.get_initiative(
|
|
tenant_id=ctx.tenant_id, initiative_id=initiative_id
|
|
)
|
|
if not initiative:
|
|
raise HTTPException(status_code=404, detail="Vorhaben nicht gefunden")
|
|
|
|
if not body.method_key and not body.method_profile_key and not body.clear_method_profile:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="method_key, method_profile_key oder clear_method_profile erforderlich",
|
|
)
|
|
|
|
try:
|
|
if body.clear_method_profile:
|
|
sc_service.update_method_profile_key(
|
|
tenant_id=ctx.tenant_id,
|
|
initiative_id=initiative_id,
|
|
method_profile_key=None,
|
|
user_id=ctx.user_id,
|
|
)
|
|
elif body.method_profile_key:
|
|
sc_service.update_method_profile_key(
|
|
tenant_id=ctx.tenant_id,
|
|
initiative_id=initiative_id,
|
|
method_profile_key=body.method_profile_key,
|
|
user_id=ctx.user_id,
|
|
)
|
|
elif body.method_key:
|
|
sc_service.update_method_key(
|
|
tenant_id=ctx.tenant_id,
|
|
initiative_id=initiative_id,
|
|
method_key=body.method_key,
|
|
user_id=ctx.user_id,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
|
|
return get_steering_context_dto(ctx, initiative_id=initiative_id)
|