docs(37): capture phase context

This commit is contained in:
2026-04-19 20:57:32 +02:00
parent 868aed4f10
commit 298da6da85
2 changed files with 191 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
# Phase 37: Admin — Global Item Management - Context
**Gathered:** 2026-04-19
**Status:** Ready for planning
<domain>
## Phase Boundary
Build the `/admin/items` list and `/admin/items/$id` edit page, wired into the Phase 36 admin shell. Admins can browse all global catalog items, open and edit any item's full field set, and delete items with an impact-aware confirmation. No new capabilities beyond browse/edit/delete.
</domain>
<decisions>
## Implementation Decisions
### List View
- **D-01:** Data table layout — dense rows with sortable columns. No card grid. No existing table component; implement with plain Tailwind-styled HTML table.
- **D-02:** Columns: Brand + Model | Category | Weight | Price | Tags (chip or count) | Owner Count | Actions.
- **D-03:** Server-side infinite scroll pagination — load next page as admin scrolls down. No explicit next/prev buttons. Consistent with IntersectionObserver scroll detection. 50 items per page is a sensible default.
### Edit Workflow
- **D-04:** Dedicated edit page at `/admin/items/$itemId` — full-page form, bookmarkable. Consistent with the item/catalog detail page pattern already in the app.
- **D-05:** Delete lives on the edit page only (not on the list). Admin must open an item to delete it.
### Brand / Manufacturer Field
- **D-06:** Dropdown of existing manufacturers (fetched from `/api/manufacturers`). Admin picks from the list — no free-text brand creation in this phase. Prevents accidental duplicate manufacturers.
### Delete Confirmation
- **D-07:** Impact-aware confirmation dialog: show item name + owner count before confirming. Example: "Delete Salsa Woodsmoke 700? 3 users have this in their collection. This cannot be undone." Owner count already available from `getGlobalItemWithOwnerCount`.
### Claude's Discretion
- Exact column sort order and default sort (brand asc is reasonable)
- Whether tags column shows chips or a count badge when many tags exist
- Form field layout on the edit page (single column vs. two-column grid for compact fields)
- How the infinite scroll trigger is implemented (IntersectionObserver sentinel div)
- Styling of the delete button (destructive red, positioned at bottom of edit form)
</decisions>
<canonical_refs>
## Canonical References
**Downstream agents MUST read these before planning or implementing.**
### Existing Service Layer
- `src/server/services/global-item.service.ts``searchGlobalItems`, `getGlobalItemWithOwnerCount`, `upsertGlobalItem`; DELETE function needs to be added here
- `src/server/routes/global-items.ts` — existing GET/POST endpoints (public); admin DELETE will go through `/api/admin/items` route
### Admin Infrastructure (Phase 36)
- `src/server/routes/admin.ts` — admin route stub; extend with item sub-routes here
- `src/server/middleware/auth.ts``requireAdmin` middleware already in place
- `src/client/routes/admin.tsx` — admin shell layout with `<Outlet />`; "Items" nav item needs to be enabled (remove `cursor-not-allowed`, add active link)
### Client Routes
- `src/client/routes/admin/index.tsx` — admin index placeholder; stays as-is
- TanStack Router file-based routing: create `admin/items.tsx` (list) and `admin/items/$itemId.tsx` (edit)
### Database Schema
- `src/db/schema.ts``globalItems`, `manufacturers`, `tags`, `globalItemTags` tables
### Existing Reusable Hooks / Patterns
- `src/client/hooks/` — React Query hooks pattern; add `useAdminGlobalItems` (infinite query) and `useAdminGlobalItem`
- `src/client/lib/api.ts``apiGet`, `apiDelete`, `apiPut` fetch wrappers
- `src/server/routes/manufacturers.ts` (or similar) — GET /api/manufacturers for the brand dropdown
### Requirements
- `.planning/REQUIREMENTS.md` — ADMN-02, ADMN-03, ADMN-04
</canonical_refs>
<code_context>
## Existing Code Insights
### Reusable Assets
- `getGlobalItemWithOwnerCount` service function: already returns `ownerCount` — reuse for delete confirmation and edit page header
- `upsertGlobalItem` service: handles create and update via `onConflictDoUpdate`; admin edit will call this directly (PUT /api/admin/items/:id)
- `ImageUpload` component (`src/client/components/`) — reuse for image field on edit page
- `useFormatters()` hook — reuse for weight/price display in the table
- LucideIcon `"package"` already in the admin sidebar "Items" entry — just enable it
### Established Patterns
- Infinite scroll: Phase 26 discovery feed used cursor pagination + React Query's `useInfiniteQuery` — same pattern here
- Edit forms: item/catalog detail pages use controlled form state with `apiPut`
- Destructive confirmation: confirm modals exist in the app (setup delete, etc.) — reuse the same modal pattern
- React Query invalidation: mutations call `queryClient.invalidateQueries` with relevant query keys
### Integration Points
- `src/client/routes/admin.tsx`: Change "Items" sidebar entry from `<div cursor-not-allowed>` to `<Link to="/admin/items">` with active styling
- `src/server/index.ts`: Register `adminItemRoutes` under `/api/admin/items`
- `src/server/routes/admin.ts`: Mount item sub-router
</code_context>
<specifics>
## Specific Ideas
- Table row click → navigate to `/admin/items/$itemId`
- Edit page has a back link "← Items" to return to the list
- Delete button at bottom of edit form, styled destructive red, triggers impact-aware modal
- Infinite scroll sentinel: a `<div ref={sentinelRef}>` at bottom of table; IntersectionObserver triggers next page fetch
</specifics>
<deferred>
## Deferred Ideas
- Manufacturer creation from within the admin panel — admin can only pick existing manufacturers in this phase; creating new ones is out of scope
- Bulk delete / bulk edit from the list — admin-only single-item workflow for now
- Column sorting — mentioned as a potential feature but not in ADMN-02/03/04 success criteria; Claude's discretion whether to include basic sort
</deferred>
---
*Phase: 37-admin-global-item-management*
*Context gathered: 2026-04-19*

