diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 4c3e4c8..e8fd93e 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -61,11 +61,12 @@ Plans: 2. User can add and remove collection items from a setup 3. User can see total weight and cost for a setup, computed live from current item data 4. User sees a dashboard home page with cards linking to their collection, active threads, and setups -**Plans**: TBD +**Plans:** 3 plans Plans: -- [ ] 03-01: TBD -- [ ] 03-02: TBD +- [ ] 03-01-PLAN.md — Backend TDD: setup schema, service, routes, and tests with junction table +- [ ] 03-02-PLAN.md — Frontend: navigation restructure, dashboard, setup UI, and item picker +- [ ] 03-03-PLAN.md — Visual verification checkpoint ## Progress @@ -76,4 +77,4 @@ Phases execute in numeric order: 1 -> 2 -> 3 |-------|----------------|--------|-----------| | 1. Foundation and Collection | 4/4 | Complete | 2026-03-14 | | 2. Planning Threads | 3/3 | Complete | 2026-03-15 | -| 3. Setups and Dashboard | 0/0 | Not started | - | +| 3. Setups and Dashboard | 0/3 | Not started | - | diff --git a/.planning/phases/03-setups-and-dashboard/03-01-PLAN.md b/.planning/phases/03-setups-and-dashboard/03-01-PLAN.md new file mode 100644 index 0000000..40308f4 --- /dev/null +++ b/.planning/phases/03-setups-and-dashboard/03-01-PLAN.md @@ -0,0 +1,176 @@ +--- +phase: 03-setups-and-dashboard +plan: 01 +type: tdd +wave: 1 +depends_on: [] +files_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/server/index.ts + - tests/helpers/db.ts + - tests/services/setup.service.test.ts + - tests/routes/setups.test.ts +autonomous: true +requirements: + - SETP-01 + - SETP-02 + - SETP-03 + +must_haves: + truths: + - "Setup CRUD operations work (create, read, update, delete)" + - "Items can be added to and removed from a setup via junction table" + - "Setup totals (weight, cost, item count) are computed correctly via SQL aggregation" + - "Deleting a setup cascades to setup_items, deleting a collection item cascades from setup_items" + artifacts: + - path: "src/db/schema.ts" + provides: "setups and setupItems table definitions" + contains: "setupItems" + - path: "src/shared/schemas.ts" + provides: "Zod schemas for setup create/update/sync" + contains: "createSetupSchema" + - path: "src/shared/types.ts" + provides: "Setup and SetupWithItems TypeScript types" + contains: "CreateSetup" + - path: "src/server/services/setup.service.ts" + provides: "Setup business logic with DB injection" + exports: ["getAllSetups", "getSetupWithItems", "createSetup", "updateSetup", "deleteSetup", "syncSetupItems", "removeSetupItem"] + - path: "src/server/routes/setups.ts" + provides: "Hono API routes for setups" + contains: "setupRoutes" + - path: "tests/services/setup.service.test.ts" + provides: "Unit tests for setup service" + min_lines: 50 + - path: "tests/routes/setups.test.ts" + provides: "Integration tests for setup API routes" + min_lines: 30 + key_links: + - from: "src/server/routes/setups.ts" + to: "src/server/services/setup.service.ts" + via: "service function calls" + pattern: "setup\\.service" + - from: "src/server/index.ts" + to: "src/server/routes/setups.ts" + via: "route mounting" + pattern: "setupRoutes" + - from: "src/server/services/setup.service.ts" + to: "src/db/schema.ts" + via: "drizzle schema imports" + pattern: "import.*schema" +--- + + +Build the complete setup backend: database schema (setups + setup_items junction table), shared Zod schemas/types, service layer with CRUD + item sync + totals aggregation, and Hono API routes. All with TDD. + +Purpose: Provides the data layer and API that the frontend (Plan 02) will consume. The many-to-many junction table is the only new DB pattern in this project. +Output: Working API at /api/setups with full test coverage. + + + +@/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md +@/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/03-setups-and-dashboard/03-RESEARCH.md + +@src/db/schema.ts +@src/shared/schemas.ts +@src/shared/types.ts +@src/server/index.ts +@tests/helpers/db.ts + + + + +From src/server/services/thread.service.ts (pattern reference): +```typescript +export function getAllThreads(db: Db = prodDb, includeResolved = false) { ... } +export function getThread(db: Db = prodDb, id: number) { ... } +export function createThread(db: Db = prodDb, data: CreateThread) { ... } +export function deleteThread(db: Db = prodDb, id: number) { ... } +``` + +From src/server/routes/threads.ts (pattern reference): +```typescript +const threadRoutes = new Hono<{ Variables: { db: Db } }>(); +threadRoutes.get("/", (c) => { ... }); +threadRoutes.post("/", zValidator("json", createThreadSchema), (c) => { ... }); +``` + +From tests/helpers/db.ts: +```typescript +export function createTestDb() { ... } // Returns in-memory Drizzle instance +``` + + + + + Setup Backend with Junction Table + + src/db/schema.ts, src/shared/schemas.ts, src/shared/types.ts, + src/server/services/setup.service.ts, src/server/routes/setups.ts, + src/server/index.ts, tests/helpers/db.ts, + tests/services/setup.service.test.ts, tests/routes/setups.test.ts + + + Service layer (setup.service.ts): + - getAllSetups: returns setups with itemCount, totalWeight (grams), totalCost (cents) via SQL subqueries + - getSetupWithItems: returns single setup with full item details (joined with categories), null if not found + - createSetup: creates setup with name, returns created setup + - updateSetup: updates setup name, returns updated setup, null if not found + - deleteSetup: deletes setup (cascade deletes setup_items), returns boolean + - syncSetupItems: delete-all + re-insert in transaction, accepts setupId + itemIds array + - removeSetupItem: removes single item from setup by setupId + itemId + + API routes (setups.ts): + - GET /api/setups -> list all setups with aggregated totals + - GET /api/setups/:id -> single setup with items + - POST /api/setups -> create setup (validates name via createSetupSchema) + - PUT /api/setups/:id -> update setup name + - DELETE /api/setups/:id -> delete setup + - PUT /api/setups/:id/items -> sync setup items (validates itemIds via syncSetupItemsSchema) + - DELETE /api/setups/:id/items/:itemId -> remove single item from setup + + Edge cases: + - Syncing with empty itemIds array clears all items from setup + - Deleting a collection item cascades removal from all setups + - getAllSetups returns 0 for weight/cost when setup has no items (COALESCE) + + + 1. Add setups and setupItems tables to src/db/schema.ts (with cascade FKs) + 2. Add Zod schemas (createSetupSchema, updateSetupSchema, syncSetupItemsSchema) to src/shared/schemas.ts + 3. Add types (CreateSetup, UpdateSetup, SyncSetupItems, Setup, SetupItem) to src/shared/types.ts + 4. Add setups and setup_items CREATE TABLE to tests/helpers/db.ts + 5. Implement setup.service.ts following thread.service.ts pattern (db as first param with prod default) + 6. Implement setups.ts routes following threads.ts pattern (Hono with zValidator) + 7. Mount setupRoutes in src/server/index.ts + 8. Use raw SQL in Drizzle sql`` for correlated subqueries in getAllSetups (per Phase 2 decision about table.column refs) + + + + +```bash +bun test tests/services/setup.service.test.ts && bun test tests/routes/setups.test.ts && bun test +``` +All setup service and route tests pass. Full test suite remains green. + + + +- Setup CRUD API responds correctly at all 7 endpoints +- Junction table correctly links items to setups (many-to-many) +- Totals aggregation returns correct weight/cost/count via SQL +- Cascade delete works both directions (setup deletion, item deletion) +- All existing tests still pass + + + +After completion, create `.planning/phases/03-setups-and-dashboard/03-01-SUMMARY.md` + diff --git a/.planning/phases/03-setups-and-dashboard/03-02-PLAN.md b/.planning/phases/03-setups-and-dashboard/03-02-PLAN.md new file mode 100644 index 0000000..3258315 --- /dev/null +++ b/.planning/phases/03-setups-and-dashboard/03-02-PLAN.md @@ -0,0 +1,362 @@ +--- +phase: 03-setups-and-dashboard +plan: 02 +type: execute +wave: 2 +depends_on: ["03-01"] +files_modified: + - src/client/routes/index.tsx + - src/client/routes/collection/index.tsx + - src/client/routes/setups/index.tsx + - src/client/routes/setups/$setupId.tsx + - src/client/routes/__root.tsx + - src/client/components/TotalsBar.tsx + - src/client/components/DashboardCard.tsx + - src/client/components/SetupCard.tsx + - src/client/components/ItemPicker.tsx + - src/client/components/ItemCard.tsx + - src/client/hooks/useSetups.ts + - src/client/hooks/useItems.ts + - src/client/stores/uiStore.ts +autonomous: true +requirements: + - SETP-01 + - SETP-02 + - SETP-03 + - DASH-01 + +must_haves: + truths: + - "User sees dashboard at / with three summary cards (Collection, Planning, Setups)" + - "User can navigate to /collection and see the existing gear/planning tabs" + - "User can create a named setup from the setups list page" + - "User can add/remove collection items to a setup via checklist picker" + - "User can see total weight and cost for a setup in the sticky bar" + - "GearBox title in TotalsBar links back to dashboard from all sub-pages" + artifacts: + - path: "src/client/routes/index.tsx" + provides: "Dashboard page with three summary cards" + contains: "DashboardCard" + - path: "src/client/routes/collection/index.tsx" + provides: "Gear + Planning tabs (moved from old index.tsx)" + contains: "CollectionView" + - path: "src/client/routes/setups/index.tsx" + provides: "Setup list with create form" + contains: "createFileRoute" + - path: "src/client/routes/setups/$setupId.tsx" + provides: "Setup detail with item cards and totals" + contains: "ItemPicker" + - path: "src/client/components/TotalsBar.tsx" + provides: "Route-aware totals bar with optional stats and linkable title" + contains: "linkTo" + - path: "src/client/components/DashboardCard.tsx" + provides: "Dashboard summary card component" + contains: "DashboardCard" + - path: "src/client/components/ItemPicker.tsx" + provides: "Checklist picker in SlideOutPanel for selecting items" + contains: "ItemPicker" + - path: "src/client/hooks/useSetups.ts" + provides: "TanStack Query hooks for setup CRUD" + exports: ["useSetups", "useSetup", "useCreateSetup", "useDeleteSetup", "useSyncSetupItems", "useRemoveSetupItem"] + key_links: + - from: "src/client/routes/index.tsx" + to: "src/client/hooks/useSetups.ts" + via: "useSetups() for setup count" + pattern: "useSetups" + - from: "src/client/routes/setups/$setupId.tsx" + to: "/api/setups/:id" + via: "useSetup() hook" + pattern: "useSetup" + - from: "src/client/routes/__root.tsx" + to: "src/client/components/TotalsBar.tsx" + via: "route-aware props" + pattern: "TotalsBar" + - from: "src/client/components/ItemPicker.tsx" + to: "src/client/hooks/useSetups.ts" + via: "useSyncSetupItems mutation" + pattern: "useSyncSetupItems" +--- + + +Build the complete frontend: restructure navigation (move gear/planning to /collection, create dashboard at /), build setup list and detail pages with item picker, make TotalsBar route-aware, and create the dashboard home page. + +Purpose: Delivers the user-facing features for setups and dashboard, completing all v1 requirements. +Output: Working dashboard, setup CRUD UI, and item picker -- all wired to the backend from Plan 01. + + + +@/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md +@/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/phases/03-setups-and-dashboard/03-CONTEXT.md +@.planning/phases/03-setups-and-dashboard/03-RESEARCH.md +@.planning/phases/03-setups-and-dashboard/03-01-SUMMARY.md + +@src/client/routes/__root.tsx +@src/client/routes/index.tsx +@src/client/components/TotalsBar.tsx +@src/client/components/ItemCard.tsx +@src/client/components/CategoryHeader.tsx +@src/client/components/ThreadCard.tsx +@src/client/components/SlideOutPanel.tsx +@src/client/hooks/useItems.ts +@src/client/hooks/useThreads.ts +@src/client/hooks/useTotals.ts +@src/client/stores/uiStore.ts +@src/client/lib/api.ts + + + + +From src/shared/schemas.ts (added by Plan 01): +```typescript +export const createSetupSchema = z.object({ + name: z.string().min(1, "Setup name is required"), +}); +export const updateSetupSchema = z.object({ + name: z.string().min(1).optional(), +}); +export const syncSetupItemsSchema = z.object({ + itemIds: z.array(z.number().int().positive()), +}); +``` + +From src/shared/types.ts (added by Plan 01): +```typescript +export type CreateSetup = z.infer; +export type Setup = typeof setups.$inferSelect; +export type SetupItem = typeof setupItems.$inferSelect; +``` + +API endpoints from Plan 01: +- GET /api/setups -> SetupListItem[] (with itemCount, totalWeight, totalCost) +- GET /api/setups/:id -> SetupWithItems (setup + items array with category info) +- POST /api/setups -> Setup +- PUT /api/setups/:id -> Setup +- DELETE /api/setups/:id -> { success: boolean } +- PUT /api/setups/:id/items -> { success: boolean } (body: { itemIds: number[] }) +- DELETE /api/setups/:id/items/:itemId -> { success: boolean } + + + +From src/client/hooks/useThreads.ts: +```typescript +export function useThreads(includeResolved = false) { + return useQuery({ queryKey: ["threads", includeResolved], queryFn: ... }); +} +export function useCreateThread() { + const qc = useQueryClient(); + return useMutation({ mutationFn: ..., onSuccess: () => qc.invalidateQueries({ queryKey: ["threads"] }) }); +} +``` + +From src/client/lib/api.ts: +```typescript +export function apiGet(url: string): Promise +export function apiPost(url: string, body: unknown): Promise +export function apiPut(url: string, body: unknown): Promise +export function apiDelete(url: string): Promise +``` + + + + + + + Task 1: Navigation restructure, TotalsBar refactor, and setup hooks + + src/client/components/TotalsBar.tsx, + src/client/routes/index.tsx, + src/client/routes/collection/index.tsx, + src/client/routes/__root.tsx, + src/client/hooks/useSetups.ts, + src/client/hooks/useItems.ts, + src/client/components/DashboardCard.tsx, + src/client/stores/uiStore.ts + + + **1. Refactor TotalsBar to accept optional props (per CONTEXT.md decisions):** + - Add props: `title?: string`, `stats?: Array<{label: string, value: string}>`, `linkTo?: string` + - When no `stats` prop: show title only (for dashboard) + - When `stats` provided: render them instead of fetching global totals internally + - When `linkTo` provided: wrap title in `` (per decision: GearBox title always links to /) + - Default behavior (no props): fetch global totals with useTotals() and display as before (backward compatible for collection page) + - Dashboard passes no linkTo (already on dashboard). All other pages pass `linkTo="/"` + + **2. Move current index.tsx content to collection/index.tsx:** + - Create `src/client/routes/collection/index.tsx` + - Move the entire HomePage, CollectionView, and PlanningView content from current `index.tsx` + - Update route: `createFileRoute("/collection/")` with same `validateSearch` for tab param + - Update handleTabChange to navigate to `/collection` instead of `/` + - The TotalsBar in __root.tsx will automatically show global stats on this page (default behavior) + + **3. Rewrite index.tsx as Dashboard (per CONTEXT.md decisions):** + - Three equal-width cards (grid-cols-1 md:grid-cols-3 gap-6) + - Collection card: shows item count, total weight, total cost. Links to `/collection`. Empty state shows "Get started" + - Planning card: shows active thread count. Links to `/collection?tab=planning` + - Setups card: shows setup count. Links to `/setups` + - Use `useTotals()` for collection stats, `useThreads(false)` for active threads, `useSetups()` for setup count + - "GearBox" title only in TotalsBar (no stats on dashboard) -- pass no stats prop + - Clean layout: max-w-7xl, centered, lots of whitespace + + **4. Create DashboardCard.tsx component:** + - Props: `to: string`, `title: string`, `icon: ReactNode`, `stats: Array<{label: string, value: string}>`, `emptyText?: string` + - Card with hover shadow transition, rounded-xl, padding + - Wraps in `` for navigation + - Shows icon, title, stats list, and optional empty state text + + **5. Create useSetups.ts hooks (follows useThreads.ts pattern exactly):** + - `useSetups()`: queryKey ["setups"], fetches GET /api/setups + - `useSetup(setupId: number | null)`: queryKey ["setups", setupId], enabled when setupId != null + - `useCreateSetup()`: POST /api/setups, invalidates ["setups"] + - `useUpdateSetup(setupId: number)`: PUT /api/setups/:id, invalidates ["setups"] + - `useDeleteSetup()`: DELETE /api/setups/:id, invalidates ["setups"] + - `useSyncSetupItems(setupId: number)`: PUT /api/setups/:id/items, invalidates ["setups"] + - `useRemoveSetupItem(setupId: number)`: DELETE /api/setups/:id/items/:itemId, invalidates ["setups"] + - Define response types inline: `SetupListItem` (with itemCount, totalWeight, totalCost) and `SetupWithItems` (with items array including category info) + + **6. Update __root.tsx:** + - Pass route-aware props to TotalsBar based on current route matching + - On dashboard (`/`): no stats, no linkTo + - On collection (`/collection`): default behavior (TotalsBar fetches its own stats), linkTo="/" + - On thread detail: linkTo="/" (keep current behavior) + - On setups: linkTo="/" + - On setup detail: TotalsBar with setup-specific title and stats (will be handled by setup detail page passing context) + - Update FAB visibility: only show on `/collection` route when gear tab is active (not on dashboard, not on setups). Match `/collection` route instead of just hiding on thread pages + - Update ResolveDialog onResolved navigation: change from `{ to: "/", search: { tab: "planning" } }` to `{ to: "/collection", search: { tab: "planning" } }` + + **7. Add setup-related UI state to uiStore.ts:** + - Add `itemPickerOpen: boolean` state + - Add `openItemPicker()` and `closeItemPicker()` actions + - Add `confirmDeleteSetupId: number | null` state with open/close actions + + **8. Update useItems invalidation (Pitfall 1 from research):** + - In `useUpdateItem` and `useDeleteItem` mutation `onSuccess`, also invalidate `["setups"]` query key + - This ensures setup totals update when a collection item's weight/price changes or item is deleted + + IMPORTANT: After creating route files, the TanStack Router plugin will auto-regenerate `routeTree.gen.ts`. Restart the dev server if needed. + + + cd /home/jean-luc-makiola/Development/projects/GearBox && npx tsc --noEmit 2>&1 | head -30 + + + - Dashboard renders at / with three summary cards showing real data + - Collection view with gear/planning tabs works at /collection + - GearBox title links back to / from all sub-pages + - TotalsBar shows contextual stats per page (title-only on dashboard, global on collection) + - FAB only appears on /collection gear tab + - Thread resolution redirects to /collection?tab=planning + - Setup query/mutation hooks are functional + + + + + Task 2: Setup list page, detail page, and item picker + + src/client/routes/setups/index.tsx, + src/client/routes/setups/$setupId.tsx, + src/client/components/SetupCard.tsx, + src/client/components/ItemPicker.tsx, + src/client/components/ItemCard.tsx + + + **1. Create SetupCard.tsx (reference ThreadCard.tsx pattern):** + - Props: `id: number`, `name: string`, `itemCount: number`, `totalWeight: number`, `totalCost: number` + - Card with rounded-xl, shadow-sm, hover:shadow-md transition + - Shows setup name, item count pill, formatted weight and cost + - Wraps in `` + - Use `formatWeight` and `formatPrice` from existing `lib/formatters` + + **2. Create setups list page (src/client/routes/setups/index.tsx):** + - Route: `createFileRoute("/setups/")` + - Inline name input + "Create" button at top (same pattern as thread creation in PlanningView) + - Uses `useSetups()` and `useCreateSetup()` hooks + - Grid layout: grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 + - Each setup rendered as SetupCard + - Empty state: icon + "No setups yet" message + "Create one to plan your loadout" + - Loading skeleton: 2 placeholder cards + + **3. Create ItemPicker.tsx (checklist in SlideOutPanel, per CONTEXT.md decisions):** + - Props: `setupId: number`, `currentItemIds: number[]`, `isOpen: boolean`, `onClose: () => void` + - Renders inside a SlideOutPanel with title "Select Items" + - Fetches all collection items via `useItems()` + - Groups items by category with emoji headers (same grouping as CollectionView) + - Each item is a checkbox row: `[x] emoji ItemName (weight, price)` + - Pre-checks items already in the setup (from `currentItemIds`) + - Local state tracks toggled item IDs + - "Done" button at bottom calls `useSyncSetupItems(setupId)` with selected IDs, then closes + - Scrollable list for large collections (max-h with overflow-y-auto) + - "Cancel" closes without saving + + **4. Create setup detail page (src/client/routes/setups/$setupId.tsx):** + - Route: `createFileRoute("/setups/$setupId")` + - Uses `useSetup(setupId)` to fetch setup with items + - Sticky TotalsBar override: pass setup name as title, setup-specific stats (item count, total weight, total cost) + - Compute totals client-side from items array (per research recommendation) + - Render a local TotalsBar-like sticky bar at top of the page with setup name + stats + - "Add Items" button opens ItemPicker via SlideOutPanel + - "Delete Setup" button with ConfirmDialog confirmation + - Item cards grouped by category using CategoryHeader + ItemCard (same visual as collection) + - Each ItemCard gets a small x remove button overlay (per CONTEXT.md: non-destructive, no confirmation) + - Per-category subtotals in CategoryHeader (weight/cost within this setup) + - Empty state when no items: "No items in this setup" + "Add Items" button + - On successful delete, navigate to `/setups` + + **5. Modify ItemCard.tsx to support remove mode:** + - Add optional prop: `onRemove?: () => void` + - When `onRemove` provided, show a small x icon button in top-right corner of card + - x button calls `onRemove` on click (stops propagation to prevent edit panel opening) + - Subtle styling: small, semi-transparent, visible on hover or always visible but muted + - Does NOT change existing behavior when `onRemove` is not provided + + IMPORTANT: Use `useRemoveSetupItem(setupId)` for the x button on cards. Use `useSyncSetupItems(setupId)` for the checklist picker "Done" action. These are separate mutations for separate UX patterns (per research: batch sync vs single remove). + + + cd /home/jean-luc-makiola/Development/projects/GearBox && npx tsc --noEmit 2>&1 | head -30 + + + - Setup list page at /setups shows all setups with name, item count, weight, cost + - User can create a new setup via inline form + - Setup detail page shows items grouped by category with per-category subtotals + - Item picker opens in SlideOutPanel with category-grouped checkboxes + - Selecting items and clicking "Done" syncs items to setup + - x button on item cards removes item from setup without confirmation + - Delete setup button with confirmation dialog works + - All existing TypeScript compilation passes + + + + + + +```bash +# TypeScript compilation +npx tsc --noEmit + +# All tests pass (backend + existing) +bun test + +# Dev server starts without errors +# (manual: bun run dev, check no console errors) +``` + + + +- Dashboard at / shows three summary cards with real data +- Collection at /collection has gear + planning tabs (same as before, different URL) +- Setups list at /setups shows setup cards with totals +- Setup detail at /setups/:id shows items grouped by category with totals +- Item picker allows adding/removing items via checklist +- GearBox title links back to dashboard from all pages +- TotalsBar shows contextual stats per page +- All internal links updated (thread resolution, FAB visibility) +- TypeScript compiles, all tests pass + + + +After completion, create `.planning/phases/03-setups-and-dashboard/03-02-SUMMARY.md` + diff --git a/.planning/phases/03-setups-and-dashboard/03-03-PLAN.md b/.planning/phases/03-setups-and-dashboard/03-03-PLAN.md new file mode 100644 index 0000000..ef2dd2d --- /dev/null +++ b/.planning/phases/03-setups-and-dashboard/03-03-PLAN.md @@ -0,0 +1,111 @@ +--- +phase: 03-setups-and-dashboard +plan: 03 +type: execute +wave: 3 +depends_on: ["03-01", "03-02"] +files_modified: [] +autonomous: false +requirements: + - SETP-01 + - SETP-02 + - SETP-03 + - DASH-01 + +must_haves: + truths: + - "All four phase requirements verified working end-to-end in browser" + - "Navigation restructure works correctly (/, /collection, /setups, /setups/:id)" + - "Setup item sync and removal work correctly" + - "Dashboard cards show accurate summary data" + artifacts: [] + key_links: [] +--- + + +Verify the complete Phase 3 implementation in the browser: dashboard, navigation, setup CRUD, item picker, and totals. + +Purpose: Human confirmation that all features work correctly before marking phase complete. +Output: Verified working application. + + + +@/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md +@/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md + + + +@.planning/ROADMAP.md +@.planning/phases/03-setups-and-dashboard/03-CONTEXT.md +@.planning/phases/03-setups-and-dashboard/03-01-SUMMARY.md +@.planning/phases/03-setups-and-dashboard/03-02-SUMMARY.md + + + + + + Task 1: Visual verification of Phase 3 features + Human verifies all Phase 3 features in the browser + Complete Phase 3: Dashboard home page, navigation restructure, setup CRUD with item management, and live totals + + Start the dev server: `bun run dev` + + **1. Dashboard (DASH-01):** + - Visit http://localhost:5173/ + - Verify three cards: Collection (item count, weight, cost), Planning (active thread count), Setups (setup count) + - Verify "GearBox" title in top bar, no stats shown on dashboard + - Click Collection card -> navigates to /collection + - Click Planning card -> navigates to /collection?tab=planning + - Click Setups card -> navigates to /setups + + **2. Navigation restructure:** + - At /collection: verify gear/planning tabs work as before + - Verify "GearBox" title in TotalsBar links back to / (dashboard) + - Verify floating + button only appears on /collection gear tab (not on dashboard, setups, or planning tab) + - Go to a thread detail page -> verify "GearBox" links back to dashboard + + **3. Setup creation (SETP-01):** + - Navigate to /setups + - Create a setup named "Summer Bikepacking" using inline form + - Verify it appears in the list as a card + + **4. Item management (SETP-02):** + - Click the new setup card to open detail page + - Click "Add Items" button + - Verify checklist picker opens in slide-out panel with items grouped by category + - Check several items, click "Done" + - Verify items appear on setup detail page grouped by category + - Click x on an item card to remove it from setup (no confirmation) + - Verify item disappears from setup but still exists in collection + + **5. Setup totals (SETP-03):** + - On setup detail page, verify sticky bar shows setup name, item count, total weight, total cost + - Remove an item -> totals update + - Add items back -> totals update + - Go back to setups list -> verify card shows correct totals + + **6. Cross-feature consistency:** + - Edit a collection item's weight from /collection -> check setup totals update + - Delete a collection item -> verify it disappears from the setup too + - Create a thread, resolve it -> verify dashboard Planning card count updates + + Human confirms all checks pass + All four requirements (SETP-01, SETP-02, SETP-03, DASH-01) confirmed working in browser + Type "approved" or describe any issues found + + + + + +Human visual verification of all Phase 3 requirements. + + + +- All four requirements (SETP-01, SETP-02, SETP-03, DASH-01) confirmed working +- Navigation restructure works without broken links +- Visual consistency with existing collection and thread UI + + + +After completion, create `.planning/phases/03-setups-and-dashboard/03-03-SUMMARY.md` +