---
phase: 01-foundation-and-collection
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - package.json
  - tsconfig.json
  - vite.config.ts
  - drizzle.config.ts
  - index.html
  - biome.json
  - .gitignore
  - src/db/schema.ts
  - src/db/index.ts
  - src/db/seed.ts
  - src/shared/schemas.ts
  - src/shared/types.ts
  - src/server/index.ts
  - src/client/main.tsx
  - src/client/routes/__root.tsx
  - src/client/routes/index.tsx
  - src/client/app.css
  - tests/helpers/db.ts
autonomous: true
requirements:
  - COLL-01
  - COLL-03

must_haves:
  truths:
    - "Project installs, builds, and runs with bun run dev (both Vite and Hono servers start)"
    - "Database schema exists with items and categories tables and proper foreign keys"
    - "Shared Zod schemas validate item and category data consistently"
    - "Default Uncategorized category is seeded on first run"
    - "Test infrastructure runs with in-memory SQLite"
  artifacts:
    - path: "src/db/schema.ts"
      provides: "Drizzle table definitions for items, categories, settings"
      contains: "sqliteTable"
    - path: "src/db/index.ts"
      provides: "Database connection singleton with WAL mode and foreign keys"
      contains: "PRAGMA foreign_keys = ON"
    - path: "src/db/seed.ts"
      provides: "Seeds Uncategorized default category"
      contains: "Uncategorized"
    - path: "src/shared/schemas.ts"
      provides: "Zod validation schemas for items and categories"
      exports: ["createItemSchema", "updateItemSchema", "createCategorySchema", "updateCategorySchema"]
    - path: "src/shared/types.ts"
      provides: "TypeScript types inferred from Zod schemas and Drizzle"
    - path: "vite.config.ts"
      provides: "Vite config with TanStack Router plugin, React, Tailwind, proxy to Hono"
    - path: "tests/helpers/db.ts"
      provides: "In-memory SQLite test helper"
  key_links:
    - from: "src/db/schema.ts"
      to: "src/shared/schemas.ts"
      via: "Shared field constraints (name required, price as int cents)"
      pattern: "priceCents|weightGrams|categoryId"
    - from: "vite.config.ts"
      to: "src/server/index.ts"
      via: "Proxy /api to Hono backend"
      pattern: "proxy.*api.*localhost:3000"
---

<objective>
Scaffold the GearBox project from scratch: install all dependencies, configure Vite + Hono + Tailwind + TanStack Router + Drizzle, create the database schema, shared validation schemas, and test infrastructure.

Purpose: Establish the complete foundation that all subsequent plans build on. Nothing can be built without the project scaffold, DB schema, and shared types.
Output: A running dev environment with two servers (Vite frontend on 5173, Hono backend on 3000), database with migrations applied, and a test harness ready for service tests.
</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/01-foundation-and-collection/01-RESEARCH.md
@.planning/phases/01-foundation-and-collection/01-VALIDATION.md
</context>

<tasks>