View File

@@ -0,0 +1,75 @@
# Phase 37: Admin — Global Item Management - Discussion Log
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
**Date:** 2026-04-19
**Phase:** 37 — Admin — Global Item Management
**Areas discussed:** List view style, Edit workflow, Brand/manufacturer field, Delete confirmation
---
## List view style
| Option | Description | Selected |
|--------|-------------|----------|
| Data table | Dense rows with columns for brand, model, category, weight, price, tags, owner count. Sortable, scannable, admin-appropriate. | ✓ |
| Card grid | Consistent with public catalog. Reuses GearImage/card patterns but wastes space for data management. | |
| List rows (compact) | Single-line rows with brand/model + a few stats. Middle ground. | |
**User's choice:** Data table
**Table columns selected:** Brand + Model, Category + Weight + Price, Tags, Owner count
**Pagination:** Server-side infinite scroll — load next page on scroll, not explicit next/prev buttons
---
## Edit workflow
| Option | Description | Selected |
|--------|-------------|----------|
| Dedicated edit page /admin/items/$id | Full-page form, bookmarkable, consistent with detail page pattern. | ✓ |
| Slide-over drawer | Slides in over list, keeps list context. Requires new drawer component. | |
**User's choice:** Dedicated edit page
**Delete location:** Edit page only (not on list)
---
## Brand/manufacturer field
| Option | Description | Selected |
|--------|-------------|----------|
| Dropdown of existing manufacturers | Admin picks from list fetched from /api/manufacturers. Safe, no duplicates. | ✓ |
| Free-text with auto-match | Admin types brand; matched or created on save. Risks duplicates. | |
**User's choice:** Dropdown of existing manufacturers
---
## Delete confirmation
| Option | Description | Selected |
|--------|-------------|----------|
| Impact-aware | Show item name + owner count: "3 users have this in their collection. This cannot be undone." | ✓ |
| Simple confirmation | "Are you sure? This cannot be undone." No extra data. | |
**User's choice:** Impact-aware confirmation with owner count
---
## Claude's Discretion
- Column sort order and default sort
- Tags column display (chips vs count badge)
- Edit form field layout (single vs two-column)
- IntersectionObserver implementation for infinite scroll trigger
- Delete button styling and position on edit page
## Deferred Ideas
- Manufacturer creation from within admin panel (out of scope for this phase)
- Bulk delete / bulk edit from the list
- Column sorting (not in success criteria; Claude's discretion)