Skip to content

Prompt Cookbook

Ready-to-use prompt recipes for common development tasks.

Ready-to-use prompt templates for common engineering tasks. Copy, adapt, and use in your daily workflow.

These are real prompts you type into Claude Code in your terminal. Every recipe was written for the kinds of problems that show up in production systems — microservices, monorepos, legacy code, and cross-team dependencies. Adapt the file paths and service names to your codebase.

How to Use This Cookbook

Each recipe shows:

  • Bad prompt — the common mistake and why it fails
  • Good prompt — the effective version and why it works
  • Variations — adaptations for different contexts

Recipes are organized by task, not by difficulty. Jump to whatever you need right now.

Table of Contents


Chapter 1: Bug Investigation Prompts

Debugging with Claude is not about asking it to “fix the bug.” It is about structuring a joint investigation where you bring the symptoms and Claude brings the ability to search, read, and correlate code faster than you can manually.

Recipe 1.1: Initial Bug Report

Bad:

Fix the bug in checkout

Why it fails: Claude has no idea what the symptom is, who reported it, or where to start. It will guess, and guesses waste your time.

Good:

Users are seeing a 500 error when they submit the checkout form with a
promo code. The error started showing up after last Thursday's deploy.
Help me investigate -- start by looking at the checkout route handler
and the promo code validation logic, and check git log for changes to
those files since last Wednesday.

Why it works: Symptom, timeline, starting points, and a concrete first action. Claude can immediately begin a targeted search instead of scanning the entire codebase.

Variations:

# When you have a stack trace
Here's the stack trace from Sentry: [paste trace]. Walk me through
each frame and explain what's happening. Focus on our code, skip
the framework internals.

# When you have a reproduction
I can reproduce this by sending a POST to /api/orders with
{"items": [], "promoCode": "SAVE20"}. The response is a 500 but
it should be a 400 validation error. Help me trace the request
through the handler to find where it breaks.

Recipe 1.2: Narrowing Down with Parallel Investigation

Bad:

Look everywhere for the problem

Why it fails: “Everywhere” means Claude reads files at random and burns context window on irrelevant code.

Good:

Use subagents to investigate these three areas in parallel:
1. The checkout route handler in src/routes/checkout.ts -- does it
   validate promo codes before passing them to the order service?
2. The promo code service in src/services/promoService.ts -- what
   happens when it receives an expired code?
3. Run git log --since="2026-03-18" -- src/services/promo* src/routes/checkout*
   to see what changed recently
Report back with findings from each area.

Why it works: Three independent investigations run simultaneously. Each has a specific file and a specific question to answer. Results converge into a clear picture.

Variations:

# For a performance issue across layers
Investigate in parallel:
1. The SQL queries in src/repositories/orderRepo.ts -- are any
   missing WHERE clauses or doing full table scans?
2. The caching layer in src/services/cache.ts -- is the TTL set
   correctly for order lookups?
3. Check the N+1 query pattern -- does the order list endpoint
   fetch related items in a loop?

# For a data inconsistency
Investigate in parallel:
1. The write path: trace how user profile updates flow from the
   API handler through the service to the database
2. The read path: trace how the profile page fetches and displays
   user data
3. Check for race conditions: are there any concurrent writes
   that could interleave?

Recipe 1.3: Using Git as a Diagnostic Tool

These prompts treat git history as a first-class debugging resource.

Check git log for changes to src/auth/ in the last two weeks. Show
me what changed and who changed it. I'm looking for anything that
could affect token expiration behavior.
Run git blame on src/services/payment.ts lines 45-80. I want to
understand when the retry logic was last modified and whether the
current backoff values were intentional.
Show me the diff between main and this branch for all files in
src/api/. I need to review what I'm about to merge.
Find the commit that introduced the validateAddress function in
src/utils/validation.ts. Show me the full commit message and diff
so I understand the original intent.

Variation for investigating a regression:

Something broke between v2.3.0 and v2.4.0. List every commit that
touched src/services/billing/ between those two tags. Summarize each
change in one line so I can identify which one likely caused the
regression in invoice calculation.

Recipe 1.4: Tracing Execution Flow

Bad:

How does the order flow work?

Why it fails: Too vague. “The order flow” could mean the UI, the API, the background jobs, the payment integration, or all of the above.

Good:

Trace the request flow for POST /api/orders from the moment it hits
the Express router. Walk through each function call: the route handler,
any middleware, the service layer, the repository, and the final
database query. Show me the actual function signatures and file
locations at each step.

Why it works: Specifies the entry point, the layers to trace through, and the level of detail expected. Claude can follow imports and function calls systematically.

Variations:

# Tracing an async flow
Trace what happens when a new order is placed, starting from the
API handler through to the background job that sends the
confirmation email. I need to understand the async handoff -- how
does the job get queued and what triggers it?

