Some checks failed
Deploy Development / deploy (push) Successful in 46s
Test Suite / pytest-backend (push) Failing after 1m30s
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 2s
Test Suite / compose-smoke (push) Has been skipped
Entfernt operating_phase aus dem Snapshot zugunsten von Lifecycle + signals. Führt methodenneutrale RoadmapItems (Migration 010), Verify-Pfad und Plan-UI ein. Milestone-API bleibt als Compat-Wrapper; Version 0.13.0-ap1.4. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
3.0 KiB
Python
104 lines
3.0 KiB
Python
"""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
|
|
)
|