"""Milestone service — Kompatibilitäts-Wrapper auf RoadmapItems (AP0.8d → AP1.4).""" from __future__ import annotations from datetime import date from typing import Any, Literal, Optional from services import roadmap as roadmap_service MilestoneStatus = Literal[ "planned", "active", "at_risk", "reached", "moved", "discarded" ] MILESTONE_STATUSES = roadmap_service.ROADMAP_ITEM_STATUSES def _as_milestone(item: dict[str, Any]) -> dict[str, Any]: return { "id": item["id"], "tenant_id": item["tenant_id"], "initiative_id": item["initiative_id"], "title": item["title"], "goal_description": item.get("goal_description", ""), "status": item["status"], "target_date": item.get("target_date"), "created_at": item["created_at"], "updated_at": item["updated_at"], } def create_milestone( *, tenant_id: str, initiative_id: str, title: str, goal_description: str = "", status: MilestoneStatus = "planned", target_date: Optional[date] = None, user_id: Optional[str] = None, ) -> dict[str, Any]: item = roadmap_service.create_roadmap_item( tenant_id=tenant_id, initiative_id=initiative_id, title=title, item_type="milestone", goal_description=goal_description, status=status, target_date=target_date, user_id=user_id, ) return _as_milestone(item) def list_milestones_for_initiative(*, tenant_id: str, initiative_id: str) -> list[dict[str, Any]]: items = roadmap_service.list_roadmap_items_for_initiative( tenant_id=tenant_id, initiative_id=initiative_id ) return [_as_milestone(i) for i in items if i["item_type"] == "milestone"] def get_milestone(*, tenant_id: str, milestone_id: str) -> Optional[dict[str, Any]]: item = roadmap_service.get_roadmap_item(tenant_id=tenant_id, item_id=milestone_id) if not item or item["item_type"] != "milestone": return None return _as_milestone(item) def update_milestone( *, tenant_id: str, milestone_id: str, user_id: Optional[str] = None, title: Optional[str] = None, goal_description: Optional[str] = None, status: Optional[MilestoneStatus] = None, target_date: Optional[date] = None, clear_target_date: bool = False, ) -> Optional[dict[str, Any]]: item = roadmap_service.update_roadmap_item( tenant_id=tenant_id, item_id=milestone_id, user_id=user_id, title=title, goal_description=goal_description, status=status, target_date=target_date, clear_target_date=clear_target_date, ) return _as_milestone(item) if item else None def delete_milestone( *, tenant_id: str, milestone_id: str, user_id: Optional[str] = None, ) -> bool: item = roadmap_service.get_roadmap_item(tenant_id=tenant_id, item_id=milestone_id) if not item or item["item_type"] != "milestone": return False return roadmap_service.delete_roadmap_item( tenant_id=tenant_id, item_id=milestone_id, user_id=user_id )