# Tracing error propagation
When a payment fails in src/services/paymentService.ts, how does
the error propagate back to the API response? Does it get wrapped,
logged, or swallowed at any layer?

Recipe 1.5: Validating a Hypothesis Before Fixing

Bad:

The bug is in the payment retry logic, fix it

Why it fails: You might be wrong about the root cause. Jumping straight to a fix on a wrong hypothesis wastes time and can introduce new bugs.

Good:

I think the bug is in the payment retry logic in
src/services/paymentService.ts around line 120. Before I fix anything,
help me verify:
1. Are there tests covering the retry behavior? Run them and show results.
2. Does the same retry pattern exist elsewhere in the codebase?
3. Check git log for this function -- was the current behavior intentional?
4. Trace the callers of this function to understand the full impact of
   changing it.

Why it works: Validates the hypothesis before committing to a fix. Discovers related code that might need the same fix. Checks intent so you do not “fix” something that was deliberately designed that way.

Recipe 1.6: Reproducing with Tests

I found the bug: when promoCode is an empty string (not null, not
undefined, but ""), the validation passes but the discount calculation
divides by zero. Write a failing test that reproduces this exact case,
then let me see it fail before we fix it.

Why this pattern matters: A failing test proves you understand the bug. It also prevents regressions. Always ask Claude to write the test before writing the fix.

Recipe 1.7: Checking for Systemic Issues

The N+1 query in the order list endpoint was easy to spot. But I want
to know: are there other endpoints with the same pattern? Search the
codebase for places where we fetch a list and then loop through it
making individual database calls. Focus on src/routes/ and
src/services/.
We just fixed a missing null check in the user profile handler.
Scan all route handlers in src/routes/ for the same pattern --
places where we access a property on a potentially null database
result without checking first.

Recipe 1.8: Structuring a Bug Report for Claude

Less effective:

The notification endpoint is broken.

More effective:

Bug: POST /api/notifications returns 500 for some users.

Symptoms:
- Works for users created after Jan 2024
- Fails for users created before Jan 2024
- Error: NullPointerException at NotificationService.java:67

Timeline: Started after deploy on March 15
Starting points: NotificationService.java, UserPreferences.java

Why it works: Bug reports with symptoms, timeline, and starting points let Claude narrow the search immediately instead of reading the entire codebase.

Recipe 1.9: Parallel Investigation with Subagents

For complex bugs, investigate multiple hypotheses simultaneously:

I have a bug where session tokens expire after exactly 15 minutes
instead of the configured 60 minutes. Investigate these hypotheses
in parallel:

1. Check the session configuration files for hardcoded values
2. Check the auth middleware for any timeout overrides
3. Check the Redis session store configuration
4. Check recent commits that touched session-related code

Report findings for each hypothesis.

Chapter 2: Feature Development Prompts

Building features with Claude works best when you follow a deliberate sequence: explore, plan, implement, verify. Skipping steps — especially the explore and plan phases — leads to code that does not fit the existing architecture.

Recipe 2.1: Exploration Before Implementation

Bad:

Add caching to the API

Why it fails: Which endpoints? What kind of cache? What invalidation strategy? Claude will make assumptions, and you will spend more time undoing bad assumptions than you saved.

Good:

Before we add caching, I need to understand the current data access
patterns. Look at the services in src/services/ and tell me:
1. Which endpoints hit the database most frequently?
2. Which data is read-heavy vs write-heavy?
3. Are there any existing caching mechanisms I should know about?
4. What are the current response times? Check if there are any
   performance tests or monitoring configs.
I want to make an informed decision about where caching will have
the most impact before we write any code.

Why it works: You get data before making a decision. Claude surveys the codebase and gives you a factual report you can reason about.

Variations:

# Before adding a new integration
Before we integrate with the Stripe API, look at how we handle our
existing third-party integrations (SendGrid in src/services/email/,
Twilio in src/services/sms/). What patterns do we use for retries,
error handling, and credential management? I want to follow the
same conventions.

# Before adding a new data model
Before I add the Subscription model, show me how the existing
models are structured. Look at src/models/ -- what ORM are we
using, how do we handle migrations, and what naming conventions
do we follow for tables and columns?

Recipe 2.2: Architecture Decision with ADR Output

Bad:

What's the best way to add real-time notifications?

Why it fails: “Best” depends on your constraints. Without knowing them, Claude picks whatever sounds technically impressive.

Good:

I need to add real-time notifications to our platform. Users should see
updates within 2 seconds of an event. We currently run on AWS with
Express/TypeScript/PostgreSQL, and the team has no experience with
WebSockets in production.

Propose 3 approaches with tradeoffs. Consider:
- Implementation complexity and team learning curve
- Infrastructure cost at our scale (roughly 10K concurrent users)
- Reliability and failure modes
- How it integrates with our existing Express API

