|
| 1 | +# Tasks: Unified Health Status |
| 2 | + |
| 3 | +**Input**: Design documents from `/specs/012-unified-health-status/` |
| 4 | +**Prerequisites**: plan.md, spec.md, research.md, data-model.md, quickstart.md |
| 5 | + |
| 6 | +**Tests**: Not explicitly requested in feature specification; test tasks included only in Polish phase for regression testing. |
| 7 | + |
| 8 | +**Organization**: Tasks grouped by user story to enable independent implementation and testing. |
| 9 | + |
| 10 | +## Format: `[ID] [P?] [Story] Description` |
| 11 | + |
| 12 | +- **[P]**: Can run in parallel (different files, no dependencies) |
| 13 | +- **[Story]**: Which user story this task belongs to (e.g., US1, US2) |
| 14 | +- Include exact file paths in descriptions |
| 15 | + |
| 16 | +## Path Conventions |
| 17 | + |
| 18 | +- **Backend**: `internal/`, `cmd/mcpproxy/` |
| 19 | +- **Frontend**: `frontend/src/` |
| 20 | +- **Tray**: `cmd/mcpproxy-tray/` |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## Phase 1: Setup (Shared Infrastructure) |
| 25 | + |
| 26 | +**Purpose**: Create the health package and core types |
| 27 | + |
| 28 | +- [ ] T001 Create internal/health/ directory structure |
| 29 | +- [ ] T002 Add HealthStatus struct to internal/contracts/types.go |
| 30 | +- [ ] T003 [P] Create health level, admin state, and action constants in internal/health/constants.go |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +## Phase 2: Foundational (Blocking Prerequisites) |
| 35 | + |
| 36 | +**Purpose**: Core health calculator that ALL interfaces depend on |
| 37 | + |
| 38 | +**CRITICAL**: No user story work can begin until this phase is complete |
| 39 | + |
| 40 | +- [ ] T004 Create HealthCalculatorInput struct in internal/health/calculator.go |
| 41 | +- [ ] T005 Create HealthCalculatorConfig struct with ExpiryWarningDuration in internal/health/calculator.go |
| 42 | +- [ ] T006 Implement CalculateHealth() function in internal/health/calculator.go |
| 43 | +- [ ] T007 Add Health field to contracts.Server struct in internal/contracts/types.go |
| 44 | +- [ ] T008 Integrate CalculateHealth() into runtime.GetAllServers() in internal/runtime/runtime.go |
| 45 | +- [ ] T009 Add oauth_expiry_warning_hours config option to internal/config/config.go |
| 46 | + |
| 47 | +**Checkpoint**: Backend health calculation complete - all interfaces can now use server.Health field |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +## Phase 3: User Story 1 - Consistent Status Across Interfaces (Priority: P1) |
| 52 | + |
| 53 | +**Goal**: All four interfaces (CLI, tray, web UI, MCP tools) display identical health status for any server |
| 54 | + |
| 55 | +**Independent Test**: Check any server's status in all four interfaces and verify they show identical health level and summary |
| 56 | + |
| 57 | +### Implementation for User Story 1 |
| 58 | + |
| 59 | +- [ ] T010 [US1] Update CLI upstream list display to use health.level for status emoji in cmd/mcpproxy/upstream_cmd.go |
| 60 | +- [ ] T011 [US1] Update CLI upstream list to show health.summary instead of calculating status in cmd/mcpproxy/upstream_cmd.go |
| 61 | +- [ ] T012 [P] [US1] Update tray server menu to use health.level for status indicator in cmd/mcpproxy-tray/ |
| 62 | +- [ ] T013 [P] [US1] Update web UI ServerCard.vue to use health.level for badge color in frontend/src/components/ServerCard.vue |
| 63 | +- [ ] T014 [US1] Update web UI ServerCard.vue to display health.summary as status text in frontend/src/components/ServerCard.vue |
| 64 | + |
| 65 | +**Checkpoint**: All four interfaces now display the same health level and summary for any given server |
| 66 | + |
| 67 | +--- |
| 68 | + |
| 69 | +## Phase 4: User Story 2 - Actionable Guidance for Issues (Priority: P1) |
| 70 | + |
| 71 | +**Goal**: When a server has an issue, users see what action to take to fix it |
| 72 | + |
| 73 | +**Independent Test**: Create various error conditions and verify each displays an appropriate action |
| 74 | + |
| 75 | +### Implementation for User Story 2 |
| 76 | + |
| 77 | +- [ ] T015 [US2] Add action hints column to CLI upstream list in cmd/mcpproxy/upstream_cmd.go |
| 78 | +- [ ] T016 [US2] Display CLI-appropriate action commands (e.g., "auth login --server=X") based on health.action in cmd/mcpproxy/upstream_cmd.go |
| 79 | +- [ ] T017 [P] [US2] Add clickable action buttons to tray menu based on health.action in cmd/mcpproxy-tray/ |
| 80 | +- [ ] T018 [P] [US2] Add action button component to ServerCard.vue based on health.action in frontend/src/components/ServerCard.vue |
| 81 | +- [ ] T019 [US2] Implement action button handlers (login, restart, enable, approve) in frontend/src/components/ServerCard.vue |
| 82 | + |
| 83 | +**Checkpoint**: All interfaces show appropriate actionable guidance when servers have issues |
| 84 | + |
| 85 | +--- |
| 86 | + |
| 87 | +## Phase 5: User Story 3 - OAuth Token Visibility in Tray/Web (Priority: P2) |
| 88 | + |
| 89 | +**Goal**: OAuth token issues (expired, expiring soon) visible in tray and web UI, not just CLI |
| 90 | + |
| 91 | +**Independent Test**: Let an OAuth token expire and verify tray and web UI both indicate the issue |
| 92 | + |
| 93 | +### Implementation for User Story 3 |
| 94 | + |
| 95 | +- [ ] T020 [US3] Ensure tray displays degraded status (yellow indicator) for token expiring soon in cmd/mcpproxy-tray/ |
| 96 | +- [ ] T021 [US3] Ensure tray displays unhealthy status (red indicator) for expired token in cmd/mcpproxy-tray/ |
| 97 | +- [ ] T022 [P] [US3] Ensure web UI ServerCard shows degraded badge for expiring token in frontend/src/components/ServerCard.vue |
| 98 | +- [ ] T023 [P] [US3] Ensure web UI ServerCard shows unhealthy badge for expired token in frontend/src/components/ServerCard.vue |
| 99 | +- [ ] T024 [US3] Add "Token expiring" / "Token expired" message display in web UI in frontend/src/components/ServerCard.vue |
| 100 | + |
| 101 | +**Checkpoint**: OAuth token status now visible across all interfaces, not just CLI |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## Phase 6: User Story 4 - Admin State Separate from Health (Priority: P2) |
| 106 | + |
| 107 | +**Goal**: Disabled and quarantined servers show admin state clearly distinct from health issues |
| 108 | + |
| 109 | +**Independent Test**: Disable a server and verify it shows "Disabled" state, not an error |
| 110 | + |
| 111 | +### Implementation for User Story 4 |
| 112 | + |
| 113 | +- [ ] T025 [US4] Add gray styling for disabled servers in frontend/src/components/ServerCard.vue |
| 114 | +- [ ] T026 [US4] Add purple styling for quarantined servers in frontend/src/components/ServerCard.vue |
| 115 | +- [ ] T027 [P] [US4] Display admin_state badge instead of level badge when server is disabled/quarantined in frontend/src/components/ServerCard.vue |
| 116 | +- [ ] T028 [P] [US4] Update CLI upstream list to show distinct indicators for disabled/quarantined in cmd/mcpproxy/upstream_cmd.go |
| 117 | +- [ ] T029 [US4] Update tray to show distinct indicators for disabled/quarantined servers in cmd/mcpproxy-tray/ |
| 118 | + |
| 119 | +**Checkpoint**: Admin states are visually distinct from health issues in all interfaces |
| 120 | + |
| 121 | +--- |
| 122 | + |
| 123 | +## Phase 7: User Story 5 - Dashboard Shows Servers Needing Attention (Priority: P3) |
| 124 | + |
| 125 | +**Goal**: Web dashboard highlights servers that need attention (degraded or unhealthy) |
| 126 | + |
| 127 | +**Independent Test**: Have a mix of healthy and unhealthy servers and verify dashboard shows correct count/list |
| 128 | + |
| 129 | +### Implementation for User Story 5 |
| 130 | + |
| 131 | +- [ ] T030 [US5] Add computed property to filter servers needing attention in frontend/src/views/Dashboard.vue |
| 132 | +- [ ] T031 [US5] Create "X servers need attention" banner component in frontend/src/views/Dashboard.vue |
| 133 | +- [ ] T032 [US5] Show quick-fix buttons for each server needing attention in frontend/src/views/Dashboard.vue |
| 134 | +- [ ] T033 [US5] Hide banner when all servers are healthy in frontend/src/views/Dashboard.vue |
| 135 | + |
| 136 | +**Checkpoint**: Dashboard now shows servers needing attention with quick-fix actions |
| 137 | + |
| 138 | +--- |
| 139 | + |
| 140 | +## Phase 8: User Story 6 - MCP Tools Return Unified Health Status (Priority: P2) |
| 141 | + |
| 142 | +**Goal**: LLMs can understand server health from MCP tools without interpreting raw fields |
| 143 | + |
| 144 | +**Independent Test**: Call upstream_servers with operation=list via MCP and verify each server includes health field |
| 145 | + |
| 146 | +### Implementation for User Story 6 |
| 147 | + |
| 148 | +- [ ] T034 [US6] Add health field to handleListUpstreams() response in internal/server/mcp.go |
| 149 | +- [ ] T035 [US6] Ensure health field uses same HealthStatus structure as REST API in internal/server/mcp.go |
| 150 | +- [ ] T036 [US6] Update MCP tool schema to document health field in response in internal/server/mcp.go |
| 151 | + |
| 152 | +**Checkpoint**: LLMs can now get unified health status from MCP tools |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +## Phase 9: Polish & Cross-Cutting Concerns |
| 157 | + |
| 158 | +**Purpose**: Documentation, testing, and cleanup |
| 159 | + |
| 160 | +- [ ] T037 [P] Add HealthStatus schema to oas/swagger.yaml |
| 161 | +- [ ] T038 [P] Update CLAUDE.md with new health fields documentation |
| 162 | +- [ ] T039 [P] Create unit tests for CalculateHealth() in internal/health/calculator_test.go |
| 163 | +- [ ] T039a [P] Add test case verifying FR-016: token with working auto-refresh returns healthy in internal/health/calculator_test.go |
| 164 | +- [ ] T040 Run quickstart.md validation scenarios |
| 165 | +- [ ] T041 Run full test suite (./scripts/run-all-tests.sh) |
| 166 | +- [ ] T042 Run API E2E tests (./scripts/test-api-e2e.sh) |
| 167 | +- [ ] T043 [P] Verify OpenAPI endpoint coverage (./scripts/verify-oas-coverage.sh) |
| 168 | + |
| 169 | +--- |
| 170 | + |
| 171 | +## Dependencies & Execution Order |
| 172 | + |
| 173 | +### Phase Dependencies |
| 174 | + |
| 175 | +- **Setup (Phase 1)**: No dependencies - can start immediately |
| 176 | +- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories |
| 177 | +- **User Stories (Phase 3-8)**: All depend on Foundational phase completion |
| 178 | + - US1 and US2 are both P1 priority - do them first |
| 179 | + - US3, US4 are P2 priority - must run SEQUENTIALLY (both modify ServerCard.vue) |
| 180 | + - US6 is P2 priority - can run in parallel with US3/US4 (MCP is independent of UI) |
| 181 | + - US5 is P3 priority - do after P2 stories |
| 182 | +- **Polish (Phase 9)**: Depends on all user stories being complete |
| 183 | + |
| 184 | +### User Story Dependencies |
| 185 | + |
| 186 | +- **User Story 1 (P1)**: Depends only on Foundational - core consistency |
| 187 | +- **User Story 2 (P1)**: Depends only on Foundational - can run in parallel with US1 |
| 188 | +- **User Story 3 (P2)**: Depends on US1 (needs health display infrastructure) - modifies ServerCard.vue |
| 189 | +- **User Story 4 (P2)**: Depends on US3 (sequential - both modify ServerCard.vue) |
| 190 | +- **User Story 5 (P3)**: Depends on US1 (needs filtering by health.level) |
| 191 | +- **User Story 6 (P2)**: Depends only on Foundational (MCP is independent of UI) |
| 192 | + |
| 193 | +### Within Each User Story |
| 194 | + |
| 195 | +- Implementation before integration tasks |
| 196 | +- Core changes before UI polish |
| 197 | +- Backend changes propagate through all interfaces via server.Health field |
| 198 | + |
| 199 | +### Parallel Opportunities |
| 200 | + |
| 201 | +- T002 and T003 can run in parallel (different files) |
| 202 | +- T012, T013 can run in parallel (tray and web UI) |
| 203 | +- T017, T018 can run in parallel (tray and web UI) |
| 204 | +- T020/T021 and T022/T023 can run in parallel (tray and web UI) |
| 205 | +- T025, T026, T027, T028 partially parallel (T27 || T28) |
| 206 | +- T037, T038, T039, T043 all parallel (documentation and tests) |
| 207 | + |
| 208 | +--- |
| 209 | + |
| 210 | +## Parallel Example: Foundational Phase |
| 211 | + |
| 212 | +```bash |
| 213 | +# After T004-T005, these can run in parallel: |
| 214 | +Task: "Create health constants in internal/health/constants.go" |
| 215 | +Task: "Add Health field to contracts.Server in internal/contracts/types.go" |
| 216 | +``` |
| 217 | + |
| 218 | +## Parallel Example: User Story 1 |
| 219 | + |
| 220 | +```bash |
| 221 | +# T012 and T013 can run in parallel: |
| 222 | +Task: "Update tray server menu in cmd/mcpproxy-tray/" |
| 223 | +Task: "Update ServerCard.vue badge color in frontend/src/components/ServerCard.vue" |
| 224 | +``` |
| 225 | + |
| 226 | +--- |
| 227 | + |
| 228 | +## Implementation Strategy |
| 229 | + |
| 230 | +### MVP First (User Stories 1 + 2 Only) |
| 231 | + |
| 232 | +1. Complete Phase 1: Setup |
| 233 | +2. Complete Phase 2: Foundational (CRITICAL - blocks all stories) |
| 234 | +3. Complete Phase 3: User Story 1 (consistent status) |
| 235 | +4. Complete Phase 4: User Story 2 (actionable guidance) |
| 236 | +5. **STOP and VALIDATE**: All interfaces show identical status with actions |
| 237 | +6. Deploy/demo if ready - this is the core value |
| 238 | + |
| 239 | +### Incremental Delivery |
| 240 | + |
| 241 | +1. Complete Setup + Foundational → Backend health calculation ready |
| 242 | +2. Add US1 + US2 → Core consistency and actions (MVP!) |
| 243 | +3. Add US3 → OAuth visibility in tray/web |
| 244 | +4. Add US4 → Admin state clarity |
| 245 | +5. Add US6 → MCP tools (LLM support) |
| 246 | +6. Add US5 → Dashboard attention banner |
| 247 | +7. Polish → Documentation and testing |
| 248 | + |
| 249 | +### Single Developer Strategy |
| 250 | + |
| 251 | +Priority order: P1 stories first (US1 → US2), then P2 (US3 → US4 → US6), then P3 (US5) |
| 252 | + |
| 253 | +--- |
| 254 | + |
| 255 | +## Notes |
| 256 | + |
| 257 | +- [P] tasks = different files, no dependencies |
| 258 | +- [Story] label maps task to specific user story for traceability |
| 259 | +- Each user story should be independently testable after completion |
| 260 | +- Backend changes (Phase 2) automatically propagate to all interfaces |
| 261 | +- No database schema changes required - health is calculated at runtime |
| 262 | +- Commit after each phase completion for easy rollback |
0 commit comments