diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 962ed91..cc9d936 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -23,10 +23,10 @@ Requirements for this milestone. Each maps to roadmap phases. ### Weight Classification -- [ ] **CLAS-01**: User can classify each item within a setup as base weight, worn, or consumable +- [x] **CLAS-01**: User can classify each item within a setup as base weight, worn, or consumable - [ ] **CLAS-02**: Setup totals display base weight, worn weight, consumable weight, and total separately -- [ ] **CLAS-03**: Items default to "base weight" classification when added to a setup -- [ ] **CLAS-04**: Same item can have different classifications in different setups +- [x] **CLAS-03**: Items default to "base weight" classification when added to a setup +- [x] **CLAS-04**: Same item can have different classifications in different setups ### Weight Visualization @@ -97,10 +97,10 @@ Which phases cover which requirements. Updated during roadmap creation. | UNIT-01 | Phase 7 | Complete | | UNIT-02 | Phase 7 | Complete | | UNIT-03 | Phase 7 | Complete | -| CLAS-01 | Phase 9 | Pending | +| CLAS-01 | Phase 9 | Complete | | CLAS-02 | Phase 9 | Pending | -| CLAS-03 | Phase 9 | Pending | -| CLAS-04 | Phase 9 | Pending | +| CLAS-03 | Phase 9 | Complete | +| CLAS-04 | Phase 9 | Complete | | VIZZ-01 | Phase 9 | Pending | | VIZZ-02 | Phase 9 | Pending | | VIZZ-03 | Phase 9 | Pending | diff --git a/.planning/STATE.md b/.planning/STATE.md index aa82860..3c34d54 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,16 +2,16 @@ gsd_state_version: 1.0 milestone: v1.2 milestone_name: Collection Power-Ups -status: completed -stopped_at: Completed 08-01-PLAN.md -last_updated: "2026-03-16T13:18:00.847Z" -last_activity: 2026-03-16 -- Completed 08-02 search/filter toolbar and category dropdown +status: in-progress +stopped_at: Completed 09-01-PLAN.md +last_updated: "2026-03-16T14:13:32Z" +last_activity: 2026-03-16 -- Completed 09-01 classification schema and badge progress: total_phases: 3 completed_phases: 2 - total_plans: 4 - completed_plans: 4 - percent: 75 + total_plans: 6 + completed_plans: 5 + percent: 83 --- # Project State @@ -21,16 +21,16 @@ progress: See: .planning/PROJECT.md (updated 2026-03-16) **Core value:** Make it effortless to manage gear and plan new purchases -- see how a potential buy affects your total setup weight and cost before committing. -**Current focus:** Phase 8 complete -- search/filter and candidate status done +**Current focus:** Phase 9 in progress -- weight classification and visualization ## Current Position -Phase: 8 of 9 (Search, Filter & Candidate Status) -- COMPLETE -Plan: 2 of 2 -Status: Phase Complete -Last activity: 2026-03-16 -- Completed 08-02 search/filter toolbar and category dropdown +Phase: 9 of 9 (Weight Classification & Visualization) +Plan: 1 of 2 +Status: In Progress +Last activity: 2026-03-16 -- Completed 09-01 classification schema and badge -Progress: [████████░░] 75% +Progress: [█████████░] 83% ## Accumulated Context @@ -51,6 +51,9 @@ Progress: [████████░░] 75% - [Phase 08]: CategoryFilterDropdown kept separate from CategoryPicker (filter vs form concerns) - [Phase 08]: StatusBadge popup uses click-outside + Escape dismiss pattern matching CategoryPicker - [Phase 08]: Status badge uses muted gray tones (bg-gray-100 text-gray-600) per user design decision +- [Phase 09]: ClassificationBadge uses simple click-to-cycle (not popup) since only 3 values +- [Phase 09]: Classification stored on setupItems join table so same item can differ across setups +- [Phase 09]: syncSetupItems preserves classifications via Map before delete/restore after re-insert ### Pending Todos @@ -62,6 +65,6 @@ None active. ## Session Continuity -Last session: 2026-03-16T13:13:36.231Z -Stopped at: Completed 08-01-PLAN.md +Last session: 2026-03-16T14:13:32Z +Stopped at: Completed 09-01-PLAN.md Resume file: None diff --git a/.planning/config.json b/.planning/config.json index 4b9263b..07e2f0b 100644 --- a/.planning/config.json +++ b/.planning/config.json @@ -1,14 +1,14 @@ { - "mode": "yolo", - "granularity": "coarse", - "parallelization": true, - "commit_docs": true, - "model_profile": "quality", - "workflow": { - "research": true, - "plan_check": true, - "verifier": true, - "nyquist_validation": true, - "_auto_chain_active": true - } -} + "mode": "yolo", + "granularity": "coarse", + "parallelization": true, + "commit_docs": true, + "model_profile": "quality", + "workflow": { + "research": true, + "plan_check": true, + "verifier": true, + "nyquist_validation": true, + "_auto_chain_active": true + } +} \ No newline at end of file diff --git a/.planning/phases/09-weight-classification-and-visualization/09-01-SUMMARY.md b/.planning/phases/09-weight-classification-and-visualization/09-01-SUMMARY.md new file mode 100644 index 0000000..2e92abe --- /dev/null +++ b/.planning/phases/09-weight-classification-and-visualization/09-01-SUMMARY.md @@ -0,0 +1,129 @@ +--- +phase: 09-weight-classification-and-visualization +plan: 01 +subsystem: database, api, ui +tags: [drizzle, sqlite, hono, react, tailwind, classification, setup-items] + +# Dependency graph +requires: + - phase: 08-search-filter-and-candidate-status + provides: StatusBadge pattern for click-interactive badges, muted gray styling convention +provides: + - classification column on setupItems join table (base/worn/consumable) + - updateItemClassification service function + - classification-preserving syncSetupItems + - PATCH /api/setups/:id/items/:itemId/classification endpoint + - ClassificationBadge click-to-cycle component + - apiPatch client helper + - useUpdateItemClassification mutation hook +affects: [09-02-weight-breakdown-visualization] + +# Tech tracking +tech-stack: + added: [] + patterns: [click-to-cycle badge, classification preservation on sync, per-join-table metadata] + +key-files: + created: + - src/client/components/ClassificationBadge.tsx + - drizzle/0003_misty_mongu.sql + modified: + - src/db/schema.ts + - src/shared/schemas.ts + - src/shared/types.ts + - src/server/services/setup.service.ts + - src/server/routes/setups.ts + - src/client/lib/api.ts + - src/client/hooks/useSetups.ts + - src/client/routes/setups/$setupId.tsx + - tests/helpers/db.ts + - tests/services/setup.service.test.ts + - tests/routes/setups.test.ts + +key-decisions: + - "ClassificationBadge uses simple click-to-cycle (not popup) since only 3 values" + - "Classification stored on setupItems join table so same item can differ across setups" + - "syncSetupItems reads classifications into Map before delete, restores after re-insert" + +patterns-established: + - "Click-to-cycle badge: for small enums (3 values), direct click cycling is simpler than popup" + - "Join table metadata preservation: save metadata before atomic sync, restore after re-insert" + - "apiPatch helper: PATCH method available in client API library for partial updates" + +requirements-completed: [CLAS-01, CLAS-03, CLAS-04] + +# Metrics +duration: 5min +completed: 2026-03-16 +--- + +# Phase 9 Plan 1: Classification Schema and Badge Summary + +**Per-setup item classification (base/worn/consumable) with click-to-cycle badge, classification-preserving sync, and full test coverage** + +## Performance + +- **Duration:** 5 min +- **Started:** 2026-03-16T14:08:56Z +- **Completed:** 2026-03-16T14:13:32Z +- **Tasks:** 2 +- **Files modified:** 12 + +## Accomplishments +- Added classification column to setupItems table with Drizzle migration (defaults to "base") +- Implemented classification-preserving syncSetupItems that saves/restores classifications across atomic re-sync +- Built PATCH endpoint with Zod validation for updating item classification within a setup +- Created ClassificationBadge component with click-to-cycle interaction (base weight -> worn -> consumable) +- Wired badge into setup detail page below each ItemCard in the category-grouped grid +- Added apiPatch client helper and useUpdateItemClassification mutation hook +- 7 new tests (5 service, 2 route) covering classification CRUD, preservation, cross-setup independence, and validation + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Schema migration, service layer, and tests for classification** - `4491e4c` (feat - TDD red/green) +2. **Task 2: API route, client hook, ClassificationBadge, and wiring** - `fb738d7` (feat) + +## Files Created/Modified +- `src/db/schema.ts` - Added classification column to setupItems table +- `drizzle/0003_misty_mongu.sql` - SQLite migration for classification column +- `src/shared/schemas.ts` - Added classificationSchema and updateClassificationSchema +- `src/shared/types.ts` - Added UpdateClassification type +- `src/server/services/setup.service.ts` - Added updateItemClassification, modified getSetupWithItems and syncSetupItems +- `src/server/routes/setups.ts` - Added PATCH /:id/items/:itemId/classification endpoint +- `src/client/lib/api.ts` - Added apiPatch helper +- `src/client/hooks/useSetups.ts` - Added classification field and useUpdateItemClassification hook +- `src/client/components/ClassificationBadge.tsx` - New click-to-cycle badge component +- `src/client/routes/setups/$setupId.tsx` - Wired ClassificationBadge into item grid +- `tests/helpers/db.ts` - Added classification column to test schema +- `tests/services/setup.service.test.ts` - Added 5 classification tests +- `tests/routes/setups.test.ts` - Added 2 classification integration tests + +## Decisions Made +- ClassificationBadge uses simple click-to-cycle rather than popup (only 3 values, simpler UX) +- Classification stored on setupItems join table (not items table) so same item can have different roles in different setups +- syncSetupItems preserves classifications by reading into Map before delete and restoring after re-insert + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered +None + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- Classification data is available for weight breakdown visualization (Plan 09-02) +- getSetupWithItems returns classification field for every item, ready for grouping by classification +- All 121 tests pass across the full suite + +## Self-Check: PASSED + +All 14 files verified present. Both task commits (4491e4c, fb738d7) confirmed in git history. + +--- +*Phase: 09-weight-classification-and-visualization* +*Completed: 2026-03-16*