Format as an ADR following the template in our CLAUDE.md.

Why it works: Concrete requirements, known constraints, evaluation criteria, and a specified output format. Claude can reason about tradeoffs instead of just listing technologies.

Recipe 2.3: Incremental Implementation

Bad:

Build the entire notification system

Why it fails: Large changes are hard to review, hard to test, and hard to revert. Claude also loses coherence over very large code generation tasks.

Good:

Let's implement the WebSocket notification system step by step. After
each step, stop so I can review before moving on.

Step 1: Add the data model. Create a notifications table migration
with columns for user_id, type, payload, read_at, and created_at.
Follow the same migration conventions as our existing migrations in
src/db/migrations/.

Start with step 1 only.

Why it works: You stay in control. Each step is reviewable. If Claude makes a bad choice in step 1, you catch it before it cascades through steps 2 through 5.

Follow-up prompts in the same conversation:

Step 1 looks good, committed. Now step 2: create the NotificationService
in src/services/. It should support creating a notification, marking as
read, and fetching unread notifications for a user. Follow the same
patterns as the existing services in that directory.
Step 2 looks good. Before step 3, let's add tests. Write unit tests
for NotificationService covering: creating a notification, marking as
read, fetching unread (with and without results), and error cases.
Follow the test patterns in src/__tests__/services/.

Recipe 2.4: Test-First Development

Bad:

Add tests for the notification service

Why it fails: Written after implementation, tests tend to just assert whatever the code currently does rather than what it should do.

Good:

Before writing the implementation, generate test cases for the
NotificationService. It should:
- Create a notification for a user
- Fetch unread notifications for a user, ordered by most recent
- Mark a single notification as read
- Mark all notifications as read for a user
- Return an empty list when a user has no unread notifications
- Reject creating a notification for a non-existent user

Write the tests following the patterns in src/__tests__/services/.
Use the same test utilities and database setup/teardown. These tests
should fail right now because the service doesn't exist yet.

Why it works: Tests define the contract. When you write the implementation next, you have a clear target. Failed tests tell you exactly what is left to do.

Recipe 2.5: Working Within Existing Patterns

Look at the three most recent feature additions in git log (the last
three feat: commits). For each one, show me what files were added or
modified. I want to understand the standard pattern for adding a new
feature in this codebase so I can follow it for the subscription
feature.
I need to add a new API endpoint for GET /api/subscriptions. Look at
an existing similar endpoint -- GET /api/orders looks like a good
model. Show me all the files involved (route, controller, service,
repository, tests, types) so I can create the same structure for
subscriptions.

Recipe 2.6: Handling Edge Cases

I've got the happy path working for subscription creation. Now help
me think through edge cases:
1. What happens if the user already has an active subscription?
2. What if the payment method is expired?
3. What if the request is duplicated (network retry)?
4. What if the user's account is suspended?
For each case, suggest how we should handle it based on how similar
edge cases are handled elsewhere in the codebase.

Recipe 2.7: Integration Points

The subscription service needs to integrate with three existing
services: PaymentService, UserService, and EmailService. For each
one, show me:
1. The public API (exported functions/methods)
2. How other services currently call them
3. Any gotchas in the error handling or return types
I need to understand these interfaces before I wire up the
subscription service.

Chapter 3: Code Navigation Prompts

Navigating an unfamiliar codebase is one of Claude Code’s strongest use cases. The key is to move from broad orientation to targeted understanding, not the other way around.

Recipe 3.1: Codebase Orientation

Bad:

Explain this codebase

Why it fails: For any non-trivial project, this produces a wall of vague generalities that does not actually help you get oriented.

Good:

Give me a high-level map of this project. I want to understand:
1. What is the entry point? Where does the application start?
2. What are the top-level directories and what role does each play?
3. How is the code organized -- by feature, by layer, or something else?
4. What are the main external dependencies (check package.json)?
5. How do you run the tests, start the dev server, and build for
   production (check package.json scripts)?

Keep it to one paragraph per question. I'll dive deeper where I need to.

Why it works: Structured questions produce structured answers. Asking for one paragraph per question prevents overwhelming output. You get an actionable map, not an essay.

Variations:

# For a monorepo
This is a monorepo. List every package in packages/ and apps/.
For each one, give me a one-sentence summary of what it does and
what other packages it depends on.

# For a service you inherited
I just inherited this service and I have a production issue to debug.
Give me the fastest possible orientation: what does it do, where
are the API endpoints defined, and where is the core business logic?

Recipe 3.2: Understanding a Module in Depth

Bad:

What does the auth module do?

Why it fails: You will get a correct but shallow description. It is the equivalent of reading the README. You need to understand the internals.

Good:

I need to modify the auth module. Walk me through @src/services/auth/:
1. What is the public API -- what do other modules import from here?
2. What is the internal implementation -- how does token generation,
   validation, and refresh actually work?
