Recipes
Add Field to Entity
Step-by-step checklist for adding a new field
Add Field to Entity
TL;DR: 6 files to modify. Use this checklist.
Checklist
| # | File | Action |
|---|---|---|
| 1 | src/lib/db/schema/<entity>.ts | Add column to table |
| 2 | src/features/<entity>/validation.ts | Add to Zod schema |
| 3 | src/features/<entity>/queries.ts | Add to types and select |
| 4 | src/features/<entity>/actions.ts | Add to create/update |
| 5 | src/server/routers/<entity>.ts | Verify input schema |
| 6 | UI components | Add to forms |
After: npm run typecheck
Example: Add "priority" to Projects
Step 1: Database Schema
// src/lib/db/schema/projects.ts
export const projects = pgTable("projects", {
// ... existing columns
priority: text("priority").notNull().default("medium"), // ADD THIS
})npm run db:pushStep 2: Validation Schema
// src/features/projects/validation.ts
export const createProjectSchema = z.object({
name: z.string().min(1),
description: z.string().optional(),
status: z.enum(["active", "completed", "archived"]).default("active"),
priority: z.enum(["low", "medium", "high"]).default("medium"), // ADD THIS
})
export const updateProjectSchema = createProjectSchema.partial()Step 3: Queries
// src/features/projects/queries.ts
// Add to type
export type Project = {
id: string
name: string
description: string | null
status: string
priority: string // ADD THIS
createdAt: Date
updatedAt: Date
}
// Add to select in listProjects
.select({
id: projects.id,
name: projects.name,
status: projects.status,
priority: projects.priority, // ADD THIS
createdAt: projects.createdAt,
})Step 4: Actions
Actions automatically include new fields via spread:
// src/features/projects/actions.ts
// No changes needed if using spread:
.values({
organizationId: params.organizationId,
...params.data, // Includes priority automatically
})Step 5: Router
Router uses Zod schema from validation.ts, so no changes needed if you updated Step 2.
Step 6: UI
// In your form component
<Select value={values.priority} onValueChange={(v) => setField("priority", v)}>
<SelectTrigger>
<SelectValue placeholder="Priority" />
</SelectTrigger>
<SelectContent>
<SelectItem value="low">Low</SelectItem>
<SelectItem value="medium">Medium</SelectItem>
<SelectItem value="high">High</SelectItem>
</SelectContent>
</Select>Verify
npm run typecheckIf TypeScript passes, you're done.
Common Mistakes
❌ Wrong: Adding column but forgetting Zod schema
// DB has the column, but validation rejects it
// Error: "Unrecognized key: priority"✅ Correct: Always update validation.ts first
❌ Wrong: Adding nullable column without default
priority: text("priority").notNull(), // Will fail for existing rows✅ Correct: Add default for existing data
priority: text("priority").notNull().default("medium"),Related
- Add New Feature - Create entire feature
- Database Schema - Schema patterns