<task type="auto">
  <name>Task 1: Project scaffolding and configuration</name>
  <files>package.json, tsconfig.json, vite.config.ts, drizzle.config.ts, index.html, biome.json, .gitignore, src/client/main.tsx, src/client/routes/__root.tsx, src/client/routes/index.tsx, src/client/app.css, src/server/index.ts</files>
  <action>
    Initialize the project from scratch:

    1. Run `bun init` in the project root (accept defaults).
    2. Install all dependencies per RESEARCH.md installation commands:
       - Core frontend: `bun add react react-dom @tanstack/react-router @tanstack/react-query zustand zod clsx`
       - Core backend: `bun add hono @hono/zod-validator drizzle-orm`
       - Styling: `bun add tailwindcss @tailwindcss/vite`
       - Build tooling: `bun add -d vite @vitejs/plugin-react @tanstack/router-plugin typescript @types/react @types/react-dom`
       - DB tooling: `bun add -d drizzle-kit`
       - Linting: `bun add -d @biomejs/biome`
       - Dev tools: `bun add -d @tanstack/react-query-devtools @tanstack/react-router-devtools`
    3. Initialize Biome: `bunx @biomejs/biome init`

    4. Create `tsconfig.json` with target ESNext, module ESNext, moduleResolution bundler, jsx react-jsx, strict true, paths "@/*" mapping to "./src/*", types ["bun-types"].

    5. Create `vite.config.ts` following RESEARCH.md Pattern 1 exactly. Plugins in order: tanstackRouter (target react, autoCodeSplitting true), react(), tailwindcss(). Proxy /api and /uploads to http://localhost:3000. Build output to dist/client.

    6. Create `drizzle.config.ts` per RESEARCH.md example (dialect sqlite, schema ./src/db/schema.ts, out ./drizzle, url gearbox.db).

    7. Create `index.html` as Vite SPA entry point with div#root and script src /src/client/main.tsx.

    8. Create `src/client/app.css` with Tailwind v4 import: @import "tailwindcss";

    9. Create `src/client/main.tsx` with React 19 createRoot, TanStack Router provider, and TanStack Query provider.

    10. Create `src/client/routes/__root.tsx` as root layout with Outlet. Import app.css here.

    11. Create `src/client/routes/index.tsx` as default route with placeholder text "GearBox Collection".

    12. Create `src/server/index.ts` following RESEARCH.md Pattern 1: Hono app, health check at /api/health, static file serving for /uploads/*, production static serving for Vite build, export default { port: 3000, fetch: app.fetch }.

    13. Add scripts to package.json: "dev:client": "vite", "dev:server": "bun --hot src/server/index.ts", "build": "vite build", "db:generate": "bunx drizzle-kit generate", "db:push": "bunx drizzle-kit push", "test": "bun test", "lint": "bunx @biomejs/biome check ."

    14. Create `uploads/` directory with a .gitkeep file. Update .gitignore with: gearbox.db, gearbox.db-*, dist/, node_modules/, .tanstack/, uploads/* (but not .gitkeep).
  </action>
  <verify>
    <automated>bun install && bun run build 2>&1 | tail -5</automated>
  </verify>
  <done>All dependencies installed. bun run build succeeds (Vite compiles frontend). Config files exist and are valid. TanStack Router generates route tree file.</done>
</task>

<task type="auto">
  <name>Task 2: Database schema, shared schemas, seed, and test infrastructure</name>
  <files>src/db/schema.ts, src/db/index.ts, src/db/seed.ts, src/shared/schemas.ts, src/shared/types.ts, tests/helpers/db.ts</files>
  <action>
    1. Create `src/db/schema.ts` following RESEARCH.md Pattern 2 exactly:
       - categories table: id (integer PK autoIncrement), name (text notNull unique), emoji (text notNull default box emoji), createdAt (integer timestamp)
       - items table: id (integer PK autoIncrement), name (text notNull), weightGrams (real nullable), priceCents (integer nullable), categoryId (integer notNull references categories.id), notes (text nullable), productUrl (text nullable), imageFilename (text nullable), createdAt (integer timestamp), updatedAt (integer timestamp)
       - settings table: key (text PK), value (text notNull) for onboarding flag
       - Export all tables

    2. Create `src/db/index.ts` per RESEARCH.md Database Connection Singleton: bun:sqlite Database, PRAGMA journal_mode WAL, PRAGMA foreign_keys ON, export drizzle instance with schema.

    3. Create `src/db/seed.ts`: seedDefaults() inserts Uncategorized category with box emoji if no categories exist. Export the function.

    4. Create `src/shared/schemas.ts` per RESEARCH.md Shared Zod Schemas: createItemSchema (name required, weightGrams optional nonneg, priceCents optional int nonneg, categoryId required int positive, notes optional, productUrl optional url-or-empty), updateItemSchema (partial + id), createCategorySchema (name required, emoji with default), updateCategorySchema (id required, name optional, emoji optional). Export all.

    5. Create `src/shared/types.ts`: Infer TS types from Zod schemas (CreateItem, UpdateItem, CreateCategory, UpdateCategory) and from Drizzle schema (Item, Category using $inferSelect). Export all.

    6. Create `tests/helpers/db.ts`: createTestDb() function that creates in-memory SQLite, enables foreign keys, applies schema via raw SQL CREATE TABLE statements matching the Drizzle schema, seeds Uncategorized category, returns drizzle instance. This avoids needing migration files for tests.

    7. Run `bunx drizzle-kit push` to apply schema to gearbox.db.

    8. Wire seed into src/server/index.ts: import and call seedDefaults() at server startup.
  </action>
  <verify>
    <automated>bunx drizzle-kit push --force 2>&1 | tail -3 && bun -e "import { db } from './src/db/index.ts'; import { categories } from './src/db/schema.ts'; import './src/db/seed.ts'; const cats = db.select().from(categories).all(); if (cats.length === 0 || cats[0].name !== 'Uncategorized') { throw new Error('Seed failed'); } console.log('OK: seed works, found', cats.length, 'categories');"</automated>
  </verify>
  <done>Database schema applied with items, categories, and settings tables. Shared Zod schemas export and validate correctly. Uncategorized category seeded. Test helper creates in-memory DB instances. All types exported from shared/types.ts.</done>
</task>

</tasks>

<verification>
- `bun run build` completes without errors
- `bunx drizzle-kit push` applies schema successfully
- Seed script creates Uncategorized category
- `bun -e "import './src/shared/schemas.ts'"` imports without error
- `bun -e "import { createTestDb } from './tests/helpers/db.ts'; const db = createTestDb(); console.log('test db ok');"` succeeds
</verification>

<success_criteria>
- All project dependencies installed and lock file committed
- Vite builds the frontend successfully
- Hono server starts and responds to /api/health
- SQLite database has items, categories, and settings tables with correct schema
- Shared Zod schemas validate item and category data
- Test helper creates isolated in-memory databases
- Uncategorized default category is seeded on server start
</success_criteria>

<output>
After completion, create `.planning/phases/01-foundation-and-collection/01-01-SUMMARY.md`
</output>