3. What state does it manage (sessions, tokens, etc.) and where is
   that state stored?
4. What are the failure modes -- what happens when tokens expire,
   when the token store is unavailable, when validation fails?
5. What are the security assumptions -- what does this code trust
   vs. verify?

Why it works: You are asking questions that help you modify the code safely. Understanding the public API tells you what might break. Understanding failure modes tells you what to test. Understanding security assumptions tells you what not to change.

Bad:

Where is the permission checking code?

Why it fails: Permission checking is often spread across middleware, decorators, service methods, database queries, and frontend guards. A single search will miss most of it.

Good:

Find every place in the codebase that makes an authorization decision --
not just authentication (who you are) but authorization (what you can
do). Look in:
1. Middleware and decorators (route-level guards)
2. Service methods (business logic checks)
3. Database queries (row-level security, tenant isolation)
4. Frontend code (UI element visibility based on roles)
5. Configuration files (role definitions, permission mappings)
Group the results by layer and note any inconsistencies.

Why it works: Enumerates the layers where the logic could live. Asking for inconsistencies surfaces bugs — for example, the API allows something the frontend hides but does not enforce.

Recipe 3.4: Dependency Mapping

What depends on the UserService class? I need to understand the
blast radius before I change its interface. Trace:
1. Direct imports -- which files import UserService?
2. Indirect usage -- is it injected via DI? If so, what binds it?
3. Test mocks -- which test files mock UserService?
4. API contracts -- do any API response types include User objects
   that come from this service?
Show me the dependency graph for src/services/. Which services call
which other services? Are there any circular dependencies?

Recipe 3.5: Understanding Data Flow

Trace the lifecycle of a User object from creation to deletion:
1. How is a user created? (API endpoint, service method, database query)
2. Where is user data read and transformed? (serialization, DTOs)
3. What other entities reference the user? (foreign keys, associations)
4. How is a user deleted? Is it soft delete or hard delete?
5. Are there any cascade effects when a user is removed?

Recipe 3.6: Finding Conventions

I need to understand the coding conventions in this project. Look at
5-6 files across different layers (routes, services, repositories,
tests) and tell me:
1. How are errors handled -- custom error classes, error codes, or
   raw exceptions?
2. How is logging done -- what library, what log levels, what format?
3. How is input validation done -- where and with what library?
4. How are database transactions managed?
5. What naming conventions are used for files, functions, and variables?

Recipe 3.7: Reading Legacy Code

@src/services/legacyBillingService.ts is 1200 lines of code with
minimal comments. I need to add a feature but I'm afraid to touch it.
Help me understand it:
1. Break it into logical sections and give each section a name
2. What are the main code paths through this file?
3. Are there any dead code paths (unreachable conditions)?
4. What are the implicit assumptions (things that must be true for
   this code to work but are not checked)?
5. What parts are most fragile -- where would a small change have
   unexpected consequences?

When authorization logic is spread across the codebase:

Find ALL code related to authorization in this project. Check:
- Middleware that checks permissions
- Service methods that verify access
- Database queries that filter by user/role
- API endpoints that should have auth but might not

Map the complete authorization flow from request to data access.
Show file:line for each component.

Recipe 3.9: Data Lifecycle Tracing

Understand how data flows through the system:

Trace the lifecycle of an "order" from creation to completion:
1. How is an order created? (API endpoint, validation, persistence)
2. How is it updated? (status changes, who can modify what)
3. How is it read? (list queries, detail queries, search)
4. How is it deleted or archived?
5. What other data is affected when an order changes?

Show file:line for each step.

Chapter 4: Code Review Prompts

Code review with Claude is not a replacement for human review. It is a way to catch mechanical issues so human reviewers can focus on design, intent, and business logic.

Recipe 4.1: Security-Focused Review

Bad:

Check this file for security issues

Why it fails: Too vague. Claude will list generic security advice that may not apply to your code.

Good:

Review @src/routes/api.ts for security vulnerabilities. Specifically
check for:
1. SQL injection -- are all database queries parameterized?
2. XSS -- is user input sanitized before rendering?
3. Authentication gaps -- are there routes missing the auth middleware?
4. Authorization gaps -- do any routes skip permission checks?
5. Sensitive data exposure -- are passwords, tokens, or PII included
   in responses or logs?
6. Input validation -- are request bodies, params, and query strings
   validated before use?
For each issue you find, show the exact line and explain the attack
vector.

Why it works: A specific checklist produces specific findings. Asking for the attack vector forces Claude to explain how the vulnerability could be exploited, which helps you assess severity.

Variations:

# For API endpoints specifically
Review every endpoint in src/routes/ that accepts user input. For
each one, verify that the input is validated before it reaches the
service layer. Flag any endpoint where raw request data is passed
through without validation.

