Microservice Spec Generator
You are helping a backend engineer document a microservice architecture. The output is a set of .md spec files — one per service — that any AI agent can read in future sessions to understand the full system without needing to ask again.
Goal
- Build a system map: what services exist, what they own, and how they interact
- Deep dive into each service: APIs, DB schema, events, dependencies
- Write a spec
.mdfor each service + one top-levelARCHITECTURE.md - All files go into
docs/architecture/(or a path the user specifies)
Phase 1: Discovery
1A. Ask the user for their starting point
To map your microservices, I need some starting context. Please share what you have:
1. [PREFERRED] A list of your service repo names or a monorepo folder listing
2. [OPTIONAL] An API gateway config, service mesh config, or docker-compose.yml
3. [OPTIONAL] Any existing architecture diagrams or docs
4. [OPTIONAL] CI/CD config that references service names (e.g. GitHub Actions workflows)
If we're inside a specific service repo right now, I'll start there and ask you to repeat this for each other service.
1B. Auto-discover from the current repo
Search the current directory for signals:
# Service identity
cat package.json 2>/dev/null | grep '"name"'
cat pyproject.toml 2>/dev/null | grep "^name"
cat pom.xml 2>/dev/null | grep -m1 "<artifactId>"
cat go.mod 2>/dev/null | grep "^module"
# Routes / API surface
find . -name "*.route.*" -o -name "*.controller.*" -o -name "*.handler.*" | head -20
find . -name "router.*" -o -name "routes.*" | head -10
# DB schema
find . -name "schema.prisma" -o -name "schema.sql" -o -name "*.migration.*" | head -10
# Events (Kafka, RabbitMQ, SQS, etc.)
grep -r "publish\|subscribe\|emit\|consumer\|producer\|topic\|queue\|exchange" --include="*.ts" --include="*.js" --include="*.go" --include="*.py" --include="*.java" -l | head -10
# Inter-service HTTP calls
grep -r "http\|axios\|fetch\|grpc\|feign\|RestTemplate" --include="*.ts" --include="*.js" --include="*.go" --include="*.py" --include="*.java" -l | head -10
# Docker / deployment
cat docker-compose.yml 2>/dev/null
cat docker-compose.yaml 2>/dev/null
find . -name "Dockerfile" | head -5
1C. If docker-compose.yml or gateway config is available
Extract the full service list from it — this is your definitive service inventory. List:
- Service name
- Port
- Dependencies (depends_on)
- Environment variables that reference other services (e.g.
ORDERS_SERVICE_URL)
Phase 2: System Map
Build the high-level interaction map. For each service, determine:
| Dimension | How to Find It |
|---|---|
| Owns | What domain/data it is responsible for |
| Exposes | REST/gRPC/GraphQL endpoints |
| Publishes | Events/messages it emits |
| Subscribes | Events/messages it consumes |
| Calls | Other services it makes HTTP/gRPC calls to |
| DB | Which database/tables it owns |
| Auth | How it authenticates requests |
Search for inter-service calls:
# Find service URLs referenced in env/config
grep -r "SERVICE_URL\|_HOST\|_ENDPOINT\|grpc\|service\." --include="*.env*" --include="*.yml" --include="*.yaml" --include="*.ts" --include="*.go" -h | sort -u | head -30
# Find event topic/queue names
grep -r "topic\|queue\|exchange\|subject" --include="*.ts" --include="*.go" --include="*.py" --include="*.java" -h | grep -v "\/\/" | sort -u | head -30
Output a System Map in this format before writing any files:
## System Map
Services:
- api-gateway → routes to: orders-service, user-service, inventory-service
- orders-service → calls: inventory-service, payment-service
→ publishes: order.created, order.shipped
→ DB: orders, order_items
- inventory-service→ subscribes: order.created
→ DB: products, stock
- user-service → DB: users, sessions
- payment-service → calls: (external: Stripe)
→ subscribes: order.created
→ publishes: payment.success, payment.failed
Data Flows:
Place Order: FE → api-gateway → orders-service → inventory-service (stock check)
→ payment-service (charge)
← order.created event → inventory-service (reserve stock)
Show this map to the user and ask for corrections before proceeding.
Phase 3: Deep Dive Per Service
For each service, extract the full spec. If in a monorepo, switch directories. If separate repos, ask the user to provide access or paste the relevant files.
API Surface
# List all route definitions
grep -rn "router\.\(get\|post\|put\|patch\|delete\)\|@Get\|@Post\|@Patch\|@Delete\|@Put\|r\.Handle\|mux\.Handle" \
--include="*.ts" --include="*.go" --include="*.py" --include="*.java" | head -50
# Find OpenAPI/Swagger spec if present
find . -name "openapi.*" -o -name "swagger.*" | head -5
For each endpoint, capture:
- Method + path
- Path/query params
- Request body shape (from DTOs, validators, or type definitions)
- Response shape (from serializers, response types, or example responses)
- Auth required (yes/no/role)
DB Schema
# Prisma
cat prisma/schema.prisma 2>/dev/null
# SQL migrations
find . -name "*.sql" -path "*/migrations/*" | sort | tail -5 | xargs cat 2>/dev/null
# Django models
find . -name "models.py" | xargs grep "class.*Model" 2>/dev/null
# TypeORM / Hibernate entities
find . -name "*.entity.*" | head -10 | xargs cat 2>/dev/null
Events
# Event names published
grep -rn "publish\|emit\|send\|produce" --include="*.ts" --include="*.go" --include="*.py" | grep -i "topic\|event\|message" | head -20
# Event names subscribed
grep -rn "subscribe\|consume\|listen\|on(" --include="*.ts" --include="*.go" --include="*.py" | grep -i "topic\|event\|message" | head -20
Outbound Calls
grep -rn "http\.\|axios\.\|fetch(\|grpc\." --include="*.ts" --include="*.go" | grep -v "test\|spec\|mock" | head -20
Domain Pollution Scan
Look for code that does not belong to this service's stated purpose:
# Find all business domain keywords used across the codebase
# e.g. if this is orders-service, flag references to "payment", "inventory", "user profile" logic
grep -rn "class\|function\|def \|func " --include="*.ts" --include="*.go" --include="*.py" --include="*.java" | grep -iv "test\|spec\|mock" | head -60
# Find TODO/FIXME/HACK comments — often signal misplaced logic or known debt
grep -rn "TODO\|FIXME\|HACK\|XXX\|TEMP\|WORKAROUND\|should not be here\|belongs to\|move this" \
--include="*.ts" --include="*.js" --include="*.go" --include="*.py" --include="*.java" | head -30
Flag any functions/classes whose names suggest they belong to a different business domain. These are candidates for the "Domain Pollution" section in the spec.
Legacy & Dead Code Scan
# Deprecated markers
grep -rn "@deprecated\|@Deprecated\|# deprecated\|// deprecated\|DEPRECATED\|obsolete\|legacy\|old_\|_old\|_v1\|_v2\|_new\|_backup" \
--include="*.ts" --include="*.js" --include="*.go" --include="*.py" --include="*.java" | head -30
# Feature flags / toggles — often gate old vs new implementations
grep -rn "featureFlag\|feature_flag\|isEnabled\|FEATURE_\|toggle\|rollout\|experiment\|if.*flag\|if.*enabled" \
--include="*.ts" --include="*.js" --include="*.go" --include="*.py" --include="*.java" | head -20
# Dual route versions (v1 vs v2 of same endpoint)
grep -rn "v1\|v2\|v3" --include="*.route.*" --include="*.controller.*" --include="*.handler.*" | head -20
# Commented-out code blocks (sign of abandoned implementation)
grep -rn "^[[:space:]]*//" --include="*.ts" --include="*.go" | grep -v "import\|eslint\|prettier\|license" | wc -l
# Old migration files vs current schema — large gaps suggest abandoned columns
find . -name