docs(09-01): complete classification schema and badge plan

- Create 09-01-SUMMARY.md with execution details
- Update STATE.md to phase 9, plan 1 of 2 complete
- Mark CLAS-01, CLAS-03, CLAS-04 requirements complete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-16 15:16:03 +01:00
parent fb738d7cc2
commit 83103251b1
4 changed files with 166 additions and 34 deletions

View File

@@ -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 |

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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<itemId, classification> 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*