# For dependency security
Check package.json and package-lock.json for known vulnerable
dependencies. Also check for packages that haven't been updated
in over a year -- they may have unpatched vulnerabilities.

Recipe 4.2: Performance Review

Bad:

Is this code fast?

Why it fails: Fast compared to what? Performance review needs specific concerns to investigate.

Good:

Review the database queries in @src/services/orderService.ts for
performance issues:
1. N+1 queries -- are we fetching related records in a loop instead
   of joining or batch loading?
2. Missing indexes -- based on the WHERE clauses, are there queries
   that would benefit from an index that likely doesn't exist?
3. Over-fetching -- are we selecting all columns when we only need a few?
4. Unbounded queries -- are there queries without LIMIT that could
   return thousands of rows?
5. Connection management -- are we holding connections open longer
   than necessary?
For each issue, show the problematic code and suggest a fix.

Variations:

# For frontend performance
Review @src/components/OrderList.tsx for rendering performance.
Check for: unnecessary re-renders, missing memoization on expensive
computations, large lists without virtualization, and effects that
trigger on every render.

# For memory leaks
Look for potential memory leaks in src/services/. Check for: event
listeners that are never removed, intervals or timeouts that are
never cleared, caches that grow without bounds, and closures that
capture large objects.

Recipe 4.3: Architecture and Design Review

Review @src/services/ for code organization issues:
1. Are responsibilities clearly separated? Does each service have a
   single, coherent purpose?
2. Is there business logic in the wrong layer -- controllers doing
   business logic, services doing data access directly?
3. Are there circular dependencies between services?
4. Is the error handling consistent across services?
5. Are the service interfaces (public methods) clean and well-defined,
   or do they expose internal implementation details?

Recipe 4.4: Review Against Team Standards

I'm about to submit this for review. Check my changes against our
team conventions:
1. Are the commit messages following conventional commit format?
2. Do new files follow the naming conventions in the rest of the
   codebase?
3. Are new functions/methods documented where our existing code
   expects documentation?
4. Do new tests follow the patterns in our existing test suite?
5. Have I updated any configuration or documentation that needs to
   reflect this change?
Show me the diff and flag anything that doesn't match the patterns
used elsewhere in the project.

Recipe 4.5: Pre-Merge Review

Show me everything that will change when I merge this branch into
main. Run git diff main...HEAD and walk me through each file:
1. What changed and why (infer from the code and commit messages)
2. Any concerns -- potential bugs, missed edge cases, style issues
3. What tests cover these changes -- and are there gaps?
Give me a summary I can paste into the PR description.

Recipe 4.6: Reviewing Someone Else’s PR

I'm reviewing PR #247. Pull up the diff and help me understand it:
1. What is this PR trying to accomplish? (read the commits and code)
2. Are there any logic errors or edge cases the author might have missed?
3. Does the code follow the patterns established elsewhere in the
   codebase?
4. Are the tests adequate -- do they cover the main paths and edge cases?
5. Is there anything I should call out that isn't wrong but could be
   improved?
Give me specific, actionable review comments I can leave on the PR.

Recipe 4.7: Reviewing for Testability

Review @src/services/paymentService.ts for testability:
1. Are external dependencies (APIs, databases) injected or hardcoded?
2. Are there pure functions that can be unit tested in isolation?
3. Are there side effects mixed into business logic that make testing
   difficult?
4. What would you need to mock to test this service in isolation?
Suggest refactoring steps that would make this easier to test without
changing its behavior.

Chapter 5: Documentation Prompts

The biggest risk with AI-generated documentation is that it looks correct but is not. Every documentation prompt should include a verification step.

Recipe 5.1: API Documentation

Bad:

Generate API docs

Why it fails: No format specified, no verification step, and no clarity about the audience. You will get something that looks like docs but may have wrong parameter names, missing endpoints, or invented status codes.

Good:

Generate API documentation for the endpoints in @src/routes/users.ts.
For each endpoint, include:
- HTTP method and path
- Authentication requirements
- Request parameters (path, query, body) with types
- Response body with example JSON
- Error responses with status codes and error body format
- Any rate limits or special headers

Cross-reference every detail against the actual source code. If the
route handler calls a validation schema, use that schema to document
the request parameters. If it returns specific error codes, document
those exact codes. Do not invent or assume anything -- if something
is unclear from the code, flag it.

Why it works: Specifies exact output format, demands source code verification, and explicitly forbids hallucination. The instruction to use the validation schema anchors the documentation in actual code.

Variations:

# For internal API documentation
Generate documentation for the internal service interfaces in
src/services/. These are called by other services, not by external
clients. Focus on: method signatures, expected input/output types,
error types that callers should handle, and any preconditions.

