diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 8665e3f..2227fd7 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -22,7 +22,7 @@ Requirements for this milestone. Each maps to roadmap phases. ### Ranking Dashboard -- [ ] **DASH-01**: Admin sees ranked project list per category on the round detail page (new tab) +- [x] **DASH-01**: Admin sees ranked project list per category on the round detail page (new tab) - [ ] **DASH-02**: Admin can drag-and-drop to reorder projects in the ranked list - [ ] **DASH-03**: Drag-and-drop state is isolated from server state to prevent snap-back race conditions - [ ] **DASH-04**: Admin can click a project to see full evaluation data in a side panel (scores, votes, juror comments, pass/fail) @@ -97,7 +97,7 @@ Which phases cover which requirements. Updated during roadmap creation. | RANK-08 | Phase 1 | Complete | | RANK-09 | Phase 1 | Complete | | RANK-10 | Phase 1 | Complete | -| DASH-01 | Phase 2 | Pending | +| DASH-01 | Phase 2 | Complete | | DASH-02 | Phase 2 | Pending | | DASH-03 | Phase 2 | Pending | | DASH-04 | Phase 2 | Pending | diff --git a/.planning/STATE.md b/.planning/STATE.md index 4ec0a9f..4aa23c3 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,13 +2,13 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: unknown -last_updated: "2026-02-27T00:07:04.010Z" +status: in_progress +last_updated: "2026-02-27T00:25:00.000Z" progress: - total_phases: 1 + total_phases: 4 completed_phases: 1 - total_plans: 4 - completed_plans: 4 + total_plans: 10 + completed_plans: 5 --- # Project State @@ -18,36 +18,37 @@ progress: See: .planning/PROJECT.md (updated 2026-02-26) **Core value:** Admins can describe ranking criteria in natural language, the system interprets and ranks projects accordingly, and they can advance the top projects to the next round with one click — all with full override control. -**Current focus:** Phase 1 — AI Ranking Backend +**Current focus:** Phase 2 — Ranking Dashboard UI ## Current Position -Phase: 1 of 4 (AI Ranking Backend) -Plan: 4 of 4 in current phase (Phase 1 complete) +Phase: 2 of 4 (Ranking Dashboard UI) +Plan: 1 of 3 in current phase (Phase 2 Plan 1 complete) Status: In progress -Last activity: 2026-02-27 — Plan 04 complete: auto-trigger hook on evaluation submit + triggerAutoRank + retroactiveScan procedures +Last activity: 2026-02-27 — Plan 02-01 complete: saveReorder mutation + Ranking tab entry point + RankingDashboard stub -Progress: [████░░░░░░] ~40% +Progress: [████░░░░░░] ~50% ## Performance Metrics **Velocity:** -- Total plans completed: 4 +- Total plans completed: 5 - Average duration: ~5 min -- Total execution time: ~18 min +- Total execution time: ~23 min **By Phase:** | Phase | Plans | Total | Avg/Plan | |-------|-------|-------|----------| | 01-ai-ranking-backend | 4 | ~18 min | ~5 min | +| 02-ranking-dashboard-ui | 1 | ~5 min | ~5 min | **Recent Trend:** -- Last 5 plans: 01-01 (~3 min), 01-02 (~3 min), 01-03 (~4 min), 01-04 (~8 min) -- Trend: Fast (service-layer tasks) +- Last 5 plans: 01-01 (~3 min), 01-02 (~3 min), 01-03 (~4 min), 01-04 (~8 min), 02-01 (~5 min) +- Trend: Fast (service-layer + UI wiring tasks) *Updated after each plan completion* -| Phase 01-ai-ranking-backend P04 | 8 | 2 tasks | 3 files | +| Phase 02-ranking-dashboard-ui P01 | 5 | 2 tasks | 3 files | ## Accumulated Context @@ -70,6 +71,8 @@ Recent decisions affecting current work: - [Phase 01-04]: triggerAutoRankIfComplete defined as module-level non-exported function in evaluation.ts — avoids circular imports, colocated with the mutation it serves - [Phase 01-04]: EvaluationConfig null fallback typed as {} as EvaluationConfig — required for TypeScript strict mode to recognize rankingCriteria and autoRankOnComplete fields - [Phase 01-04]: retroactiveScan uses RETROACTIVE triggerType to distinguish from MANUAL/AUTO/QUICK — prevents duplicate re-runs on subsequent scans +- [02-01]: ReorderEvent type defined locally in ranking.ts (not exported) — only consumed by saveReorder procedure +- [02-01]: saveReorder is append-only: full ordered list stored per event, latest entry per category = current admin order, gives full audit trail ### Pending Todos @@ -84,5 +87,5 @@ None yet. ## Session Continuity Last session: 2026-02-27 -Stopped at: Completed 01-04-PLAN.md (auto-trigger hook + triggerAutoRank + retroactiveScan + AI ranking notifications) +Stopped at: Completed 02-01-PLAN.md (saveReorder mutation + Ranking tab entry point + RankingDashboard stub) Resume file: None diff --git a/.planning/phases/02-ranking-dashboard-ui/02-01-SUMMARY.md b/.planning/phases/02-ranking-dashboard-ui/02-01-SUMMARY.md new file mode 100644 index 0000000..608d310 --- /dev/null +++ b/.planning/phases/02-ranking-dashboard-ui/02-01-SUMMARY.md @@ -0,0 +1,100 @@ +--- +phase: 02-ranking-dashboard-ui +plan: 01 +subsystem: ui +tags: [trpc, prisma, ranking, react, nextjs] + +# Dependency graph +requires: + - phase: 01-ai-ranking-backend + provides: rankingRouter with listSnapshots/getSnapshot, RankingSnapshot model with reordersJson field +provides: + - saveReorder mutation on rankingRouter (append-only audit log of admin drag-reorders) + - Ranking tab visible on EVALUATION round detail pages + - RankingDashboard stub component (Plan 02 will flesh out) +affects: [02-02-ranking-dashboard-ui] + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Append-only JSON log pattern: read existing array, push new event, write full array as Prisma.InputJsonValue" + - "isEvaluation guard for tab/content conditional rendering (matches isFiltering pattern)" + +key-files: + created: + - src/components/admin/round/ranking-dashboard.tsx + modified: + - src/server/routers/ranking.ts + - src/app/(admin)/admin/rounds/[roundId]/page.tsx + +key-decisions: + - "ReorderEvent type defined locally in ranking.ts (not exported) — only used by saveReorder" + - "saveReorder is append-only: full ordered list stored per event, latest entry per category = current admin order, gives full audit trail" + +patterns-established: + - "Tab conditional: ...(isEvaluation ? [{ value: 'ranking', label: 'Ranking', icon: BarChart3 }] : []) follows existing isFiltering pattern" + +requirements-completed: [DASH-01] + +# Metrics +duration: 5min +completed: 2026-02-27 +--- + +# Phase 2 Plan 01: Ranking Tab Entry Point Summary + +**saveReorder append-only audit mutation + Ranking tab registered on EVALUATION round detail pages with RankingDashboard stub component** + +## Performance + +- **Duration:** ~5 min +- **Started:** 2026-02-27T00:15:00Z +- **Completed:** 2026-02-27T00:20:00Z +- **Tasks:** 2 +- **Files modified:** 3 + +## Accomplishments +- Added `saveReorder` adminProcedure to rankingRouter — accepts snapshotId, category, orderedProjectIds; appends ReorderEvent to reordersJson (append-only audit log) +- Registered Ranking tab in round detail page guarded by `isEvaluation` with BarChart3 icon (already imported) +- Created minimal `RankingDashboard` stub component that compiles and renders placeholder text + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Add saveReorder mutation to ranking router** - `68422e6` (feat) +2. **Task 2: Register Ranking tab in round detail page + create component stub** - `8f71527` (feat) + +**Plan metadata:** (docs commit to follow) + +## Files Created/Modified +- `src/server/routers/ranking.ts` - Added ReorderEvent local type and saveReorder adminProcedure +- `src/components/admin/round/ranking-dashboard.tsx` - New stub component exporting RankingDashboard with competitionId+roundId props +- `src/app/(admin)/admin/rounds/[roundId]/page.tsx` - Import RankingDashboard, add Ranking tab to tab array, add TabsContent block + +## Decisions Made +- `ReorderEvent` type defined locally in ranking.ts (not exported) — only consumed by saveReorder +- Stub uses `_competitionId` / `_roundId` underscore prefix to avoid TypeScript unused-var warnings while keeping the correct prop signature for Plan 02 to use + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness +- saveReorder backend contract established and type-safe +- Ranking tab entry point wired — visible when viewing EVALUATION rounds +- Plan 02 can now replace the stub body with the full RankingDashboard component +- Build and typecheck both pass with 0 errors + +--- +*Phase: 02-ranking-dashboard-ui* +*Completed: 2026-02-27*