Agent skill
backend-bootstrapper
Bootstraps complete backend with Apso, including API setup, database configuration, and testing. Triggers when user needs to create backend, setup API, or initialize server.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/backend-bootstrapper
SKILL.md
Backend Bootstrapper
I set up production-ready backends using Apso, giving you a fully functional REST API in minutes.
What I Create
1. Apso Service Configuration
Complete .apsorc schema file with:
- All entities defined
- Relationships configured
- Validation rules
- Indexes optimized
- Multi-tenancy enabled
2. Generated NestJS Backend
Apso auto-generates:
- REST API with OpenAPI docs
- CRUD endpoints for all entities
- TypeORM models
- Database migrations
- Validation middleware
- Error handling
- Logging
3. Database Setup
- PostgreSQL database (local or AWS RDS)
- All tables created
- Relationships enforced
- Migrations ready
- Seed data (optional)
4. Development Environment
- Docker Compose for local database
- Environment variable configuration
- Development server running
- Hot reload enabled
5. API Documentation
- OpenAPI/Swagger documentation
- Interactive API testing UI
- Type definitions exported
- Example requests
The Bootstrap Process
Step 1: Validate Schema
I'll review the schema from schema-architect and:
- Check for missing fields
- Validate relationships
- Ensure multi-tenancy
- Add recommended indexes
- Suggest optimizations
Step 2: Create Apso Project
# Install Apso CLI
npm install -g @apso/apso-cli
# Create new service
apso server new --name your-service-backend
# Navigate to project
cd your-service-backend
Step 3: Configure Schema
I'll create the .apsorc file with your entities:
{
"service": "your-service-api",
"version": "1.0.0",
"database": {
"provider": "postgresql",
"host": "localhost",
"port": 5432,
"database": "your_service_db"
},
"auth": {
"enabled": true,
"provider": "better-auth"
},
"multiTenant": true,
"entities": {
// Your schema here
}
}
Step 4: Generate Code
# Generate NestJS backend
apso server scaffold
# This creates:
# src/
# autogen/ ← Generated code (DON'T EDIT)
# extensions/ ← Your custom code
# common/ ← Shared utilities
# main.ts ← Entry point
Step 5: Install Dependencies
npm install
Step 6: Start Database
# Start PostgreSQL via Docker
npm run compose
# This starts:
# - PostgreSQL on port 5432
# - pgAdmin on port 5050 (optional)
Step 7: Provision Database
# Create tables and run migrations
npm run provision
# This:
# - Creates all tables
# - Sets up foreign keys
# - Creates indexes
# - Runs seed data (if any)
Step 8: Start Development Server
# Start backend server
npm run start:dev
# Server runs at:
# - API: http://localhost:3001
# - OpenAPI Docs: http://localhost:3001/api/docs
# - Health Check: http://localhost:3001/health
Step 9: Verify & Test
I'll test all endpoints:
# Health check
curl http://localhost:3001/health
# Test CRUD endpoints
curl http://localhost:3001/organizations
curl http://localhost:3001/users
curl http://localhost:3001/projects
Generated API Structure
For each entity, you get:
Standard REST Endpoints
List
GET /entities
Query params: ?page=1&limit=10&sort=created_at&order=desc
Response: { data: [...], total: 100, page: 1, limit: 10 }
Get by ID
GET /entities/:id
Response: { id, ...fields }
Create
POST /entities
Body: { field1: value1, field2: value2 }
Response: { id, ...fields, created_at, updated_at }
Update
PUT /entities/:id
PATCH /entities/:id (partial update)
Body: { field1: newValue }
Response: { id, ...fields, updated_at }
Delete
DELETE /entities/:id
Response: { success: true }
Filtering & Querying
Filter by field
GET /entities?status=active
GET /entities?created_at_gte=2024-01-01
Full-text search
GET /entities?search=keyword
Relations
GET /entities?include=relations
GET /organizations/123/users (nested route)
Aggregations
GET /entities/count
GET /entities/stats
Automatic Features
1. Multi-Tenancy
Every request is automatically scoped to the organization:
// Middleware adds organization context
@UseGuards(OrgGuard)
export class ProjectController {
// All queries filtered by req.organizationId
async findAll(@Req() req) {
// Only returns projects for req.organizationId
}
}
2. Validation
Input validation with class-validator:
// Automatically validated
class CreateProjectDto {
@IsString()
@MinLength(3)
@MaxLength(100)
name: string;
@IsEnum(['active', 'archived'])
status: string;
}
3. Error Handling
Consistent error responses:
{
"statusCode": 400,
"message": "Validation failed",
"errors": [
{
"field": "name",
"message": "name must be at least 3 characters"
}
]
}
4. Logging
Structured logging with Winston:
// Automatic logging of:
// - All requests
// - Errors
// - Database queries
// - Performance metrics
5. OpenAPI Documentation
Interactive docs at /api/docs:
- All endpoints documented
- Request/response schemas
- Try-it-out functionality
- Example requests
File Structure
your-service-backend/
├── src/
│ ├── autogen/ ← ⚠️ NEVER MODIFY - Generated by Apso
│ │ ├── Organization/ ← Entity-specific modules
│ │ │ ├── Organization.entity.ts
│ │ │ ├── Organization.service.ts
│ │ │ ├── Organization.controller.ts
│ │ │ └── Organization.module.ts
│ │ ├── User/
│ │ ├── guards/ ← ⚠️ AUTO-GENERATED - Auth & scope guards
│ │ │ ├── auth.guard.ts # AuthGuard for session validation
│ │ │ ├── scope.guard.ts # ScopeGuard for multi-tenant data isolation
│ │ │ ├── guards.module.ts # NestJS module for guards
│ │ │ └── index.ts # Barrel exports
│ │ └── index.ts
│ │
│ ├── extensions/ ← ✅ YOUR CUSTOM CODE (safe to modify)
│ │ ├── Organization/
│ │ │ ├── Organization.controller.ts (add custom endpoints)
│ │ │ └── Organization.service.ts (add business logic)
│ │ ├── User/
│ │ ├── Project/
│ │ └── auth/ (Better Auth integration)
│ │
│ ├── common/ ← Shared utilities
│ │ ├── interceptors/
│ │ ├── decorators/
│ │ └── filters/
│ │
│ └── main.ts ← App entry point
│
├── test/ ← Tests
│ ├── unit/
│ └── e2e/
│
├── .apsorc ← Schema definition
├── docker-compose.yml ← Local database
├── package.json
└── README.md
Important: Guards are now generated inside src/autogen/guards/ to clearly indicate they are auto-generated. All files in autogen/ are overwritten on every apso server scaffold run.
Customization Options
Adding Custom Endpoints
// src/extensions/Project/Project.controller.ts
import { Controller, Post, Param } from '@nestjs/common';
@Controller('projects')
export class ProjectController {
// Add custom endpoint
@Post(':id/archive')
async archive(@Param('id') id: string) {
// Your custom logic
return this.projectService.archive(id);
}
@Get(':id/statistics')
async getStats(@Param('id') id: string) {
// Custom aggregation
return this.projectService.getStatistics(id);
}
}
Adding Business Logic
// src/extensions/Project/Project.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class ProjectService {
async archive(id: string) {
// Complex business logic
const project = await this.findOne(id);
// Archive all tasks
await this.taskService.archiveByProject(id);
// Update project status
return this.update(id, { status: 'archived' });
}
}
Adding Middleware
// src/common/interceptors/logging.interceptor.ts
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler) {
const req = context.switchToHttp().getRequest();
const { method, url } = req;
console.log(`${method} ${url}`);
return next.handle();
}
}
Environment Configuration
I'll create .env files:
# .env (local development)
NODE_ENV=development
PORT=3001
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=your_service_db
DB_USER=postgres
DB_PASSWORD=postgres
# Better Auth
AUTH_SECRET=your-secret-key-here
AUTH_URL=http://localhost:3001
# AWS (for production)
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
# Stripe
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
Testing
I'll set up testing structure:
// test/e2e/project.e2e-spec.ts
describe('ProjectController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/projects (GET)', () => {
return request(app.getHttpServer())
.get('/projects')
.expect(200)
.expect((res) => {
expect(res.body.data).toBeInstanceOf(Array);
});
});
it('/projects (POST)', () => {
return request(app.getHttpServer())
.post('/projects')
.send({ name: 'Test Project', organization_id: '...' })
.expect(201)
.expect((res) => {
expect(res.body.name).toBe('Test Project');
});
});
});
Verification Checklist
Before marking bootstrap as complete, I verify:
- ✅ Server starts without errors
- ✅ Database connection successful
- ✅ All tables created
- ✅ OpenAPI docs accessible
- ✅ CRUD endpoints work for all entities
- ✅ Multi-tenancy filtering active
- ✅ Validation works on create/update
- ✅ Error handling returns proper responses
- ✅ Environment variables configured
- ✅ Docker Compose running
Common Issues & Solutions
Issue: "Cannot connect to database"
Fix: Ensure npm run compose is running and ports aren't conflicting
Issue: "Module not found"
Fix: Run npm install after generating code
Issue: "TypeORM entity not found"
Fix: Run npm run provision to sync schema
Issue: "Port 3001 already in use"
Fix: Kill existing process: lsof -ti:3001 | xargs kill
What's Next?
After bootstrap, you're ready for:
- Frontend Setup - Call
frontend-bootstrapper - Authentication - Call
auth-implementer - Custom Endpoints - Add business logic to extensions/
- Testing - Call
test-generator
Ready?
I'll bootstrap a production-ready backend in about 5 minutes. Just provide your schema (or I can call schema-architect first if you don't have one yet).
Do you have a schema ready, or should I design one first?
Didn't find tool you were looking for?