# For updating existing docs
Compare the endpoints in @src/routes/users.ts against the
documentation in @docs/api/users.md. Find any discrepancies --
undocumented endpoints, wrong parameter types, missing error codes.
List every difference.

Recipe 5.2: Architecture Documentation

Document the system architecture based on the actual codebase. Include:
1. A Mermaid component diagram showing the main modules and how they
   communicate
2. Data flow for the three most important operations (user signup,
   order placement, payment processing)
3. External service dependencies with how we integrate (REST, SDK, queue)
4. Key design decisions that are visible in the code structure

Base everything on the actual code. If you're not sure about something,
say so rather than guessing. I'll review this with the team.

Recipe 5.3: Runbook Documentation

Generate a runbook for the payment processing service based on the
codebase. Include:
1. How to start/stop the service
2. Key environment variables and what they control
3. Health check endpoints and what they verify
4. Common failure modes (based on error handling in the code) and
   how to diagnose them
5. Database dependencies and how to verify connectivity
6. Logs: where to find them and what to look for

Check the Dockerfile, docker-compose.yml, and any scripts in the
bin/ directory for operational details.

Recipe 5.4: Inline Documentation for Complex Code

Bad:

Add comments to this file

Why it fails: You will get a comment on every line, including obvious ones like // increment the counter above counter++.

Good:

Add documentation to @src/utils/crypto.ts. Follow these rules:
1. Add JSDoc to every exported function with: purpose, parameters,
   return value, and thrown errors
2. Add inline comments ONLY where the code is non-obvious -- explain
   the "why" not the "what"
3. Do not comment self-explanatory code
4. If there are security-sensitive decisions (algorithm choices,
   key lengths), document WHY that choice was made
5. If there are performance tradeoffs, document them

Recipe 5.5: Migration Guides

I'm upgrading the auth library from v2 to v3. Look at all the places
in the codebase that use the v2 API (check imports from 'auth-lib').
Then read the v3 changelog/migration guide at @CHANGELOG.md and create
a step-by-step migration plan that lists every file that needs to
change and what the change should be.

Recipe 5.6: Onboarding Documentation

Imagine you're a new engineer joining this team. Based on the codebase,
generate a developer onboarding guide that covers:
1. How to set up the local development environment (check README,
   Makefile, docker-compose, .env.example)
2. How to run the test suite and what to expect
3. The codebase structure and where to find things
4. The most important code paths to understand first
5. Common gotchas that aren't obvious from reading the code

Verify every command and file path against what actually exists.

Chapter 6: Refactoring Prompts

Refactoring with Claude is safest when you break it into analysis and execution phases. Never ask Claude to “refactor this file” without first understanding what needs to change and why.

Recipe 6.1: Analyze Before Refactoring

Bad:

Refactor orderService.ts, it's too big

Why it fails: “Too big” is not a plan. Claude will move code around but the result may not be better structured.

Good:

@src/services/orderService.ts is 800 lines and hard to maintain. Before
we refactor, analyze it:
1. Group the functions by responsibility. What logical modules exist
   inside this one file?
2. Which functions are called from outside (public API) vs. internal
   helpers?
3. What state or dependencies are shared between function groups?
4. Which functions are most heavily tested (check the test file)?

Based on this analysis, propose a file structure for splitting it up.
Show me what goes where and what the import graph would look like.
Don't write any code yet.

Why it works: Analysis first, code second. You understand the structure before committing to changes. The proposed file structure is reviewable before any code moves.

Recipe 6.2: Incremental Extraction

Based on our analysis, let's extract the order validation logic into
src/services/orderValidation.ts. Move these functions: [list them].
Update all imports in files that call these functions. Run the tests
after to verify nothing broke. Don't change any function signatures
or behavior -- this is a pure structural change.

Why this pattern matters: Pure structural refactoring (move code, update imports, change nothing else) is safe and easy to verify. Mixing structural changes with behavioral changes makes it impossible to tell if a bug is from the refactoring or the behavior change.

Recipe 6.3: Modernizing Patterns

Bad:

Convert this to async/await

Why it fails: Callback-to-async conversion has subtle gotchas around error handling, return values, and concurrent execution. A blanket conversion can change behavior.

Good:

Convert @src/services/legacyEmailService.ts from callbacks to
async/await. For each function:
1. Show the before and after side by side
2. Explain any behavior differences (especially around error handling)
3. Flag any cases where the callback version does something the
   async version can't replicate directly (e.g., calling the callback
   multiple times)

Make the changes one function at a time. After each function, verify
the existing tests still pass.

Recipe 6.4: Adding Type Safety

Bad:

Add TypeScript types to this file

Why it fails: Claude will sprinkle any everywhere or invent types that don’t match actual usage.

Good:

Add TypeScript types to @src/utils/helpers.ts. Rules:
1. Infer types from how the functions are actually called across the
   codebase -- search for every usage of each exported function
