Skip to content
KheAi
Go back

Claude Code & the AI Development Layer

Edit page

What This Part Covers


Meteor Equivalent

Meteor developers had no equivalent. You Googled, read StackOverflow, pasted code from the docs. In 2026, that workflow is the slow path.

Old workflowAI-accelerated workflow
Read docs, grep files, understand the patterngraphify query "how does auth work" → answer in 5 seconds
Manually check “what calls this function?”gitnexus impact({ target: "signIn" }) → blast radius in seconds
Write boilerplate from scratchbackend-specialist agent generates 12 files, you review
Forget a @UseGuards on a mutation/code-review catches it before the PR
Lose context across sessionsPersistent memory recalls your last decision

The shift is not “AI writes your code.” It is AI handles the mechanical + structural work; you handle the business logic and judgment.


1. Install Claude Code

npm install -g @anthropic-ai/claude-code
claude --version
# claude 1.x.x

Start a session from your project root:

cd /path/to/enterprise-todo
claude

Claude Code reads the .claude/ directory in your project and the global ~/.claude/ automatically on startup.


2. The .claude/ Directory

Every enterprise project should have this structure:

.claude/
├── CLAUDE.md               ← instructions loaded on every Claude session
├── agents/                 ← sub-agent persona definitions
│   ├── backend-specialist.md
│   ├── migration-specialist.md
│   └── test-writer.md
├── rules/                  ← standing rules (injected as system context)
│   ├── architecture.md
│   ├── security.md
│   ├── performance.md
│   └── migrations.md
├── skills/                 ← slash command workflows
│   └── graphify/
│       └── SKILL.md
├── mcp.json                ← MCP server connections
├── settings.json           ← hooks (auto-run on tool calls)
└── settings.local.json     ← personal permission allowlist (gitignored)

2.1 CLAUDE.md — The Project Briefing

This file is loaded automatically at the start of every Claude session. It tells Claude:

# enterprise-todo CLAUDE.md

## Caveman Mode
Terse, imperative. No pleasantries.

## Rule Files
@.claude/rules/architecture.md
@.claude/rules/security.md
@.claude/rules/performance.md
@.claude/rules/migrations.md

## Project Overview
**What it is:** Enterprise NestJS GraphQL API for a todo app
**Stack:** NestJS 11, GraphQL/Apollo, TypeORM/PostgreSQL, Redis/Bull, Passport JWT RS256
**Modules:** Auth, User, Tag, Todo

## Commands
# Start:  yarn api:dev
# Test:   yarn api:test
# Build:  yarn api:build
# Lint:   yarn lint

## Architecture
Nx monorepo. apps/api is the main NestJS GraphQL API. libs/contracts has shared types.
All modules follow CQRS: Resolver → Bus → Handler → Service → Repository.
Feature branches → squash merge to main. Conventional commits via yarn cz.

The @.claude/rules/architecture.md syntax tells Claude to load the content of that file inline. You maintain rules in separate files instead of one giant CLAUDE.md.

2.2 rules/ — Standing Constraints

Claude loads these automatically because CLAUDE.md references them. They encode the non-negotiables:

# .claude/rules/architecture.md
- Every module MUST follow the 9-step pattern: Entity → DTO → CQRS Input → Handler → Service → Resolver → Module → Register → Migrate.
- Handlers are thin. No business logic in handlers — it belongs in services.
- Resolvers do not touch repositories directly. Always go through CQRS bus.
- Use AbstractEntity and AbstractDto as base classes.
- All paginated lists use Relay cursor pagination (Connection types) — never raw arrays.
- Use @IsUndefined() (not @IsOptional()) for partial update input fields.
# .claude/rules/security.md
- Every mutation and sensitive query MUST have @UseGuards(AuthJwtGuard).
- Never store secrets in code. Use .env locally, AWS Secrets Manager in production.
- All JWT uses RS256. Never use HS256.
- ValidationPipe with forbidNonWhitelisted: true is global — never disable it.
- userId is NEVER a @Field() on any input type — always injected from JWT.

When you type “create a Product module”, Claude reads these rules first and generates code that complies with them — without you repeating “don’t forget guards” every time.

2.3 agents/ — Sub-Agent Personas

Agents are specialized sub-instances of Claude with a focused system prompt. You invoke them for parallelisable or deep specialized work.

---
# .claude/agents/backend-specialist.md
name: backend-specialist
description: Expert in this project's NestJS/CQRS/TypeORM/GraphQL backend patterns.
Use for: adding modules, reviewing handlers, writing service logic, debugging queries.
---

