Guided Tutorials
Generate a Full CRUD Feature
Add a complete create, read, update, delete feature to an existing project with validation and tests.
What you'll learn
- How to describe a feature with enough detail for the agent to generate accurate code
- How Autohand reads existing patterns and matches them in generated files
- How to verify generated tests pass and extend the feature with follow-up prompts
Before you start
- Autohand Code installed
- An existing project with at least one resource already implemented
- A test setup already in place (Vitest, Jest, or Mocha)
- Zod or another validation library installed
Describe the feature
Be specific about the data shape, relationships, and business rules when writing your prompt. The agent uses these details to generate accurate validation schemas and correct database queries.
Describe:
- Fields and their types. For blog posts:
title(string, required),body(text, required),published(boolean, default false),authorId(foreign key to users). - Relationships. A post belongs to a user. A user can have many posts.
- Validation rules. Title must be between 5 and 200 characters. Body must not be empty.
authorIdmust reference an existing user. - Any special behavior. Only published posts should appear in the public list endpoint. The author can see all their own posts.
bash
# A prompt with enough detail to generate accurate code
autohand "Add a complete CRUD feature for blog posts to this project.
Fields: title (string, 5-200 chars), body (text, required), published (boolean, default false), authorId (FK to users).
Include model, routes, validation with Zod, and unit tests.
The GET /posts endpoint should only return published posts unless the request is from the author."Run the prompt
Navigate to your project root and run the prompt. The agent reads the existing codebase before generating anything.
bash
cd my-project
autohand "Add a complete CRUD feature for blog posts to this project. Include model, routes, validation with Zod, and unit tests."You will see the agent read several files first. It is looking at your existing models, routes, and tests to understand the patterns already in use.
bash
# Agent output (abbreviated)
Reading: src/models/User.js
Reading: src/routes/users.js
Reading: src/controllers/userController.js
Reading: src/models/__tests__/user.test.js
Reading: package.json
Understood patterns:
- Model layer uses pg Pool with parameterized queries
- Routes follow Express Router pattern
- Tests use Vitest with a test database
- Validation uses Zod schemas in a separate schemas/ folder
Generating blog post feature to match...The agent generates the new feature using the same patterns it found in your existing code. You get output that looks like it was written by the same developer who wrote the rest of your project.
Generated files
A typical CRUD feature for blog posts produces these files.
bash
src/
├── models/
│ └── Post.js # DB queries: create, findById, findAll, update, delete
├── routes/
│ └── posts.js # GET /posts, POST /posts, GET /posts/:id, PUT /posts/:id, DELETE /posts/:id
├── controllers/
│ └── postController.js # Handler functions, calls model methods
├── schemas/
│ └── postSchema.js # Zod schemas for create and update payloads
└── models/__tests__/
└── post.test.js # Unit tests for model methodsThe route file is also registered in your main app file. The agent finds where you import and mount other routers and adds the new one in the same place.
javascript
// src/app.js - the agent adds this line alongside your existing routes
app.use('/posts', require('./routes/posts'));The Zod schema covers both create and update cases. The update schema uses .partial() so all fields are optional on PATCH requests.
javascript
// src/schemas/postSchema.js
import { z } from 'zod';
export const createPostSchema = z.object({
title: z.string().min(5).max(200),
body: z.string().min(1),
published: z.boolean().default(false),
});
export const updatePostSchema = createPostSchema.partial();Verify the tests pass
Run your test suite immediately after generation. The agent should produce passing tests.
bash
npm test
# Expected output
PASS src/models/__tests__/post.test.js
Post model
create
+ creates a post with valid data (12ms)
+ throws when title is too short (3ms)
findAll
+ returns only published posts for anonymous requests (8ms)
+ returns all posts for the author (6ms)
update
+ updates allowed fields (5ms)
delete
+ removes the post from the database (4ms)
Test Files 1 passed (1)
Tests 6 passed (6)If any test fails, read the error message and ask Autohand to fix it.
bash
autohand "The test 'returns all posts for the author' is failing with: Cannot read properties of undefined. Fix it."Customize the output
Once the tests pass, extend the feature with follow-up prompts. The agent keeps all changes consistent with the code it just generated.
bash
# Add soft delete instead of hard delete
autohand "Change the delete endpoint to use soft delete. Add a deletedAt timestamp column. Filter out soft-deleted posts in all queries."
# Add search
autohand "Add a search parameter to GET /posts that does a case-insensitive search on the title and body fields."
# Add pagination
autohand "Add limit and offset pagination to GET /posts. Return a total count along with the results."
# Add slug-based URLs
autohand "Generate a URL-safe slug from the post title on creation. Use the slug as the identifier in GET /posts/:slug instead of the numeric ID."Tip: Run the test suite after each follow-up. Catching a regression early is much easier than debugging three changes at once.
What you learned
- You described a feature with fields, relationships, and validation rules so the agent generated accurate code
- You watched Autohand read existing patterns and produce files that match your project style
- You verified the generated tests pass and extended the feature with soft delete, search, and pagination