7.8 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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 18-global-items-public-profiles | 01 | execute | 1 |
|
true |
|
|
Purpose: Every subsequent plan depends on these schema definitions. Defining contracts first prevents the scavenger hunt anti-pattern. Output: Updated schema.ts, schemas.ts, types.ts, and global-items-seed.json
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/18-global-items-public-profiles/18-CONTEXT.md @.planning/phases/18-global-items-public-profiles/18-RESEARCH.md@src/db/schema.ts @src/shared/schemas.ts @src/shared/types.ts
Task 1: Schema tables and column additions src/db/schema.ts src/db/schema.ts Add `boolean` to the drizzle-orm/pg-core imports (per D-01, D-12).Add the globalItems table per D-01:
id: serial("id").primaryKey()brand: text("brand").notNull()model: text("model").notNull()category: text("category")weightGrams: doublePrecision("weight_grams")priceCents: integer("price_cents")imageUrl: text("image_url")description: text("description")createdAt: timestamp("created_at").defaultNow().notNull()
Add the itemGlobalLinks junction table per D-02:
id: serial("id").primaryKey()itemId: integer("item_id").notNull().references(() => items.id, { onDelete: "cascade" }).unique()— each user item links to at most one global itemglobalItemId: integer("global_item_id").notNull().references(() => globalItems.id, { onDelete: "cascade" })
Extend the users table per D-08 — add three nullable text columns:
displayName: text("display_name")avatarUrl: text("avatar_url")bio: text("bio")
Extend the setups table per D-12 — add:
isPublic: boolean("is_public").notNull().default(false)
Place new tables after setupItems section. Export all new tables.
After schema changes, run bun run db:generate to create the migration, then bun run db:push to verify it applies cleanly.
bun run db:generate 2>&1 | tail -5
<acceptance_criteria>
- grep -q "globalItems" src/db/schema.ts
- grep -q "itemGlobalLinks" src/db/schema.ts
- grep -q "displayName" src/db/schema.ts
- grep -q "isPublic" src/db/schema.ts
- grep -q "boolean" src/db/schema.ts
</acceptance_criteria>
All four schema additions (globalItems table, itemGlobalLinks table, users profile columns, setups isPublic) are defined and exported. Migration generated successfully.
-
searchGlobalItemsSchemaper D-04 and D-16:z.object({ q: z.string().optional() }) -
linkItemSchemaper D-18:z.object({ globalItemId: z.number().int().positive() }) -
updateProfileSchemaper D-08, D-21:z.object({ displayName: z.string().max(100).optional(), avatarUrl: z.string().optional(), bio: z.string().max(500).optional(), }) -
Update the existing
updateSetupSchemato includeisPublicper D-12, D-14: AddisPublic: z.boolean().optional()to the existing schema object. -
Update the existing
createSetupSchemaif it exists — addisPublic: z.boolean().optional().default(false).
types.ts — Add type exports:
export type GlobalItem = typeof globalItems.$inferSelect;(import globalItems, itemGlobalLinks from schema)export type ItemGlobalLink = typeof itemGlobalLinks.$inferSelect;export type SearchGlobalItems = z.infer<typeof searchGlobalItemsSchema>;export type LinkItem = z.infer<typeof linkItemSchema>;export type UpdateProfile = z.infer<typeof updateProfileSchema>;
global-items-seed.json — Create per D-06, D-07. Array of 15-20 bikepacking gear items covering categories like bags (frame bags, handlebar bags, saddle bags), shelters (tents, bivvies, tarps), sleep systems (sleeping bags, pads), cooking, hydration, and lighting. Each object has: brand, model, category, weightGrams, priceCents, description. Use real product names and approximate specs (e.g., Revelate Designs Terrapin, Apidura Expedition Handlebar Pack, Sea to Summit Spark SP1, MSR PocketRocket 2, Nemo Tensor Ultralight). Do NOT include id or createdAt.
bun run lint 2>&1 | tail -5
<acceptance_criteria>
- grep -q "searchGlobalItemsSchema" src/shared/schemas.ts
- grep -q "linkItemSchema" src/shared/schemas.ts
- grep -q "updateProfileSchema" src/shared/schemas.ts
- grep -q "GlobalItem" src/shared/types.ts
- grep -q "UpdateProfile" src/shared/types.ts
- test -f src/db/global-items-seed.json
</acceptance_criteria>
Zod schemas cover global item search, item linking, profile update, and setup visibility. Types inferred from schemas and Drizzle tables. Seed file has 15-20 bikepacking items with real product names.
<success_criteria> Schema.ts has globalItems, itemGlobalLinks, user profile columns, and setup isPublic. Schemas.ts has all new Zod validators. Types.ts exports all new types. Seed JSON file exists with 15-20 items. Lint passes. </success_criteria>
After completion, create `.planning/phases/18-global-items-public-profiles/18-01-SUMMARY.md`