You are a backend specialist for the enterprise-todo project.

Stack: NestJS 11, TypeScript 5, GraphQL (Apollo + nestjs-query), TypeORM 0.3, PostgreSQL,
Redis/Bull, Passport JWT RS256, CQRS via @nestjs/cqrs + nestjs-typed-cqrs.

You know the 9-step module pattern and apply it precisely. When asked to scaffold a module,
produce all 9 files in the correct pattern without asking for clarification on structure.

Rules you always follow:
- Run impact analysis before touching any existing symbol
- Handlers are always one-liners: service.method(message.args)
- Every domain entity carries tenantId FK for multi-tenancy
- userId is never a @Field() on inputs — always injected from JWT
- DataLoaders are Scope.REQUEST — never singleton
---
# .claude/agents/migration-specialist.md
name: migration-specialist
description: Safe DB migration generation and review.
---

You are a database migration specialist.

ORM: TypeORM 0.3 + PostgreSQL 15. SnakeNamingStrategy active.
AbstractEntity provides id (SERIAL PK), created_at, updated_at.

Before generating any migration:
1. Read the entity file
2. Check existing migrations for current DB state
3. Generate, then READ the SQL — verify it matches intent
4. Check for: DROP COLUMN (data loss), ALTER TYPE (lock), NOT NULL without default

Always provide a rollback plan. For destructive changes, recommend multi-step migration.
---
# .claude/agents/test-writer.md
name: test-writer
description: Writes unit and E2E tests following the project's test patterns.
---

You write unit and E2E tests for the enterprise-todo project.

Unit tests:
- Mock repositories with jest.fn() + getRepositoryToken(Entity)
- Test service methods independently
- Test handler execute() = delegates to service with message.args

E2E tests:
- Use supertest against the real NestJS app
- Real PostgreSQL test database — never mock the DB
- Test: happy path, auth rejection, business rule violations

Always run yarn api:test after writing unit tests. Verify no regressions.

How to invoke agents:

# In Claude session:
"Use the backend-specialist agent to scaffold a Product module with..."
"Use the test-writer agent to write unit tests for ProductService..."
"Use the migration-specialist to review this migration file: <paste content>"

2.4 mcp.json — Tool Connections

MCP (Model Context Protocol) servers give Claude specialized tool access beyond its built-in capabilities.

// .claude/mcp.json
{
  "mcpServers": {
    "gitnexus": {
      "command": "node",
      "args": [".gitnexus/run.cjs", "mcp"]
    },
    "sequential-thinking": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}
ServerWhat it enables
gitnexusCall graph, impact analysis, blast radius, safe renames
sequential-thinkingStructured multi-step reasoning for complex problems
githubRead/create issues and PRs without leaving the terminal

Verify connected:

claude
/mcp
# → gitnexus: connected
# → sequential-thinking: connected
# → github: connected

2.5 settings.json — Auto Hooks

Hooks run automatically before or after specific tool calls. They nudge Claude toward better habits without you typing reminders.

// .claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{
          "type": "command",
          "command": "echo 'Reminder: for codebase questions, prefer graphify query over grep'"
        }]
      }
    ]
  }
}

Practical effect: when Claude reaches for grep to understand the codebase, the hook reminds it to use the knowledge graph instead — saving tokens and returning more accurate results.

2.6 settings.local.json — Your Permission Allowlist

This file is gitignored (yours alone). Pre-approve common commands so Claude doesn’t ask for permission every run.

// .claude/settings.local.json
{
  "permissions": {
    "allow": [
      "Bash(git status)",
      "Bash(git log *)",
      "Bash(git diff *)",
      "Bash(yarn api:test*)",
      "Bash(yarn lint*)",
      "Bash(graphify *)",
      "Bash(nx show project *)"
    ]
  }
}

graphify builds a knowledge graph from your source code’s AST (abstract syntax tree). It extracts symbols, relationships, and concepts — then lets you query in natural language.

Building the Graph

# Initial build (runs once, or after major refactors)
graphify export .

# Fast update after edits (AST-only, no API cost)
graphify update .

This creates graphify-out/ with:

Querying the Graph

# Semantic concept search — best for "what" questions
graphify query "how does auth guard work"
graphify query "which modules use DataLoader"
graphify query "CQRS handler pattern"

# Relationship query — best for "how do X and Y connect"
graphify path "TodoResolver" "TodoService"

