feat: add milestone_type field to distinguish start/finish milestones

Add milestone_type field to milestone queries that indicates whether
a milestone is a start milestone ('start') or finish milestone ('finish').

Changes:
- Add milestone_type column to activities table schema
- Parse milestone_type from XER TASK table (MS_Start/MS_Finish)
- Include milestone_type in list_milestones response
- Update contract tests for milestone_type field
- Update specs, contracts, and documentation

The milestone_type is determined by:
1. Explicit milestone_type field in XER (MS_Start -> 'start', MS_Finish -> 'finish')
2. Derived from task_type (TT_Mile -> 'start', TT_FinMile -> 'finish')
This commit is contained in:
2026-01-08 12:18:34 -05:00
parent bf2f85813e
commit a7b6b76db8
13 changed files with 345 additions and 198 deletions

View File

@@ -87,3 +87,38 @@ class TestListMilestonesContract:
assert "error" in result
assert result["error"]["code"] == "NO_FILE_LOADED"
async def test_list_milestones_includes_milestone_type_field(
self, sample_xer_single_project: Path
) -> None:
"""list_milestones returns milestones with milestone_type field."""
from xer_mcp.tools.list_milestones import list_milestones
from xer_mcp.tools.load_xer import load_xer
await load_xer(file_path=str(sample_xer_single_project))
result = await list_milestones()
# All milestones should have milestone_type field
for milestone in result["milestones"]:
assert "milestone_type" in milestone
async def test_list_milestones_returns_start_and_finish_types(
self, sample_xer_single_project: Path
) -> None:
"""list_milestones returns milestones with correct start/finish types."""
from xer_mcp.tools.list_milestones import list_milestones
from xer_mcp.tools.load_xer import load_xer
await load_xer(file_path=str(sample_xer_single_project))
result = await list_milestones()
# Find milestones by name and verify their types
milestones_by_name = {m["task_name"]: m for m in result["milestones"]}
# "Project Start" should be a start milestone
assert milestones_by_name["Project Start"]["milestone_type"] == "start"
# "Project Complete" should be a finish milestone
assert milestones_by_name["Project Complete"]["milestone_type"] == "finish"