7. Build your first feature with your agent
Features in CrabStack are built as modules: one folder of backend code
per feature (its database table, its API routes and the rules for who may
call them), plus a page on the frontend. The template ships a skill that
walks your agent through writing one the same way as the items module
already in the code. A skill is a Markdown file of instructions an agent
follows; this one is .claude/skills/new-module/SKILL.md.
Before you prompt
- The database is running (
docker compose up -d --wait postgres maildevfrom the repository root), because the agent runs a migration. - Docker is running, because the final check starts its own test database.
The prompt
In Claude Code, which loads the skill by itself:
Use the new-module skill to add a notes module. Each signed-in user can
create, list, edit and delete their own notes. A note has a title (up to
200 characters) and a body. Add a page at /notes. When a user deletes their
account, delete their notes. Finish with ./verify.sh and tell me what you
created.
In Cursor, Codex or another agent, start the prompt with "Open
.claude/skills/new-module/SKILL.md and follow it to add a notes module"
instead.
The skill begins by settling four things: the resource name, its fields, who may call each route, and whether you want a page. It also decides what account deletion does to the new table, and tells you which way it went. The prompt above answers all of these; if yours leaves one open, the agent asks or states what it assumed.
What the agent creates
- a migration in
backend/migrations/that creates thenotestable, and its row type inbackend/src/db/types.ts backend/src/notes/: the schemas (the shapes of requests and responses), the service, the controller (the API routes), the module and its specs (tests)- the module registered in
backend/src/app.module.ts - an entry for each new route in
backend/src/common/route-auth.spec.ts, saying who may call it - an entry for the table in
backend/src/users/deletion-policy.ts, the erasure wired into account deletion, and an assertion for it inbackend/src/users/users.service.integration.spec.ts - a regenerated
openapi.json(the API contract) andfrontend/types/api.d.ts(the frontend's types generated from it), with the new types re-exported fromfrontend/lib/api.ts - the page in
frontend/app/notes/
How to check it followed the pattern
Run the full check from the repository root:
./verify.sh
It runs most of what CI runs: formatting, lint, unused-code checks, build
and tests for both halves, against a throwaway Postgres it starts and
removes, plus a check that openapi.json and the frontend types match the
code. A pass ends with verify: all green (integration specs ran). If
Docker is not running, the database tests skip and it ends
verify: NOT green - integration specs skipped instead.
VERIFY_QUIET=1 ./verify.sh prints only the stage results.
What it catches:
- a route with no entry in the route policy (
route-auth.spec.tsfails, naming the controller), or a route whose guards differ from its entry - a table with no account-deletion decision (
deletion-policy.spec.tsfails, naming the table), or an erasure the policy claims but the code does not perform - an API change without a regenerated
openapi.jsonor frontend types - code that does not build, and tests that fail
What it does not catch:
- a route marked public, or a deletion decision of "keep", that is the wrong call. The checks prove the code matches the policy the agent wrote; whether that policy is right is for you to read in the diff.
- a feature that works but is not what you asked for. The agent's tests test what the agent understood.
- what CI does and this check skips to stay quick, among them: running
the tests a second time against a database that already has data in it,
testing on both Node 24 and Node 26, building and starting the Docker
images, testing
verify.shitself, and the dependency audit when the npm registry does not answer (it printsSKIPPED).
So also try the feature: run the app (Option 2 on page 4), open http://localhost:3000/notes, and create, edit and delete a note. Sign in as a second address in a private window and check you cannot see the first user's notes. The checklist at the end of Consume from the frontend is a good final read.
Commit everything the agent changed together, including openapi.json and
frontend/types/api.d.ts: CI regenerates both and fails if the committed
copies differ.
The full walkthrough the skill automates is Adding a Module.
Next: Next steps