# Deep explanation — best for "explain this"
graphify explain "FilterQueryBuilder"

In Claude sessions (preferred — Claude interprets results):

"Query the graph for how the auth module handles RS256 JWT verification."
"Find all modules that inject TenantContext."
"Explain the FilterQueryBuilder usage pattern in this codebase."

When to Use graphify vs Read

QuestionTool
”How does X work?”graphify query "X"
”Which files use X?”graphify query "X"
”What’s the relationship between A and B?”graphify path "A" "B"
”I need to edit file X.ts”Read the file directly
”I need to debug a specific function”Read the specific file

Rule: use graphify for understanding, Read/Edit for modifying.


4. gitnexus — Call Graph & Impact Analysis

gitnexus indexes the actual call relationships between functions, classes, and modules. It answers: “if I change X, what breaks?”

The Most Important Rule in This Stack

MUST run impact analysis before editing any symbol.

# In Claude session, before touching any function:
"I want to modify signIn in AuthService. Run impact analysis first."

Claude runs:

impact({ target: "signIn", direction: "upstream" })

Returns:

Symbol: signIn (AuthService)
Direct callers: signInCommandHandler.execute
Affected processes: Authentication Flow (3 steps)
Risk level: LOW

Upstream chain:
AuthResolver.signIn → CommandBus → SignInCommandHandler.execute → AuthService.signIn

LOW risk → safe to proceed. If it returns HIGH or CRITICAL, Claude explains why and what else would break.

Other gitnexus Tools

# Full context on a symbol (callers + callees + execution flows)
"Give me full context on TodoService.createOne"
→ context({ name: "TodoService.createOne" })

# Detect what your changes actually touched
"Run detect_changes and tell me if I accidentally changed anything outside TodoModule"
→ detect_changes({ scope: "uncommitted" })

# Compare against main before a PR
"Check detect_changes against main to verify my PR scope"
→ detect_changes({ scope: "compare", base_ref: "main" })

# Safe rename (updates all call sites in the graph)
"Rename createOneTodoCommandHandler to createTodoCommandHandler everywhere"
→ rename({ from: "createOneTodoCommandHandler", to: "createTodoCommandHandler" })

Why rename matters: find-and-replace renames strings. gitnexus rename understands the call graph — it knows which occurrences are symbol references vs. string literals vs. comments.


5. The 6-Phase AI-Accelerated Workflow

This is the complete workflow for adding a new module using AI tools at each phase. Everything here is optional — all of it can be done without agents. The agents save time on repetitive structure; they don’t replace judgment.

Read this only after building at least two modules manually. You need the muscle memory to catch mistakes in what agents generate.

Phase 1 — Orient (Before Creating Any File)

claude

Understand the territory:

"Query the graph for how the Tag module is structured.
I'm about to build a similar module called Product."

Claude runs graphify query "tag module structure" → returns the relevant nodes.

Find the closest reference:

"Which existing module is most similar to what I'm building?
I need: one entity, FK to user, ownership-scoped reads, no nested relations."

Check blast radius on anything you plan to touch:

"I need to extend AbstractEntity to add a soft-delete column.
Run impact analysis first."

Phase 2 — Scaffold with backend-specialist

"Use the backend-specialist agent to scaffold a Product module.

Entity: Product
Columns: name (string, required), price (decimal, required), status (ProductStatus enum: ACTIVE/ARCHIVED), userId (FK to user, required, server-injected)
GraphQL: createProduct (auth), updateProduct (auth, ownership), deleteProduct (auth, ownership), getMyProducts (auth, paginated, userId filter), product (public, by id)
Ownership: userId injected from JWT in resolver, never from @Args()
Pattern reference: follow the Tag module exactly for structure, Bookmark module for ownership"

Your job after scaffold returns:

# 1. Review every generated file — do not skip
# Check: AbstractEntity base class on entity
# Check: @UseGuards(AuthJwtGuard) on all mutations
# Check: userId has NO @Field() on any input — only declared as TypeScript property
# Check: NestjsQueryGraphQLModule.forFeature in module (not plain TypeOrmModule)
# Check: handlers are one-liners
# Check: module imported in AppModule

# 2. TypeScript compile check
yarn api:dev
# Fix compile errors before continuing

# 3. Ask Claude to review the output
"Review the generated Product module files.
Check: AbstractEntity, guard usage, userId security, module wiring, thin handlers.
List any violations."

Phase 3 — Migration Review with migration-specialist

