Files
GearBox/.planning/phases/04-database-planning-fixes/04-01-PLAN.md

7.7 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
04-database-planning-fixes 01 execute 1
src/db/schema.ts
src/shared/schemas.ts
src/shared/types.ts
src/server/services/thread.service.ts
src/server/routes/threads.ts
src/client/hooks/useThreads.ts
tests/helpers/db.ts
true
DB-01
PLAN-01
truths artifacts key_links
Database schema push creates threads and thread_candidates tables without errors
Threads table includes category_id column with foreign key to categories
Creating a thread with name and categoryId succeeds via API
getAllThreads returns categoryName and categoryEmoji for each thread
path provides contains
src/db/schema.ts threads table with categoryId column categoryId.*references.*categories
path provides contains
src/shared/schemas.ts createThreadSchema with categoryId field categoryId.*z.number
path provides exports
src/server/services/thread.service.ts Thread CRUD with category join
createThread
getAllThreads
path provides contains
tests/helpers/db.ts Test DB with category_id on threads category_id.*REFERENCES categories
from to via pattern
src/server/routes/threads.ts src/server/services/thread.service.ts createThread(db, data) with categoryId createThread.*data
from to via pattern
src/server/services/thread.service.ts src/db/schema.ts Drizzle insert/select on threads with categoryId threads.*categoryId
Fix the missing threads table in the database and add categoryId to threads so thread creation works end-to-end.

Purpose: DB-01 (threads table exists) and the backend half of PLAN-01 (thread creation works with category). Without this, the planning tab crashes on any thread operation. Output: Working database schema, updated API that accepts categoryId on thread creation, and thread list returns category info.

<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>

@.planning/ROADMAP.md @.planning/phases/04-database-planning-fixes/04-CONTEXT.md

From src/db/schema.ts (threads table -- needs categoryId added):

export const threads = sqliteTable("threads", {
  id: integer("id").primaryKey({ autoIncrement: true }),
  name: text("name").notNull(),
  status: text("status").notNull().default("active"),
  resolvedCandidateId: integer("resolved_candidate_id"),
  // MISSING: categoryId column
  createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
  updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().$defaultFn(() => new Date()),
});

From src/shared/schemas.ts (createThreadSchema -- needs categoryId):

export const createThreadSchema = z.object({
  name: z.string().min(1, "Thread name is required"),
  // MISSING: categoryId
});

From src/client/hooks/useThreads.ts (ThreadListItem -- needs category fields):

interface ThreadListItem {
  id: number;
  name: string;
  status: "active" | "resolved";
  resolvedCandidateId: number | null;
  createdAt: string;
  updatedAt: string;
  candidateCount: number;
  minPriceCents: number | null;
  maxPriceCents: number | null;
  // MISSING: categoryId, categoryName, categoryEmoji
}
Task 1: Add categoryId to threads schema, Zod schemas, types, and test helper src/db/schema.ts, src/shared/schemas.ts, src/shared/types.ts, tests/helpers/db.ts 1. In `src/db/schema.ts`, add `categoryId` column to the `threads` table: ``` categoryId: integer("category_id").notNull().references(() => categories.id), ``` Place it after the `resolvedCandidateId` field.
  1. In src/shared/schemas.ts, update createThreadSchema to require categoryId:

    export const createThreadSchema = z.object({
      name: z.string().min(1, "Thread name is required"),
      categoryId: z.number().int().positive(),
    });
    

    Also update updateThreadSchema to allow optional categoryId:

    export const updateThreadSchema = z.object({
      name: z.string().min(1).optional(),
      categoryId: z.number().int().positive().optional(),
    });
    
  2. In tests/helpers/db.ts, update the threads CREATE TABLE to include category_id:

    CREATE TABLE threads (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      status TEXT NOT NULL DEFAULT 'active',
      resolved_candidate_id INTEGER,
      category_id INTEGER NOT NULL REFERENCES categories(id),
      created_at INTEGER NOT NULL DEFAULT (unixepoch()),
      updated_at INTEGER NOT NULL DEFAULT (unixepoch())
    )
    
  3. Run bun run db:generate to generate the migration for adding category_id to threads.

  4. Run bun run db:push to apply the migration. cd /home/jean-luc-makiola/Development/projects/GearBox && bun run db:push 2>&1 | tail -5 threads table in schema.ts has categoryId with FK to categories, createThreadSchema requires categoryId, test helper CREATE TABLE matches, db:push succeeds

Task 2: Update thread service and routes to handle categoryId, update hook types src/server/services/thread.service.ts, src/server/routes/threads.ts, src/client/hooks/useThreads.ts 1. In `src/server/services/thread.service.ts`: - Update `createThread` to insert `categoryId` from data: `.values({ name: data.name, categoryId: data.categoryId })` - Update `getAllThreads` to join with categories table and return `categoryId`, `categoryName`, `categoryEmoji` in the select: ``` categoryId: threads.categoryId, categoryName: categories.name, categoryEmoji: categories.emoji, ``` Add `.innerJoin(categories, eq(threads.categoryId, categories.id))` to the query. - Update `updateThread` data type to include optional `categoryId: number`.
  1. In src/server/routes/threads.ts:

    • The route handlers already pass data through from Zod validation, so createThread and updateThread should work with the updated schemas. Verify the PUT handler passes categoryId if present.
  2. In src/client/hooks/useThreads.ts:

    • Add categoryId: number, categoryName: string, categoryEmoji: string to the ThreadListItem interface.
    • Update useCreateThread mutationFn type to { name: string; categoryId: number }.
  3. Run existing tests to confirm nothing breaks. cd /home/jean-luc-makiola/Development/projects/GearBox && bun test 2>&1 | tail -20 Thread creation accepts categoryId, getAllThreads returns category name and emoji for each thread, existing tests pass, useCreateThread hook sends categoryId

- `bun run db:push` completes without errors - `bun test` passes all existing tests - Start dev server (`bun run dev:server`) and confirm `curl http://localhost:3000/api/threads` returns 200 (empty array is fine)

<success_criteria>

  • threads table exists in database with category_id column
  • POST /api/threads requires { name, categoryId } and creates a thread
  • GET /api/threads returns threads with categoryName and categoryEmoji
  • All existing tests pass </success_criteria>
After completion, create `.planning/phases/04-database-planning-fixes/04-01-SUMMARY.md`