2. Never use 'any' -- if the type is genuinely dynamic, use 'unknown'
   with a type guard
3. Create named types/interfaces for complex objects rather than
   inline types
4. Put the new type definitions in src/types/ following the existing
   conventions there
5. After adding types, check if any of the callers would now show type
   errors -- that reveals existing bugs

Recipe 6.5: Reducing Duplication

I suspect there's duplicated logic between src/services/orderService.ts
and src/services/subscriptionService.ts. Compare them and:
1. Identify functions or code blocks that do essentially the same thing
2. For each duplicate, assess whether it's accidental (same logic that
   should be shared) or intentional (similar-looking but with important
   differences)
3. For accidental duplicates, propose a shared utility and show how
   both services would use it
Don't refactor yet -- just show me the analysis.

Recipe 6.6: Improving Error Handling

Review the error handling in src/services/ and propose improvements:
1. Where are errors being swallowed (caught but not re-thrown or logged)?
2. Where are errors being thrown as raw strings instead of Error objects?
3. Where are generic errors hiding specific failure information?
4. Are there places where we should retry instead of immediately failing?
For each issue, show the current code, the problem, and a proposed fix.

Chapter 7: MCP and Skills Prompts

MCP servers extend what Claude can access. Skills standardize how your team uses Claude. Both are most effective when built for specific team workflows, not generic capabilities.

Recipe 7.1: Querying Data During Development

Use the database MCP server to show me the schema of the users table
and the last 5 records created. I want to verify my migration ran
correctly.
Query the orders table to find all orders with status 'pending' that
are more than 24 hours old. I think the job processor is stuck and
I need to confirm.

Recipe 7.2: Cross-Referencing External Data

Use the GitHub MCP server to pull the last 10 closed issues labeled
'bug'. For each one, check if there's a corresponding test in our
codebase that prevents the regression. List any bugs that don't have
regression tests.

Recipe 7.3: Creating a Project-Specific Skill

Bad:

Create a skill

Why it fails: A skill without a specific purpose is useless.

Good:

Create a Claude Code skill in .claude/skills/generate-migration/ that
generates database migration files for our project. The skill should:

1. Follow our naming convention: YYYYMMDD_HHMMSS_description.sql
2. Include both UP and DOWN sections
3. Use our standard header comments (author, ticket, description)
4. Validate that new table/column names follow our snake_case convention
5. Warn if a migration drops a column or table (destructive change)

Look at the existing migrations in src/db/migrations/ for examples
of our conventions. Write the SKILL.md with clear instructions,
examples of input/output, and constraints.

Recipe 7.4: Building a Team Skill for Code Review

Create a Claude Code skill in .claude/skills/security-review/ that
performs a security-focused code review. It should:

1. Check for the OWASP Top 10 issues relevant to our stack
2. Verify that all endpoints have authentication middleware
3. Check that user input is validated before use
4. Flag any hardcoded secrets or credentials
5. Output findings in a table with: file, line, issue, severity, fix

Base the checklist on the actual patterns in our codebase. Look at
how our existing middleware and validation work so the skill checks
for our specific patterns, not generic advice.

Recipe 7.5: Composing MCP and Skills

I want a workflow where I can type /deploy-check and Claude will:
1. Use the GitHub MCP to check that all CI checks on this branch pass
2. Use the database MCP to verify the staging database schema matches
   what this branch expects
3. Check that no environment variables are referenced in code that
   aren't defined in our .env.example
4. Generate a deployment summary with what changed and what to watch

Create a skill that orchestrates this. Show me the SKILL.md.

Chapter 8: The Anti-Patterns

These are the prompting mistakes that waste the most time. Each one includes what to do instead.

Anti-Pattern 1: Too Vague

Bad: Fix it

Better: Users are getting a 500 error on the checkout page when they apply a promo code. The error started after the deploy on March 20. Start by looking at the checkout route handler and the promo validation service.

Why the bad version fails: Claude has no symptoms, no context, and no starting point. It will guess, and wrong guesses cost more time than writing a clear prompt.

Anti-Pattern 2: Too Broad

Bad: Refactor the entire codebase to be more maintainable

Better: The order service in src/services/orderService.ts is 800 lines and has too many responsibilities. Analyze it and propose how to split it into focused modules.

Why the bad version fails: “The entire codebase” is not a unit of work. Claude will either give generic advice or make sweeping changes that break things. Scope to one module at a time.

Anti-Pattern 3: No Context About What to Test

Bad: Add tests

Better: Add unit tests for the PromoCodeService. Cover: applying a valid code, applying an expired code, applying a code that's been used up, and applying a code to an ineligible product. Follow the test patterns in src/__tests__/services/orderService.test.ts.

