Files
GearBox/.planning/phases/03-setups-and-dashboard/03-01-PLAN.md

177 lines
6.9 KiB
Markdown

---
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"
---
<objective>
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.
</objective>
<execution_context>
@/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md
@/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.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
<interfaces>
<!-- Existing patterns to follow exactly -->
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
```
</interfaces>
</context>
<feature>
<name>Setup Backend with Junction Table</name>
<files>
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
</files>
<behavior>
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)
</behavior>
<implementation>
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)
</implementation>
</feature>
<verification>
```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.
</verification>
<success_criteria>
- 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
</success_criteria>
<output>
After completion, create `.planning/phases/03-setups-and-dashboard/03-01-SUMMARY.md`
</output>