yarn migration:generate --name=create-product-table

Then:

"Use the migration-specialist to review this migration.
Flag: data loss risk, missing constraints, NOT NULL without default, unexpected table changes.
<paste the full migration TypeScript file>"

Common issues the specialist catches:

Phase 4 — Test Generation with test-writer

"Use the test-writer agent to write unit tests for ProductService.
Cover: createOne happy path, createOne DB error throws BadRequestException,
updateOne not-found throws, deleteOne happy path.
Follow the TagService test pattern exactly.
Write to: apps/api/src/modules/product/test/product.service.spec.ts"
"Use the test-writer to write CQRS handler tests for the Product module.
Each handler: one test, verifies delegation to service method with message.args.
Write to: apps/api/src/modules/product/test/product.cqrs.spec.ts"
"Use the test-writer to write E2E tests for Product.
Cover: createProduct (auth), createProduct (no auth → 401), getMyProducts (only own records),
updateProduct, deleteProduct.
Write to: apps/api-e2e/src/api/product.e2e-spec.ts"

Then verify:

yarn api:test        # unit tests must pass
yarn api:e2e         # E2E must pass (Docker running)

Phase 5 — Pre-PR Code Review

# In Claude session with feature branch checked out:
/code-review

This reviews the current git diff against main. Claude checks for:

For focused review:

"Review only the resolver and entity for the Product module.
Check: (1) all mutations have @UseGuards, (2) userId is never a @Field(),
(3) @Index() on the userId column in the entity,
(4) no direct repository access in the resolver."

Phase 6 — Update Knowledge Graphs After Merge

# After PR is merged, pull main and update both graphs:
git checkout main && git pull

# Update codebase knowledge graph (fast, no API cost)
graphify update .

# Re-index call graph with new symbols
node .gitnexus/run.cjs analyze

If your module introduced a non-obvious pattern (custom soft-delete, unusual query scope):

"Document the Product module's soft-delete pattern as a concept note.
The soft-delete uses a deletedAt column filtered in every FindMany query
via a custom scope — different from the standard deleteOne() pattern used in Tag."

6. Prompt Library

Copy-paste these into any Claude session. Substitute <Module> with your module name.

Orient before building:

"Query the graph for modules that have: FK to user, ownership-scoped queries.
I'm designing <Module> and need the right reference module."

Scaffold a module:

"Use the backend-specialist agent to scaffold a <Module> module.
Entity columns: <list>
GraphQL operations: <list>
Ownership: userId injected from JWT, not from client
FK dependencies: <list any FKs>
Reference pattern: <Tag | Bookmark | Todo>"

Check impact before editing existing code:

"I need to change <FunctionName> in <file>.
Run impact analysis and report the blast radius before I proceed."

Review a migration:

"Review this migration for safety. Flag DROP statements, missing constraints,
NOT NULL without defaults, and verify down() is reversible:
<paste migration content>"

Generate tests for a finished module:

"Write unit tests for <Module>Service: happy path, not-found error, silence mode.
Write E2E tests: authenticated create, auth rejection, list shows only own records.
Follow the patterns in tag.service.spec.ts and tag.e2e-spec.ts exactly."

Pre-PR review:

"Review my current git diff for: missing guards, userId as @Field(),
logic in CQRS handlers, wrong base class, missing CqrsModule.
List violations only — no praise."

Detect unintended changes:

"Run detect_changes against main and tell me which symbols I changed
outside of <Module>. If any exist, explain why."

7. What Agents Cannot Do

These limits are non-negotiable. Know them before relying on agents.

The right mental model: you are the architect, the agents are skilled contractors. A contractor builds what you specify precisely; they don’t redesign the building.


Summary

ToolWhen to useWhat it does
CLAUDE.md + rulesAlwaysLoads project context and constraints automatically
agents/Phase 2, 3, 4Scaffolds modules, reviews migrations, writes tests
graphify queryPhase 1, anytimeSemantic search over codebase without reading files
gitnexus impactBefore any edit to existing codeBlast radius, risk level
gitnexus detect_changesBefore every commitVerify you only changed what you meant to
/code-reviewPhase 5, before every PRSecurity + pattern violations in the diff
settings.local.jsonOnce, personal setupPre-approve common commands to reduce prompts

Edit page
Share this post:

Next Post
GitHub MCP, ClickUp/Lark & Project Management Integration
Previous Post
Multi-tenancy & Role-Based Access Control (RBAC)