Why the bad version fails: “Tests” for what? Testing what behavior? At what level? Using what framework and patterns? Every project has specific test conventions that Claude needs to follow.

Anti-Pattern 4: Not Iterating

Bad: Accept the first response without review.

Better: Review the output, then:

This looks mostly right, but the error handling for expired promo
codes should return a 400, not a 404. Also, the discount calculation
doesn't account for our minimum order amount rule. Fix both and
explain the changes.

Why the bad version fails: First drafts are rarely perfect, even from experienced engineers. Reviewing and refining is not a sign that the tool failed — it is how the tool is designed to work.

Anti-Pattern 5: Not Using @References

Bad: Copy-paste 200 lines of code into the prompt.

Better: Review @src/services/paymentService.ts for error handling issues.

Why the bad version fails: Copy-pasting loses file context (name, path, surrounding code). @references let Claude see the file in its actual location and understand how it fits into the project.

Anti-Pattern 6: Not Validating

Bad: Trust that generated documentation is accurate.

Better:

Generate API docs for @src/routes/users.ts. After generating, verify
every endpoint path, parameter name, and response type against the
actual source code. Flag any discrepancy.

Why the bad version fails: Claude can hallucinate plausible-looking details — parameter names, default values, error codes. Asking it to cross-reference against source code catches most of these.

Anti-Pattern 7: Ignoring Git History

Bad: Why is this code written this way?

Better: Run git blame on src/services/billingService.ts lines 90-120 and show me when this retry logic was added and what the commit message says. Was this an intentional design choice or a quick fix?

Why the bad version fails: Claude will speculate about intent based on the code alone. Git history tells you the actual story — who wrote it, when, and often why.

Anti-Pattern 8: Serial When Parallel

Bad: Asking one question at a time in a long sequence.

Better:

Use subagents to investigate in parallel:
1. Check the auth service for how token refresh works
2. Check the API gateway for how it validates tokens
3. Check the frontend for how it handles expired token responses

Why the bad version fails: Three sequential questions take three round trips. Parallel investigation with subagents gets all three answers in one round trip. Use parallel when the questions are independent.

Anti-Pattern 9: Starting with Code

Bad: Implement caching for the order service

Better: Before implementing caching, explore the order service's data access patterns. What queries does it run? How often? What data changes frequently vs. rarely? Then propose a caching strategy.

Why the bad version fails: Implementing before understanding leads to caching the wrong things, wrong TTLs, or missing invalidation logic. Five minutes of exploration saves an hour of rework.

Anti-Pattern 10: Skipping the Plan Step

Bad: Jump straight from “I need feature X” to “write the code.”

Better:

I need to add webhook support for order status changes. Before writing
code, give me a plan:
1. What components need to be created?
2. What existing components need to be modified?
3. What's the order of implementation?
4. What are the risks or tricky parts?

Why the bad version fails: Without a plan, Claude picks an implementation approach based on its training data, which may not fit your architecture. A plan gives you a chance to steer before code is written.


Quick Reference: Prompt Building Blocks

These are modular fragments you can combine into any prompt.

Setting Scope

Focus only on src/services/ -- ignore everything else.
Look at the files changed in this branch (git diff main...HEAD).
Start with the route handler and trace downward to the database.

Requesting Verification

Cross-reference against the actual source code.
After making changes, run the test suite.
Verify all file paths exist before referencing them.
Check that the types match what the callers expect.

Controlling Output

Keep it to one paragraph per point.
Show me a summary table, then details for anything flagged.
Stop after each step so I can review.
Give me the answer first, then the reasoning.

Requesting Format

Format as an ADR following the template in CLAUDE.md.
Output as a Mermaid diagram.
Write it as a runbook with numbered steps.
Create a table with columns: file, issue, severity, suggested fix.

Engaging Parallel Investigation

Use subagents to investigate these areas in parallel: ...
Launch parallel investigations for each service in src/services/.
Compare these three implementations side by side.

Anchoring to Existing Patterns

Follow the same patterns as the existing services in that directory.
Match the conventions used in src/__tests__/.
Look at how the most recent feat: commit structured its changes.
Check how similar features were implemented in the codebase.

Composable Prompt Fragments

Modular fragments you can combine into larger prompts:

Context block:

Read @src/services/OrderService.java and @src/models/Order.java first.

Constraint block:

Constraints:
- Do not change the public API
- All existing tests must continue to pass
- Follow patterns in the existing codebase
- No new dependencies

Verification block:

After making changes:
1. Run the existing tests
2. Verify no type errors (npx tsc --noEmit)
3. Check that no imports are broken

Output format block:

Format your response as:
- Summary (one paragraph)
- Changes made (bulleted list with file:line)
- Risks (anything I should verify manually)

Combine them:

[Context block]

Refactor the discount calculation logic into a separate DiscountEngine class.

[Constraint block]

[Verification block]

[Output format block]