# Tasks: Add Driving Flag to Relationships **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 computed `driving` flag to relationship query responses. ## Format: `[ID] [P?] [Story] Description` - **[P]**: Can run in parallel (different files, no dependencies) - **[Story]**: Which user story this task belongs to (US3 = Query Activity Relationships) - Include exact file paths in descriptions ## Path Conventions - **Source**: `src/xer_mcp/` - **Tests**: `tests/` - **Config**: `pyproject.toml` --- ## Phase 1: Setup (Schema Enhancement) **Purpose**: Add early date columns needed for driving flag computation - [x] T001 Update activities table schema to add early_start_date and early_end_date columns in src/xer_mcp/db/schema.py --- ## Phase 2: Foundational (Parser Enhancement) **Purpose**: Parse early dates from TASK table and store in database **⚠️ CRITICAL**: Must complete before relationship queries can compute driving flag ### Tests - [x] T002 [P] Unit test for TASK handler parsing early dates in tests/unit/test_table_handlers.py (verify early_start_date, early_end_date extracted) ### Implementation - [x] T003 Update TASK table handler to parse early_start_date and early_end_date in src/xer_mcp/parser/table_handlers/task.py - [x] T004 Update database loader to store early dates when inserting activities in src/xer_mcp/db/loader.py **Checkpoint**: Early dates are now parsed and stored - driving computation can begin --- ## Phase 3: User Story 3 - Add Driving Flag to Relationships (Priority: P2) 🎯 FOCUS **Goal**: Compute and return `driving` flag in all relationship query responses **Independent Test**: Load XER file, query relationships, verify driving flag is present and correctly computed ### Tests for User Story 3 > **NOTE: Write these tests FIRST, ensure they FAIL before implementation** - [x] T005 [P] [US3] Update contract test to verify driving flag in list_relationships response in tests/contract/test_list_relationships.py - [x] T006 [P] [US3] Update contract test to verify driving flag in get_predecessors response in tests/contract/test_get_predecessors.py - [x] T007 [P] [US3] Update contract test to verify driving flag in get_successors response in tests/contract/test_get_successors.py - [x] T008 [P] [US3] Unit test for driving flag computation logic in tests/unit/test_db_queries.py (test is_driving_relationship function) ### Implementation for User Story 3 - [x] T009 [US3] Create is_driving_relationship helper function in src/xer_mcp/db/queries.py (implements date comparison logic from research.md) - [x] T010 [US3] Update query_relationships function to JOIN on activity early dates and compute driving flag in src/xer_mcp/db/queries.py - [x] T011 [US3] Update get_predecessors function to JOIN on activity early dates and compute driving flag in src/xer_mcp/db/queries.py - [x] T012 [US3] Update get_successors function to JOIN on activity early dates and compute driving flag in src/xer_mcp/db/queries.py **Checkpoint**: Driving flag now included in all relationship responses --- ## Phase 4: Polish & Validation **Purpose**: Verify integration and documentation alignment - [x] T013 Integration test validating driving flag against sample XER data in tests/integration/test_xer_parsing.py - [x] T014 Run all tests to verify no regressions: pytest tests/ - [x] T015 Run quickstart.md validation - verify driving flag examples match actual output - [x] T016 Run ruff check and fix any linting issues: ruff check src/ --- ## Dependencies & Execution Order ### Phase Dependencies ``` Phase 1 (Schema) │ ▼ Phase 2 (Parser) │ ▼ Phase 3 (Queries) ← MAIN WORK │ ▼ Phase 4 (Polish) ``` ### Task Dependencies Within Phase 3 ``` T005, T006, T007, T008 (Tests) ← Write first, verify FAIL │ ▼ T009 (Helper function) │ ├── T010 (query_relationships) ├── T011 (get_predecessors) └── T012 (get_successors) │ ▼ All tests now PASS ``` ### Parallel Opportunities **Phase 2 Tests + Phase 3 Tests** (can write all tests in parallel): ```bash # All test tasks can run in parallel: Task T002: "Unit test for TASK handler parsing early dates" Task T005: "Update contract test for list_relationships" Task T006: "Update contract test for get_predecessors" Task T007: "Update contract test for get_successors" Task T008: "Unit test for driving flag computation" ``` **Phase 3 Query Updates** (after T009 is complete): ```bash # These can run in parallel once helper function exists: Task T010: "Update query_relationships" Task T011: "Update get_predecessors" Task T012: "Update get_successors" ``` --- ## Parallel Example: Phase 3 ```bash # First: Write all tests in parallel Task: "Update contract test for list_relationships in tests/contract/test_list_relationships.py" Task: "Update contract test for get_predecessors in tests/contract/test_get_predecessors.py" Task: "Update contract test for get_successors in tests/contract/test_get_successors.py" Task: "Unit test for driving flag computation in tests/unit/test_db_queries.py" # Verify all tests FAIL (driving flag not yet implemented) # Then: Implement helper function Task: "Create is_driving_relationship helper in src/xer_mcp/db/queries.py" # Then: Update all queries in parallel Task: "Update query_relationships in src/xer_mcp/db/queries.py" Task: "Update get_predecessors in src/xer_mcp/db/queries.py" Task: "Update get_successors in src/xer_mcp/db/queries.py" # Verify all tests PASS ``` --- ## Implementation Strategy ### Driving Flag Computation (from research.md) The driving flag is computed at query time by comparing dates: ```python def is_driving_relationship( pred_early_end: str | None, succ_early_start: str | None, lag_hours: float, pred_type: str ) -> bool: """Determine if relationship is driving based on early dates.""" if pred_early_end is None or succ_early_start is None: return False # For FS: pred_end + lag = succ_start means driving if pred_type == "FS": # Parse dates, add lag, compare with 1-hour tolerance ... # Similar logic for SS, FF, SF return False ``` ### SQL Query Pattern ```sql SELECT r.*, pred.early_end_date, succ.early_start_date, -- Compute driving in Python after fetch, or use CASE in SQL FROM relationships r JOIN activities pred ON r.pred_task_id = pred.task_id JOIN activities succ ON r.task_id = succ.task_id ``` --- ## Summary | Phase | Tasks | Focus | |-------|-------|-------| | Setup | 1 | Schema update | | Foundational | 3 | Parser enhancement | | US3 Implementation | 8 | Driving flag computation | | Polish | 4 | Validation | | **Total** | **16** | | ### Task Distribution by Type | Type | Count | IDs | |------|-------|-----| | Schema | 1 | T001 | | Tests | 5 | T002, T005-T008 | | Implementation | 6 | T003-T004, T009-T012 | | Validation | 4 | T013-T016 | ### MVP Scope Complete through T012 for minimal viable driving flag implementation. --- ## Notes - [P] tasks = different files, no dependencies on incomplete tasks - [US3] = User Story 3 (Query Activity Relationships) - Constitution mandates TDD: write tests first, verify they fail, then implement - Driving flag is COMPUTED at query time, not stored in database - Use 1-hour tolerance for floating-point date arithmetic - Commit after each task or logical group