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')
7.7 KiB
Tasks: Add Milestone Type to List Milestones Tool
Input: Design documents from /specs/001-schedule-tools/
Prerequisites: plan.md (required), spec.md (required), research.md, data-model.md, contracts/
Tests: TDD is mandated by constitution - tests MUST be written and fail before implementation.
Scope: Enhancement to existing implementation - add milestone_type (start/finish) to milestone query responses per spec clarification.
Change Summary: The spec was updated to require that the list_milestones tool return both Start Milestones and Finish Milestones with their milestone_type field (start/finish for milestones, null otherwise).
Format: [ID] [P?] [Story] Description
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: Which user story this task belongs to (US4 = Query Project Summary)
- Include exact file paths in descriptions
Path Conventions
- Source:
src/xer_mcp/ - Tests:
tests/ - Config:
pyproject.toml
Phase 1: Setup (Schema Enhancement)
Purpose: Add milestone_type column needed for distinguishing start vs finish milestones
- T001 Update activities table schema to add milestone_type column in src/xer_mcp/db/schema.py
Phase 2: Foundational (Parser Enhancement)
Purpose: Parse milestone_type from TASK table and store in database
⚠️ CRITICAL: Must complete before milestone queries can return the type
Tests
- T002 [P] Unit test for TASK handler parsing milestone_type in tests/unit/test_table_handlers.py (verify milestone_type extracted for TT_Mile activities)
Implementation
- T003 Update TASK table handler to parse milestone_type field in src/xer_mcp/parser/table_handlers/task.py
- T004 Update database loader to store milestone_type when inserting activities in src/xer_mcp/db/loader.py
Checkpoint: milestone_type is now parsed and stored - queries can begin
Phase 3: User Story 4 - Add Milestone Type to Queries (Priority: P3)
Goal: Return milestone_type field in milestone query responses
Independent Test: Load XER file, query milestones, verify milestone_type is present and correctly identifies start vs finish milestones
Tests for User Story 4
NOTE: Write these tests FIRST, ensure they FAIL before implementation
- T005 [P] [US4] Update contract test to verify milestone_type field in list_milestones response in tests/contract/test_list_milestones.py
- T006 [P] [US4] Add test case verifying both start and finish milestones are returned with correct types in tests/contract/test_list_milestones.py
Implementation for User Story 4
- T007 [US4] Update query_milestones function to SELECT and return milestone_type in src/xer_mcp/db/queries.py
- T008 [US4] Update list_milestones tool docstring to document milestone_type field in src/xer_mcp/tools/list_milestones.py
Checkpoint: milestone_type now included in milestone responses
Phase 4: Documentation & Contracts
Purpose: Update contracts and documentation to reflect the new field
- T009 [P] Update ActivitySummary schema to include optional milestone_type field in specs/001-schedule-tools/contracts/mcp-tools.json
- T010 [P] Update Activity entity in data-model.md to include milestone_type field in specs/001-schedule-tools/data-model.md
- T011 Update quickstart.md milestone example to show milestone_type in output in specs/001-schedule-tools/quickstart.md
Phase 5: Polish & Validation
Purpose: Verify integration and ensure no regressions
- T012 Run all tests to verify no regressions: uv run pytest tests/
- T013 Run ruff check and fix any linting issues: uv run ruff check src/
- T014 Validate list_milestones output matches updated contract schema
Dependencies & Execution Order
Phase Dependencies
Phase 1 (Schema)
│
▼
Phase 2 (Parser)
│
▼
Phase 3 (Queries) ← MAIN WORK
│
▼
Phase 4 (Docs) ← Can run in parallel with Phase 3
│
▼
Phase 5 (Polish)
Task Dependencies Within Phases
T001 (Schema)
│
├── T002 (Parser test)
│
▼
T003 (Parser impl) ← depends on T001
│
▼
T004 (Loader) ← depends on T003
│
├── T005, T006 (Contract tests)
│
▼
T007 (Query impl) ← depends on T004
│
▼
T008 (Tool docs)
Parallel Opportunities
Phase 2 Tests + Phase 3 Tests (can write all tests in parallel):
Task T002: "Unit test for TASK handler parsing milestone_type"
Task T005: "Update contract test for list_milestones"
Task T006: "Add test for start/finish milestone types"
Phase 4 Documentation (can run in parallel):
Task T009: "Update ActivitySummary schema"
Task T010: "Update Activity entity in data-model.md"
Task T011: "Update quickstart.md example"
Implementation Details
Milestone Type Determination
In Primavera P6, milestones are identified by task_type = 'TT_Mile'. The distinction between Start and Finish milestones is typically:
- XER Field: Check for
milestone_typefield in TASK table (values:MS_Start,MS_Finish) - Fallback: If field not present, can infer from dates:
- Start milestone: Has only
target_start_date(or start = end) - Finish milestone: Has only
target_end_date(or represents completion)
- Start milestone: Has only
Schema Change
-- Add to activities table
milestone_type TEXT -- 'start', 'finish', or NULL for non-milestones
Query Change
SELECT task_id, task_code, task_name,
target_start_date, target_end_date,
status_code, milestone_type
FROM activities
WHERE task_type = 'TT_Mile'
ORDER BY target_start_date, task_code
Response Format
{
"milestones": [
{
"task_id": "M001",
"task_code": "MS-START",
"task_name": "Project Start",
"milestone_type": "start",
"target_start_date": "2026-01-15T08:00:00",
"target_end_date": "2026-01-15T08:00:00",
"status_code": "TK_Complete"
},
{
"task_id": "M002",
"task_code": "MS-END",
"task_name": "Project Complete",
"milestone_type": "finish",
"target_start_date": "2026-06-30T17:00:00",
"target_end_date": "2026-06-30T17:00:00",
"status_code": "TK_NotStart"
}
]
}
Summary
| Phase | Tasks | Focus |
|---|---|---|
| Setup | 1 | Schema update |
| Foundational | 3 | Parser enhancement |
| US4 Implementation | 4 | Milestone type in queries |
| Documentation | 3 | Contracts & docs |
| Polish | 3 | Validation |
| Total | 14 |
Task Distribution by Type
| Type | Count | IDs |
|---|---|---|
| Schema | 1 | T001 |
| Tests | 3 | T002, T005, T006 |
| Implementation | 4 | T003, T004, T007, T008 |
| Documentation | 3 | T009, T010, T011 |
| Validation | 3 | T012, T013, T014 |
Independent Test Criteria
| Verification | How to Test |
|---|---|
| milestone_type parsed | Unit test: parse XER with milestones, verify milestone_type extracted |
| milestone_type in response | Contract test: call list_milestones, verify milestone_type field present |
| Start/Finish distinction | Contract test: verify "Project Start" has type="start", "Project Complete" has type="finish" |
MVP Scope
Complete through T008 for minimal viable milestone_type implementation.
Notes
- [P] tasks = different files, no dependencies on incomplete tasks
- [US4] = User Story 4 (Query Project Summary - milestones)
- Constitution mandates TDD: write tests first, verify they fail, then implement
- milestone_type is stored in database, not computed at query time
- For non-milestone activities, milestone_type should be NULL
- Commit after each task or logical group