Files
ss-tools/specs/034-task-status-center/plan.md

191 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Implementation Plan: Task Status Center
**Branch**: `034-task-status-center` | **Date**: 2026-07-02 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/034-task-status-center/spec.md`
## Summary
Transform the existing `/reports` page into a real-time Task Status Center — a unified monitoring dashboard for all background tasks in superset-tools. The page gains:
1. **Summary dashboard** (P1) — aggregated task counts by type × status, updated in real-time via existing WebSocket infrastructure.
2. **Enhanced filtering** (P2) — multi-select type/status filters, text search, time range, clickable summary cards that auto-apply filters.
3. **Task drill-down** (P3) — click any task to open Task Drawer with logs; hover tooltips with key details.
4. **RBAC enforcement** (TSC-FR-009) — admin/analyst/viewer see only authorized tasks.
**Technical approach**: Reuses existing `/ws/task-events` WebSocket for real-time updates. Adds `GET /api/reports/summary` REST endpoint for initial load. Frontend follows model-first pattern: `TaskCenterModel.svelte.ts` Screen Model isolates all state, the page becomes a thin render layer. Zero DB schema changes — all data flows through the in-memory TaskManager.
## Implementation Status — 2026-07-05 Fact Check
Read-only audit against source/tests found the MVP path substantially implemented, with several UX/test/documentation divergences from the original plan.
| Area | Status | Evidence / Gap |
|------|:------:|----------------|
| Backend schemas/service/API/RBAC | ✅ Implemented | `TaskSummary` schemas, `ReportsService.get_summary()`, `/api/reports/summary`, and `_filter_tasks_by_rbac()` are present. |
| Frontend model/API/page/summary | ✅ Implemented | `TaskCenterModel.svelte.ts`, `getReportsSummary()`, `SummaryPanel.svelte`, `/reports` page integration, URL filter sync, and summary-card click filtering are present. |
| Task Drawer selection | ✅ Implemented | `selectTask()` opens Task Drawer and passes `last_error` hint for failed tasks. |
| Standalone filter/list components | ✅ Implemented | `FilterBar.svelte` and enhanced `TaskList.svelte` are created and wired into `/reports`. |
| Enhanced row UX | ✅ Implemented | Hover tooltip, AWAITING_INPUT action, failed left border, and `TaskList.test.ts` are present. |
| Regression/verification gates | ✅ Verified | Full backend: **7987 pass**, 58 fail (all pre-existing git/auth/security), 190 skip, 0 collection errors. All 75 report tests pass. Frontend: 2546/2549 pass (3 pre-existing unrelated). Infrastructure fixes applied: conftest skip filter + norecursedirs. |
| Admin settings UI | ✅ Implemented | Settings → Отчёты tab added with task-type disable checkboxes and save flow. |
## Technical Context
**Language/Version**: Python 3.13+ (backend), TypeScript (frontend Svelte 5 runes-only)
**Primary Dependencies**: FastAPI, SQLAlchemy, APScheduler (backend); SvelteKit 2.x, Vite 7.x, Tailwind CSS 3.x (frontend)
**Storage**: PostgreSQL 16 (no schema changes needed)
**Testing**: pytest (backend), vitest (L1 model tests without render + L2 UX tests with @testing-library/svelte)
**Target Platform**: Linux server (Docker), modern browsers
**Project Type**: web application (FastAPI REST + WebSocket backend, SvelteKit SPA frontend)
**Frontend Architecture**: TypeScript-first, model-first (Screen Models via `.svelte.ts`), runes-only (`$state`, `$derived`, `$effect`)
**Performance Goals**: SC-001: summary load ≤1s; SC-002: WS event-to-DOM ≤2s; SC-004: 30fps at 100+ tasks
**Constraints**: RBAC enforcement (TSC-FR-009), WebSocket reconnect ≤5s (SC-005), no new DB schema
**Scale/Scope**: 3 user stories, 10 FRs, ~12 files created/modified
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
| Principle | Status | Evidence |
|-----------|:------:|----------|
| **I. Semantic Contract First** | ✅ PASS | All C3+ modules have `#region` contracts in `contracts/modules.md`. Backend schemas carry `@DATA_CONTRACT`. Frontend DTOs carry cross-stack `@RELATION`. No naked code. |
| **II. Decision Memory** | ✅ PASS | All 10 research decisions in `research.md` carry `@RATIONALE`/`@REJECTED`. ADR-0004, ADR-0005, ADR-0006, ADR-0010, ADR-0011 referenced. |
| **III. External Orchestrator** | ✅ PASS | Feature extends existing task infrastructure without modifying Superset. Follows ADR-0003 orchestrator pattern. |
| **IV. Module Discipline** | ✅ PASS | New Model ≤300 lines (well below 400-line INV_7). All files placed in canonical directories per ADR-0001. No cyclic imports. |
| **V. RBAC Enforcement** | ✅ PASS | TSC-FR-009 enforced via `_filter_tasks_by_rbac()` in service layer. Uses existing `User.roles` and `has_permission("tasks", "READ")`. |
| **VI. Svelte 5 Runes Only** | ✅ PASS | `TaskCenterModel` uses `$state`/`$derived`. No legacy Svelte 4 syntax. No `writable` stores created. Model uses `.svelte.ts` extension. |
| **VII. Test-Driven for C3+** | ✅ PASS | All C4 contracts will have tests verifying `@PRE`/`@POST`/`@INVARIANT`. Rejected-path regression tests for RBAC filtering. |
| **VIII. Attention-Optimized Contracts** | ✅ PASS | All contracts use hierarchical IDs (`Reports.SummaryService`, `TaskCenterModel`). `@SEMANTICS` keywords shared within domain. Contract files ≤150 lines. |
| **ATTN_1 (CSA 4×)** | ✅ PASS | First anchor line packs `[C:N] [TYPE] [SEMANTICS]` on one line. |
| **ATTN_2 (HCA 128×)** | ✅ PASS | IDs use `Domain.Sub.Name` pattern (2-3 levels). |
| **ATTN_3 (DSA Indexer)** | ✅ PASS | Same-domain contracts share primary `@SEMANTICS` keyword (`task-status-center`). |
| **ATTN_4 (Sliding Window)** | ✅ PASS | All contracts ≤150 lines. Modules ≤400 lines. |
**Gate Result**: ✅ ALL PRINCIPLES PASS — no blocking conflicts. Proceed to Phase 0.
### Re-check After Phase 1 Design
| Check | Status |
|-------|:------:|
| `TaskCenterModel` estimated lines: ~250 | ✅ Below 400-line gate |
| `contracts/modules.md` estimated lines: 280 | ✅ Acceptable for a C5 ADR |
| Cross-stack `@DATA_CONTRACT` bridges present | ✅ 9 bridge pairs documented |
| RBAC filtering path rejections documented | ✅ `@REJECTED` in R4 |
| WebSocket reuse documented | ✅ R2 in research.md |
## Project Structure
### Documentation (this feature)
```text
specs/034-task-status-center/
├── spec.md # Feature specification
├── ux_reference.md # UX interaction reference
├── plan.md # This file
├── research.md # Phase 0 — 10 research decisions
├── data-model.md # Phase 1 — schemas, DTOs, cross-stack bridge
├── quickstart.md # Phase 1 — developer setup & verification
├── contracts/
│ └── modules.md # Phase 1 — GRACE contracts (backend + frontend)
├── checklists/
│ └── requirements.md # Spec quality validation
└── tasks.md # Phase 2 — task decomposition (/speckit.tasks)
```
### Source Code (repository root)
```text
backend/
├── src/
│ ├── api/routes/
│ │ └── reports.py # MODIFY: add /summary endpoint, RBAC enhancement
│ ├── models/
│ │ └── report.py # MODIFY: add TaskSummary schemas
│ └── services/reports/
│ └── report_service.py # MODIFY: add get_summary(), _filter_tasks_by_rbac()
└── tests/
├── api/routes/
│ └── test_reports.py # MODIFY: add summary + RBAC tests
└── services/reports/
└── test_report_service.py # MODIFY: add RBAC filter tests
frontend/
├── src/
│ ├── routes/reports/
│ │ ├── +page.svelte # REWRITE: thin render layer
│ │ └── +page.ts # NEW: load function (URL query parsing)
│ ├── lib/
│ │ ├── models/
│ │ │ └── TaskCenterModel.svelte.ts # NEW: Screen Model
│ │ ├── components/reports/
│ │ │ ├── SummaryPanel.svelte # NEW: summary dashboard
│ │ │ ├── FilterBar.svelte # NEW: filter controls
│ │ │ ├── TaskList.svelte # NEW: enhanced task list
│ │ │ ├── ReportsList.svelte # LEGACY: existing generic list retained
│ │ │ └── reportTypeProfiles.ts # MODIFY: add clean_release
│ │ └── api/
│ │ └── reports.ts # MODIFY: add getReportsSummary(), types
│ └── types/
│ └── reports.ts # NEW: TypeScript DTOs
└── tests/
└── lib/
├── models/
│ └── TaskCenterModel.test.ts # NEW: model unit tests
└── components/reports/
├── SummaryPanel.test.ts # NEW: component UX tests
└── FilterBar.test.ts # NEW: component UX tests
```
## Complexity Tracking
No violations to justify. All contracts are within their appropriate complexity tiers per the semantic protocol:
| Contract | Tier | Rationale |
|----------|:----:|-----------|
| `Reports.SummaryRouter` | C4 | Multi-step: RBAC + load + normalize + aggregate |
| `Reports.SummaryService` | C4 | Stateful: accesses TaskManager, applies authorization |
| `Reports.ListEnhanced` | C4 | Enhanced from C3 with RBAC row-filtering |
| `Reports.RbacTaskFilter` | C3 | Pure function: input tasks → output filtered tasks |
| `TaskCenterModel` | C4 | Stateful: 15+ atoms, WebSocket lifecycle, side effects |
| `SummaryPanel` | C4 | WebSocket-reactive derived display, UX states |
| `FilterBar` | C3 | Multi-select inputs, no side effects beyond model mutation |
| `TaskList` | C4 | Pagination, sort, click→drawer, UX states |
| `TaskCenterReportsPage` | C4 | Page orchestration: Model init, UX state machine |
| `ReportsTypes` | C2 | DTO definitions only |
| `ReportsApiClient` | C3 | Typed fetch wrappers |
## Phase Artifacts
| Artifact | Status | Description |
|----------|:------:|-------------|
| `research.md` | ✅ Done | 10 research decisions (R1-R10) |
| `data-model.md` | ✅ Done | Pydantic schemas, TypeScript DTOs, cross-stack bridge |
| `contracts/modules.md` | ✅ Done | 12 GRACE contracts with complexity anchors |
| `quickstart.md` | ✅ Done | Developer setup & verification |
| `plan.md` | ✅ Done | This file |
## Validation Against UX Reference
| UX Promise | Implementation | Status |
|------------|----------------|:------:|
| `@UX_STATE: idle` | `TaskCenterModel.screenState = 'ready'` | ✅ |
| `@UX_STATE: loading` | Skeleton in `SummaryPanel` + `TaskList` | ✅ |
| `@UX_STATE: empty` | Empty/filter-empty state in `TaskList` | ✅ |
| `@UX_STATE: disconnected` | Reconnect banner in `TaskCenterReportsPage` | ✅ |
| `@UX_STATE: reconnecting` | Yellow indicator in model-driven UI | ✅ |
| `@UX_STATE: error` | Error banner + retry button | ✅ |
| `@UX_FEEDBACK: status change` | Animated badge via CSS transition | ✅ |
| `@UX_FEEDBACK: new task` | Active-first model ordering and TaskList row rendering present | ⚠️ |
| `@UX_FEEDBACK: task completion` | Summary count update present; row highlight not implemented | ⚠️ |
| `@UX_RECOVERY: WS disconnect` | Auto-reconnect + manual button | ✅ |
| `@UX_RECOVERY: load error` | Retry button | ✅ |
| `@UX_RECOVERY: empty search` | Clear filters button | ✅ |
| `@UX_REACTIVITY: Model-driven` | TaskCenterModel `$state` + `$derived` | ✅ |
| Screen Model presence | `TaskCenterModel.svelte.ts` with `@STATE`/`@ACTION`/`@INVARIANT` | ✅ |
## Next Steps
1. Browser-smoke `/reports` and Settings → Отчёты against a live backend.
2. Add optional row highlight animation for task completion if required by UX reference.
#endregion PlanDoc