fix(22): revise plans based on checker feedback
This commit is contained in:
@@ -25,7 +25,7 @@ must_haves:
|
|||||||
provides: "Add-to-collection confirmation modal"
|
provides: "Add-to-collection confirmation modal"
|
||||||
min_lines: 80
|
min_lines: 80
|
||||||
- path: "src/client/stores/uiStore.ts"
|
- path: "src/client/stores/uiStore.ts"
|
||||||
provides: "Modal state slices for addToCollectionModal and catalogSessionThreadId"
|
provides: "Modal state slices for addToCollectionModal, addToThreadModal, and catalogSessionThreadId"
|
||||||
contains: "addToCollectionModal"
|
contains: "addToCollectionModal"
|
||||||
- path: "src/client/routes/__root.tsx"
|
- path: "src/client/routes/__root.tsx"
|
||||||
provides: "Toaster and AddToCollectionModal rendered at root"
|
provides: "Toaster and AddToCollectionModal rendered at root"
|
||||||
@@ -43,6 +43,10 @@ must_haves:
|
|||||||
to: "src/client/stores/uiStore.ts"
|
to: "src/client/stores/uiStore.ts"
|
||||||
via: "openAddToCollection on button click"
|
via: "openAddToCollection on button click"
|
||||||
pattern: "openAddToCollection"
|
pattern: "openAddToCollection"
|
||||||
|
- from: "src/client/stores/uiStore.ts"
|
||||||
|
to: "src/client/components/AddToThreadModal.tsx (Plan 02)"
|
||||||
|
via: "addToThreadModal state slice and catalogSessionThreadId consumed by Plan 02"
|
||||||
|
pattern: "addToThreadModal|catalogSessionThreadId"
|
||||||
---
|
---
|
||||||
|
|
||||||
<objective>
|
<objective>
|
||||||
@@ -241,7 +245,7 @@ In the RootLayout JSX, after the `<CatalogSearchOverlay />` line (around line 20
|
|||||||
```
|
```
|
||||||
</action>
|
</action>
|
||||||
<verify>
|
<verify>
|
||||||
<automated>cd /home/jean-luc-makiola/Development/projects/GearBox && bun run build 2>&1 | tail -5</automated>
|
<automated>cd /home/jean-luc-makiola/Development/projects/GearBox && bun run build 2>&1 | tail -5 && bun test tests/services/item.service.test.ts tests/services/thread.service.test.ts 2>&1 | tail -10</automated>
|
||||||
</verify>
|
</verify>
|
||||||
<acceptance_criteria>
|
<acceptance_criteria>
|
||||||
- `src/client/stores/uiStore.ts` contains `addToCollectionModal: { open: boolean; globalItemId: number | null; globalItemName: string | null }`
|
- `src/client/stores/uiStore.ts` contains `addToCollectionModal: { open: boolean; globalItemId: number | null; globalItemName: string | null }`
|
||||||
@@ -260,8 +264,9 @@ In the RootLayout JSX, after the `<CatalogSearchOverlay />` line (around line 20
|
|||||||
- `src/client/routes/__root.tsx` contains `<AddToCollectionModal />`
|
- `src/client/routes/__root.tsx` contains `<AddToCollectionModal />`
|
||||||
- `src/client/routes/__root.tsx` contains `<Toaster`
|
- `src/client/routes/__root.tsx` contains `<Toaster`
|
||||||
- `bun run build` exits with code 0
|
- `bun run build` exits with code 0
|
||||||
|
- `bun test tests/services/item.service.test.ts tests/services/thread.service.test.ts` passes (no regressions)
|
||||||
</acceptance_criteria>
|
</acceptance_criteria>
|
||||||
<done>UIStore has all Phase 22 modal states (addToCollectionModal, addToThreadModal, catalogSessionThreadId). AddToCollectionModal renders with category dropdown, notes, purchase price. Sonner Toaster is in root layout. Build passes.</done>
|
<done>UIStore has all Phase 22 modal states (addToCollectionModal, addToThreadModal, catalogSessionThreadId). AddToCollectionModal renders with category dropdown, notes, purchase price. Sonner Toaster is in root layout. Build passes. Service tests pass.</done>
|
||||||
</task>
|
</task>
|
||||||
|
|
||||||
<task type="auto">
|
<task type="auto">
|
||||||
@@ -343,7 +348,7 @@ Replace the existing "Add to Collection" button (line 131-135) that has `console
|
|||||||
Per D-14 and D-15: both buttons on the detail page. "Add to Collection" is primary (filled), "Add to Thread" is secondary (outlined).
|
Per D-14 and D-15: both buttons on the detail page. "Add to Collection" is primary (filled), "Add to Thread" is secondary (outlined).
|
||||||
</action>
|
</action>
|
||||||
<verify>
|
<verify>
|
||||||
<automated>cd /home/jean-luc-makiola/Development/projects/GearBox && bun run build 2>&1 | tail -5</automated>
|
<automated>cd /home/jean-luc-makiola/Development/projects/GearBox && bun run build 2>&1 | tail -5 && bun test tests/services/item.service.test.ts tests/services/thread.service.test.ts 2>&1 | tail -10</automated>
|
||||||
</verify>
|
</verify>
|
||||||
<acceptance_criteria>
|
<acceptance_criteria>
|
||||||
- `src/client/components/CatalogSearchOverlay.tsx` does NOT contain `handleAddStub`
|
- `src/client/components/CatalogSearchOverlay.tsx` does NOT contain `handleAddStub`
|
||||||
@@ -357,18 +362,20 @@ Per D-14 and D-15: both buttons on the detail page. "Add to Collection" is prima
|
|||||||
- `$globalItemId.tsx` contains `Add to Thread`
|
- `$globalItemId.tsx` contains `Add to Thread`
|
||||||
- `$globalItemId.tsx` imports `useUIStore`
|
- `$globalItemId.tsx` imports `useUIStore`
|
||||||
- `bun run build` exits with code 0
|
- `bun run build` exits with code 0
|
||||||
|
- `bun test tests/services/item.service.test.ts tests/services/thread.service.test.ts` passes
|
||||||
</acceptance_criteria>
|
</acceptance_criteria>
|
||||||
<done>CatalogSearchOverlay dispatches to correct modal based on catalogSearchMode. Global item detail page has both "Add to Collection" and "Add to Thread" buttons wired to UIStore. handleAddStub is fully replaced. No console.log stubs remain.</done>
|
<done>CatalogSearchOverlay dispatches to correct modal based on catalogSearchMode. Global item detail page has both "Add to Collection" and "Add to Thread" buttons wired to UIStore. handleAddStub is fully replaced. No console.log stubs remain. Service tests pass.</done>
|
||||||
</task>
|
</task>
|
||||||
|
|
||||||
</tasks>
|
</tasks>
|
||||||
|
|
||||||
<verification>
|
<verification>
|
||||||
1. `bun run build` passes with no type errors
|
1. `bun run build` passes with no type errors
|
||||||
2. In collection mode, clicking Add on catalog card opens AddToCollectionModal
|
2. `bun test tests/services/item.service.test.ts tests/services/thread.service.test.ts` passes
|
||||||
3. Submitting modal with category creates a reference item (POST /api/items with globalItemId)
|
3. In collection mode, clicking Add on catalog card opens AddToCollectionModal
|
||||||
4. Toast "Added to Collection" appears after successful add
|
4. Submitting modal with category creates a reference item (POST /api/items with globalItemId)
|
||||||
5. Global item detail page shows both "Add to Collection" and "Add to Thread" buttons
|
5. Toast "Added to Collection" appears after successful add
|
||||||
|
6. Global item detail page shows both "Add to Collection" and "Add to Thread" buttons
|
||||||
</verification>
|
</verification>
|
||||||
|
|
||||||
<success_criteria>
|
<success_criteria>
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ must_haves:
|
|||||||
- "User can choose New Thread which shows thread name + category fields and creates thread + candidate in one step"
|
- "User can choose New Thread which shows thread name + category fields and creates thread + candidate in one step"
|
||||||
- "After creating a new thread, subsequent adds in same session default to that thread"
|
- "After creating a new thread, subsequent adds in same session default to that thread"
|
||||||
- "Clicking Add to Thread on the global item detail page opens the same thread picker modal"
|
- "Clicking Add to Thread on the global item detail page opens the same thread picker modal"
|
||||||
- "Resolving a thread with a catalog-linked candidate creates a reference item (already works)"
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: "src/client/components/AddToThreadModal.tsx"
|
- path: "src/client/components/AddToThreadModal.tsx"
|
||||||
provides: "Thread picker modal with new thread creation flow"
|
provides: "Thread picker modal with new thread creation flow"
|
||||||
@@ -41,9 +40,9 @@ must_haves:
|
|||||||
---
|
---
|
||||||
|
|
||||||
<objective>
|
<objective>
|
||||||
Build the AddToThreadModal: thread picker with existing active threads, "New Thread..." option for combined thread+candidate creation, and session thread memory. Wire to root layout. Verify CATFLOW-06 (thread resolution with catalog-linked candidates).
|
Build the AddToThreadModal: thread picker with existing active threads, "New Thread..." option for combined thread+candidate creation, and session thread memory. Wire to root layout. Verify CATFLOW-06 regression (thread resolution with catalog-linked candidates) via existing service tests.
|
||||||
|
|
||||||
Purpose: CATFLOW-05 -- users can add catalog items as thread candidates from search. CATFLOW-06 -- resolution already works, verify it.
|
Purpose: CATFLOW-05 -- users can add catalog items as thread candidates from search. CATFLOW-06 -- resolution already works, confirmed by existing tests.
|
||||||
Output: Working add-to-thread flow, complete Phase 22 catalog integration.
|
Output: Working add-to-thread flow, complete Phase 22 catalog integration.
|
||||||
</objective>
|
</objective>
|
||||||
|
|
||||||
@@ -115,8 +114,9 @@ export async function apiPost<T>(url: string, body: unknown): Promise<T>
|
|||||||
|
|
||||||
From src/client/hooks/useGlobalItems.ts:
|
From src/client/hooks/useGlobalItems.ts:
|
||||||
```typescript
|
```typescript
|
||||||
export function useGlobalItem(id: number)
|
export function useGlobalItem(id: number | null)
|
||||||
// Returns globalItem with: id, brand, model, category, weightGrams, priceCents, imageUrl, description, ownerCount
|
// Returns globalItem with: id, brand, model, category, weightGrams, priceCents, imageUrl, description, ownerCount
|
||||||
|
// NOTE: Already has `enabled: id != null` guard built in -- safe to call with null globalItemId
|
||||||
```
|
```
|
||||||
</interfaces>
|
</interfaces>
|
||||||
</context>
|
</context>
|
||||||
@@ -162,7 +162,7 @@ import { useQueryClient } from "@tanstack/react-query";
|
|||||||
**State management:**
|
**State management:**
|
||||||
- Read from UIStore: `addToThreadModal` (open, globalItemId, globalItemName), `closeAddToThread`, `catalogSessionThreadId`, `setCatalogSessionThreadId`
|
- Read from UIStore: `addToThreadModal` (open, globalItemId, globalItemName), `closeAddToThread`, `catalogSessionThreadId`, `setCatalogSessionThreadId`
|
||||||
- Local state: `mode` ("pick" | "create"), `selectedThreadId` (number | null), `newThreadName` (string), `newThreadCategoryId` (number | null), `isSubmitting` (boolean), `error` (string | null)
|
- Local state: `mode` ("pick" | "create"), `selectedThreadId` (number | null), `newThreadName` (string), `newThreadCategoryId` (number | null), `isSubmitting` (boolean), `error` (string | null)
|
||||||
- Fetch: `useThreads()` for thread list, `useCategories()` for new thread category dropdown, `useGlobalItem(globalItemId)` for the global item data needed to create the candidate
|
- Fetch: `useThreads()` for thread list, `useCategories()` for new thread category dropdown, `useGlobalItem(globalItemId)` for the global item data needed to create the candidate. NOTE: `useGlobalItem` already has `enabled: id != null` guard built in, so passing `globalItemId` (which may be null when modal is closed) is safe -- no additional enabled guard needed.
|
||||||
- `useCreateThread()` for thread creation, `useQueryClient()` for manual invalidation
|
- `useCreateThread()` for thread creation, `useQueryClient()` for manual invalidation
|
||||||
|
|
||||||
**Initialization logic (per D-12, D-19):**
|
**Initialization logic (per D-12, D-19):**
|
||||||
@@ -263,7 +263,7 @@ import { AddToThreadModal } from "../components/AddToThreadModal";
|
|||||||
Add `<AddToThreadModal />` right after `<AddToCollectionModal />` in the JSX.
|
Add `<AddToThreadModal />` right after `<AddToCollectionModal />` in the JSX.
|
||||||
</action>
|
</action>
|
||||||
<verify>
|
<verify>
|
||||||
<automated>cd /home/jean-luc-makiola/Development/projects/GearBox && bun run build 2>&1 | tail -5</automated>
|
<automated>cd /home/jean-luc-makiola/Development/projects/GearBox && bun run build 2>&1 | tail -5 && bun test tests/services/thread.service.test.ts 2>&1 | tail -10</automated>
|
||||||
</verify>
|
</verify>
|
||||||
<acceptance_criteria>
|
<acceptance_criteria>
|
||||||
- `src/client/components/AddToThreadModal.tsx` exists with `export function AddToThreadModal`
|
- `src/client/components/AddToThreadModal.tsx` exists with `export function AddToThreadModal`
|
||||||
@@ -280,8 +280,9 @@ Add `<AddToThreadModal />` right after `<AddToCollectionModal />` in the JSX.
|
|||||||
- `src/client/routes/__root.tsx` contains `import { AddToThreadModal }`
|
- `src/client/routes/__root.tsx` contains `import { AddToThreadModal }`
|
||||||
- `src/client/routes/__root.tsx` contains `<AddToThreadModal />`
|
- `src/client/routes/__root.tsx` contains `<AddToThreadModal />`
|
||||||
- `bun run build` exits with code 0
|
- `bun run build` exits with code 0
|
||||||
|
- `bun test tests/services/thread.service.test.ts` passes -- confirms CATFLOW-06 regression coverage (resolveThread with globalItemId candidate creates reference item, test at line 704)
|
||||||
</acceptance_criteria>
|
</acceptance_criteria>
|
||||||
<done>AddToThreadModal supports picking an existing active thread and creating a new thread with first candidate. Session thread tracking persists across adds. Both catalog search overlay and global item detail page wire to this modal via UIStore. Build passes.</done>
|
<done>AddToThreadModal supports picking an existing active thread and creating a new thread with first candidate. Session thread tracking persists across adds. Build passes. Thread service tests pass confirming CATFLOW-06 (resolveThread with catalog-linked candidate) is covered.</done>
|
||||||
</task>
|
</task>
|
||||||
|
|
||||||
<task type="checkpoint:human-verify" gate="blocking">
|
<task type="checkpoint:human-verify" gate="blocking">
|
||||||
@@ -330,7 +331,7 @@ Add `<AddToThreadModal />` right after `<AddToCollectionModal />` in the JSX.
|
|||||||
2. Click "Add to Thread"
|
2. Click "Add to Thread"
|
||||||
3. Verify: thread picker modal opens, same as Flow 3
|
3. Verify: thread picker modal opens, same as Flow 3
|
||||||
|
|
||||||
**Flow 6: Thread resolution (CATFLOW-06 -- existing behavior)**
|
**Flow 6: Thread resolution regression (CATFLOW-06)**
|
||||||
1. Go to a thread that has a catalog-linked candidate (from Flow 3/4)
|
1. Go to a thread that has a catalog-linked candidate (from Flow 3/4)
|
||||||
2. Resolve the thread by selecting that candidate
|
2. Resolve the thread by selecting that candidate
|
||||||
3. Verify: a new item appears in collection with the global item data
|
3. Verify: a new item appears in collection with the global item data
|
||||||
@@ -342,7 +343,7 @@ Add `<AddToThreadModal />` right after `<AddToCollectionModal />` in the JSX.
|
|||||||
|
|
||||||
<verification>
|
<verification>
|
||||||
1. `bun run build` passes with no type errors
|
1. `bun run build` passes with no type errors
|
||||||
2. `bun test` passes (no backend changes, existing tests should remain green)
|
2. `bun test tests/services/thread.service.test.ts` passes (CATFLOW-06 regression -- resolveThread with globalItemId)
|
||||||
3. Add-to-collection flow works from both entry points
|
3. Add-to-collection flow works from both entry points
|
||||||
4. Add-to-thread flow works with existing threads and new thread creation
|
4. Add-to-thread flow works with existing threads and new thread creation
|
||||||
5. Session thread memory works within a search session
|
5. Session thread memory works within a search session
|
||||||
@@ -351,7 +352,7 @@ Add `<AddToThreadModal />` right after `<AddToCollectionModal />` in the JSX.
|
|||||||
|
|
||||||
<success_criteria>
|
<success_criteria>
|
||||||
- CATFLOW-05 is functional: user can add catalog items as thread candidates from search
|
- CATFLOW-05 is functional: user can add catalog items as thread candidates from search
|
||||||
- CATFLOW-06 is verified: resolving a catalog-linked candidate creates a reference item
|
- CATFLOW-06 is verified: resolving a catalog-linked candidate creates a reference item (confirmed by `bun test tests/services/thread.service.test.ts` and manual Flow 6)
|
||||||
- AddToThreadModal supports existing thread selection AND new thread + candidate creation
|
- AddToThreadModal supports existing thread selection AND new thread + candidate creation
|
||||||
- Session thread tracking remembers selection within a catalog search session
|
- Session thread tracking remembers selection within a catalog search session
|
||||||
- All flows accessible from both catalog search overlay and global item detail page
|
- All flows accessible from both catalog search overlay and global item detail page
|
||||||
|
|||||||
Reference in New Issue
Block a user