Backend Developer
Overview
This skill provides expertise in TypeScript backend development with Node.js, NestJS, and modern server-side technologies. Apply this skill when building APIs, implementing database integrations, fixing backend bugs, optimizing performance, or ensuring backend security.
Core Development Principles
TypeScript Configuration
Essential Setup:
- Enable TypeScript strict mode
- Use TypeScript utility types for code reuse
Architecture Patterns
Layered Architecture:
- Separate into controllers → services → repositories → models
- Use dependency injection; inject interfaces, not concrete classes
- Structure by domain boundaries in modules
Async/Await Best Practices
Consistent Usage:
- Use async/await (not raw
.then() chains)
- Wrap awaited calls in try/catch; throw typed exceptions from services, convert to HTTP responses in middleware
NestJS Development Guidelines
Service Architecture
Controller and Service Separation:
- Keep controllers lean, delegate business logic to services
- Follow SOLID principles, especially Single Responsibility
- Use constructor injection for all dependencies
- Implement interfaces for repositories and external services
Example Implementation:
// ✅ Good - Single Responsibility
@Controller('users')
export class UsersController {
constructor(private readonly userService: UserService) {}
@Post()
async create(@Body() dto: CreateUserDto) {
return this.userService.create(dto);
}
}
@Injectable()
export class UserService {
constructor(private readonly userRepository: IUserRepository) {}
async create(dto: CreateUserDto) {
return this.userRepository.create(dto);
}
}
// ✅ Good - Dependency Inversion
@Module({
providers: [
{ provide: 'UserRepository', useClass: TypeOrmUserRepository }
],
})
export class UsersModule {}
Dependency Injection
Best Practices:
- Always use constructor injection
- Inject interfaces, not concrete implementations
- Define clear provider tokens for dependency resolution
- Use custom providers for complex dependency scenarios
TypeORM Patterns
Entity-First Design
Schema Definition:
- Drive database schema through TypeORM entities
- Use decorators for columns, relationships, and constraints
- Implement entity lifecycle hooks (BeforeInsert, BeforeUpdate) for validation
Example:
@Entity('users')
export class UserEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
email: string;
@BeforeInsert()
@BeforeUpdate()
validateData() {
// Validation logic here
if (!this.email.includes('@')) {
throw new Error('Invalid email');
}
}
}
Repository Pattern
Data Access Encapsulation:
- Create custom repositories for complex queries
- Encapsulate data access logic
- Use query builders for type-safe dynamic queries
Example:
@Injectable()
export class CustomUserRepository extends Repository<UserEntity> {
async findActiveUsers(): Promise<UserEntity[]> {
return this.createQueryBuilder('user')
.where('user.isActive = :isActive', { isActive: true })
.orderBy('user.createdAt', 'DESC')
.getMany();
}
}
Performance Optimization
Async Operation Parallelization
Critical Pattern:
When multiple independent async operations can run concurrently, use Promise.all() to parallelize them for significant performance gains (15-40% latency reduction).
Example:
// ✅ Good - Parallelized independent operations (~40% faster)
async searchByAccount(account: Account): Promise<ContactData[]> {
const startTime = Date.now();
// Parallelize independent operations that don't depend on each other
const [domainResult, keywordsResult] = await Promise.all([
// Operation 1: Domain lookup
this.domainService.findDomain(account.domain).then(result => {
this.logger.log(`Domain lookup completed in ${Date.now() - startTime}ms`);
return result;
}),
// Operation 2: Keywords generation
this.keywordService.generateKeywords(account).then(result => {
this.logger.log(`Keywords generation completed in ${Date.now() - startTime}ms`);
return result;
})
]);
// Use results for subsequent operations
return this.processContactData(domainResult, keywordsResult);
}
// ❌ Bad - Sequential operations (unnecessary wait time)
async searchByAccount(account: Account): Promise<ContactData[]> {
const domainResult = await this.domainService.findDomain(account.domain);
const keywordsResult = await this.keywordService.generateKeywords(account);
return this.processContactData(domainResult, keywordsResult);
}
Key Benefits:
- 15-40% latency reduction for independent operations
- Better resource utilization
- Improved user experience with faster responses
- Reduced total execution time
Performance Monitoring Integration
Metrics:
Emit latency gauges (p50/p95/p99), throughput, and error rate around optimized paths so improvements are measurable.
// ✅ Good - Comprehensive timing metrics for parallel operations
async getInitialContactData(params: SearchParams): Promise<ContactData> {
const overallStart = Date.now();
const salesforceStart = Date.now();
const providerStart = Date.now();
const [salesforceContacts, providerContacts] = await Promise.all([
this.salesforceService.searchContacts(params).then(result => {
this.metricsService.gauge('salesforce_search.latency', Date.now() - salesforceStart);
return result;
}),
this.providerService.searchContacts(params).then(result => {
this.metricsService.gauge('provider_search.latency', Date.now() - providerStart);
return result;
})
]);
this.metricsService.gauge('parallel_contact_search.latency', Date.now() - overallStart);
return this.mergeContactData(salesforceContacts, providerContacts);
}
// Track performance improvement metrics
this.metricsService.histogram('contact_discovery.latency_reduction', reductionPercentage);
Performance Optimization Decision Matrix
| Scenario |
Optimization Technique |
Expected Improvement |
| Independent async operations |
Promise.all() parallelization |
15-40% latency reduction |
| Sequential API calls |
Concurrent requests with error handling |
20-50% improvement |
| Heavy computations |
Caching with Redis/in-memory |
Variable based on computation |
| Large data sets |
Pagination, lazy loading |
Dramatic API responsiveness |
| External service calls |
Request deduplication, intelligent caching |
Reduces redundant network calls |
| Database queries |
Indexing, query optimization, connection pool |
50-90% query time reduction |
Key Insight: Always analyze operation dependencies before optimization - independent operations are prime candidates for parallelization.
Database Optimization
Query Performance:
- Index columns used in WHERE, JOIN, and ORDER BY; verify with
EXPLAIN
- Build queries with query builders, not string concatenation
- Use reversible migrations for schema changes
Connection Management:
- Use a connection pool; acquire on request start, release on request end
- Monitor connection usage and leaks
- Use read replicas for read-heavy operations
API Development
RESTful API Design
Conventions:
- Use semantic HTTP status codes (200, 201, 400, 401, 404, 500, …)
- Validate and sanitize every request body and query param
- Version API endpoints semantically
Error Handling
Strategy:
- Define custom error classes per error type, mapped to HTTP status codes
- Catch at a single middleware boundary; never leak stack traces or internals in responses
Request Validation
Input Sanitization:
- Validate at the controller layer using DTOs with class-validator
- Sanitize user inputs to prevent injection attacks
- Validate both structure and content of requests
Security Best Practices
Authentication & Authorization
Implementation:
- Implement JWT, OAuth, or session-based auth
- Store tokens with short expiry and rotate refresh tokens; never log them
- Hash passwords with bcrypt or argon2
- Implement role-based access control (RBAC)
Security Hardening
Essential Measures:
- Apply input validation and sanitization
- Restrict CORS to known origins (no wildcard in production)
- Use helmet middleware for security headers
- Implement rate limiting and request throttling
- Manage environment variables securely
- Never commit secrets to version control
Logging & Monitoring
Structured Logging
Configuration:
- Configure structured logging with Winston or similar
- Use logging levels (error, warn, info, debug) consistently
- Implement request/response logging
- Include correlation IDs for distributed tracing
Observability
Health Checks:
- Implement health check endpoints
- Monitor application metrics
- Set up alerts for critical errors
- Track performance metrics over time
Testing Strategy
Test Coverage
Comprehensive Testing:
- Write unit tests for business logic
- Implement integration tests for API endpoints
- Create E2E tests for critical user flows
- Use Jest, Supertest, or similar frameworks
- Aim for >80% code coverage for critical paths
Test Organization
Best Practices:
- Follow AAA pattern (Arrange, Act, Assert)
- Mock only external dependencies (network, DB, third-party APIs), not the unit under test
- Use test fixtures and factories
- Keep tests isolated and independent
Deployment & DevOps
CI/CD Integration
Automation:
- Run tests and build on every push; block merge on failure
- Automate deployment from the main branch
- Use environment-based configuration management
- Implement blue-green or canary deployments
Documentation
API Documentation:
- Create API documentation with Swagger/OpenAPI
- Document environment variables and configuration in the README
- Provide setup and deployment instructions
Implementation Workflow
When applying this skill to backend development tasks:
- Project Analysis: Assess current backend structure, dependencies, and architecture patterns
- Architecture Design: Plan the controller/service/repository layering
- Database Integration: Set up ORM/ODM connections and entities
- API Development: Create APIs with routing, middleware, and request validation
- Security Implementation: Apply authentication, authorization, and security hardening
- Performance Optimization: Implement caching, parallelization, and query optimization
- Testing: Write comprehensive unit, integration, and E2E tests
- Logging & Monitoring: Configure structured logging and observability features
- Documentation: Create API docs and maintain README files
Common Anti-Patterns to Avoid
Architecture:
- ❌ Fat controllers with business logic
- ❌ Direct database access from controllers
- ❌ Circular dependencies between modules
- ❌ Missing dependency injection
Performance:
- ❌ Sequential execution of independent async operations
- ❌ Missing database indexes on frequently queried columns
- ❌ No connection pooling
- ❌ Missing caching for expensive operations
Security:
- ❌ Storing passwords in plain text
- ❌ Missing input validation
- ❌ Exposing sensitive data in error messages
- ❌ Hardcoded secrets in code
Error Handling:
- ❌ Swallowing errors silently
- ❌ Generic error messages that don't help debugging
- ❌ Missing try/catch blocks for async operations
- ❌ Improper HTTP status codes
1---2name: backend-developer3description: Specialist for TypeScript backend development including Node.js servers, NestJS applications, APIs, databases (PostgreSQL, MongoDB, Redis), authentication, testing, deployment, server-side code, microservices, database queries, migrations, controllers, services, repositories, and middleware. Use for ANY work involving .ts backend files, server-side architecture, performance optimization, and backend security.4---56# Backend Developer78## Overview910This skill provides expertise in TypeScript backend development with Node.js, NestJS, and modern server-side technologies. Apply this skill when building APIs, implementing database integrations, fixing backend bugs, optimizing performance, or ensuring backend security.1112## Core Development Principles1314### TypeScript Configuration1516**Essential Setup:**17- Enable TypeScript strict mode18- Use TypeScript utility types for code reuse1920### Architecture Patterns2122**Layered Architecture:**23- Separate into controllers → services → repositories → models24- Use dependency injection; inject interfaces, not concrete classes25- Structure by domain boundaries in modules2627### Async/Await Best Practices2829**Consistent Usage:**30- Use async/await (not raw `.then()` chains)31- Wrap awaited calls in try/catch; throw typed exceptions from services, convert to HTTP responses in middleware3233## NestJS Development Guidelines3435### Service Architecture3637**Controller and Service Separation:**38- Keep controllers lean, delegate business logic to services39- Follow SOLID principles, especially Single Responsibility40- Use constructor injection for all dependencies41- Implement interfaces for repositories and external services4243**Example Implementation:**44```typescript45// ✅ Good - Single Responsibility46@Controller('users')47export class UsersController {48 constructor(private readonly userService: UserService) {}4950 @Post()51 async create(@Body() dto: CreateUserDto) {52 return this.userService.create(dto);53 }54}5556@Injectable()57export class UserService {58 constructor(private readonly userRepository: IUserRepository) {}5960 async create(dto: CreateUserDto) {61 return this.userRepository.create(dto);62 }63}6465// ✅ Good - Dependency Inversion66@Module({67 providers: [68 { provide: 'UserRepository', useClass: TypeOrmUserRepository }69 ],70})71export class UsersModule {}72```7374### Dependency Injection7576**Best Practices:**77- Always use constructor injection78- Inject interfaces, not concrete implementations79- Define clear provider tokens for dependency resolution80- Use custom providers for complex dependency scenarios8182## TypeORM Patterns8384### Entity-First Design8586**Schema Definition:**87- Drive database schema through TypeORM entities88- Use decorators for columns, relationships, and constraints89- Implement entity lifecycle hooks (BeforeInsert, BeforeUpdate) for validation9091**Example:**92```typescript93@Entity('users')94export class UserEntity {95 @PrimaryGeneratedColumn('uuid')96 id: string;9798 @Column()99 email: string;100101 @BeforeInsert()102 @BeforeUpdate()103 validateData() {104 // Validation logic here105 if (!this.email.includes('@')) {106 throw new Error('Invalid email');107 }108 }109}110```111112### Repository Pattern113114**Data Access Encapsulation:**115- Create custom repositories for complex queries116- Encapsulate data access logic117- Use query builders for type-safe dynamic queries118119**Example:**120```typescript121@Injectable()122export class CustomUserRepository extends Repository<UserEntity> {123 async findActiveUsers(): Promise<UserEntity[]> {124 return this.createQueryBuilder('user')125 .where('user.isActive = :isActive', { isActive: true })126 .orderBy('user.createdAt', 'DESC')127 .getMany();128 }129}130```131132## Performance Optimization133134### Async Operation Parallelization135136**Critical Pattern:**137When multiple independent async operations can run concurrently, use `Promise.all()` to parallelize them for significant performance gains (15-40% latency reduction).138139**Example:**140```typescript141// ✅ Good - Parallelized independent operations (~40% faster)142async searchByAccount(account: Account): Promise<ContactData[]> {143 const startTime = Date.now();144145 // Parallelize independent operations that don't depend on each other146 const [domainResult, keywordsResult] = await Promise.all([147 // Operation 1: Domain lookup148 this.domainService.findDomain(account.domain).then(result => {149 this.logger.log(`Domain lookup completed in ${Date.now() - startTime}ms`);150 return result;151 }),152153 // Operation 2: Keywords generation154 this.keywordService.generateKeywords(account).then(result => {155 this.logger.log(`Keywords generation completed in ${Date.now() - startTime}ms`);156 return result;157 })158 ]);159160 // Use results for subsequent operations161 return this.processContactData(domainResult, keywordsResult);162}163164// ❌ Bad - Sequential operations (unnecessary wait time)165async searchByAccount(account: Account): Promise<ContactData[]> {166 const domainResult = await this.domainService.findDomain(account.domain);167 const keywordsResult = await this.keywordService.generateKeywords(account);168169 return this.processContactData(domainResult, keywordsResult);170}171```172173**Key Benefits:**174- 15-40% latency reduction for independent operations175- Better resource utilization176- Improved user experience with faster responses177- Reduced total execution time178179### Performance Monitoring Integration180181**Metrics:**182Emit latency gauges (p50/p95/p99), throughput, and error rate around optimized paths so improvements are measurable.183184```typescript185// ✅ Good - Comprehensive timing metrics for parallel operations186async getInitialContactData(params: SearchParams): Promise<ContactData> {187 const overallStart = Date.now();188 const salesforceStart = Date.now();189 const providerStart = Date.now();190191 const [salesforceContacts, providerContacts] = await Promise.all([192 this.salesforceService.searchContacts(params).then(result => {193 this.metricsService.gauge('salesforce_search.latency', Date.now() - salesforceStart);194 return result;195 }),196197 this.providerService.searchContacts(params).then(result => {198 this.metricsService.gauge('provider_search.latency', Date.now() - providerStart);199 return result;200 })201 ]);202203 this.metricsService.gauge('parallel_contact_search.latency', Date.now() - overallStart);204205 return this.mergeContactData(salesforceContacts, providerContacts);206}207208// Track performance improvement metrics209this.metricsService.histogram('contact_discovery.latency_reduction', reductionPercentage);210```211212### Performance Optimization Decision Matrix213214| Scenario | Optimization Technique | Expected Improvement |215|----------|------------------------|---------------------|216| Independent async operations | `Promise.all()` parallelization | 15-40% latency reduction |217| Sequential API calls | Concurrent requests with error handling | 20-50% improvement |218| Heavy computations | Caching with Redis/in-memory | Variable based on computation |219| Large data sets | Pagination, lazy loading | Dramatic API responsiveness |220| External service calls | Request deduplication, intelligent caching | Reduces redundant network calls |221| Database queries | Indexing, query optimization, connection pool | 50-90% query time reduction |222223**Key Insight:** Always analyze operation dependencies before optimization - independent operations are prime candidates for parallelization.224225### Database Optimization226227**Query Performance:**228- Index columns used in WHERE, JOIN, and ORDER BY; verify with `EXPLAIN`229- Build queries with query builders, not string concatenation230- Use reversible migrations for schema changes231232**Connection Management:**233- Use a connection pool; acquire on request start, release on request end234- Monitor connection usage and leaks235- Use read replicas for read-heavy operations236237## API Development238239### RESTful API Design240241**Conventions:**242- Use semantic HTTP status codes (200, 201, 400, 401, 404, 500, …)243- Validate and sanitize every request body and query param244- Version API endpoints semantically245246### Error Handling247248**Strategy:**249- Define custom error classes per error type, mapped to HTTP status codes250- Catch at a single middleware boundary; never leak stack traces or internals in responses251252### Request Validation253254**Input Sanitization:**255- Validate at the controller layer using DTOs with class-validator256- Sanitize user inputs to prevent injection attacks257- Validate both structure and content of requests258259## Security Best Practices260261### Authentication & Authorization262263**Implementation:**264- Implement JWT, OAuth, or session-based auth265- Store tokens with short expiry and rotate refresh tokens; never log them266- Hash passwords with bcrypt or argon2267- Implement role-based access control (RBAC)268269### Security Hardening270271**Essential Measures:**272- Apply input validation and sanitization273- Restrict CORS to known origins (no wildcard in production)274- Use helmet middleware for security headers275- Implement rate limiting and request throttling276- Manage environment variables securely277- Never commit secrets to version control278279## Logging & Monitoring280281### Structured Logging282283**Configuration:**284- Configure structured logging with Winston or similar285- Use logging levels (error, warn, info, debug) consistently286- Implement request/response logging287- Include correlation IDs for distributed tracing288289### Observability290291**Health Checks:**292- Implement health check endpoints293- Monitor application metrics294- Set up alerts for critical errors295- Track performance metrics over time296297## Testing Strategy298299### Test Coverage300301**Comprehensive Testing:**302- Write unit tests for business logic303- Implement integration tests for API endpoints304- Create E2E tests for critical user flows305- Use Jest, Supertest, or similar frameworks306- Aim for >80% code coverage for critical paths307308### Test Organization309310**Best Practices:**311- Follow AAA pattern (Arrange, Act, Assert)312- Mock only external dependencies (network, DB, third-party APIs), not the unit under test313- Use test fixtures and factories314- Keep tests isolated and independent315316## Deployment & DevOps317318### CI/CD Integration319320**Automation:**321- Run tests and build on every push; block merge on failure322- Automate deployment from the main branch323- Use environment-based configuration management324- Implement blue-green or canary deployments325326### Documentation327328**API Documentation:**329- Create API documentation with Swagger/OpenAPI330- Document environment variables and configuration in the README331- Provide setup and deployment instructions332333## Implementation Workflow334335When applying this skill to backend development tasks:3363371. **Project Analysis**: Assess current backend structure, dependencies, and architecture patterns3382. **Architecture Design**: Plan the controller/service/repository layering3393. **Database Integration**: Set up ORM/ODM connections and entities3404. **API Development**: Create APIs with routing, middleware, and request validation3415. **Security Implementation**: Apply authentication, authorization, and security hardening3426. **Performance Optimization**: Implement caching, parallelization, and query optimization3437. **Testing**: Write comprehensive unit, integration, and E2E tests3448. **Logging & Monitoring**: Configure structured logging and observability features3459. **Documentation**: Create API docs and maintain README files346347## Common Anti-Patterns to Avoid348349**Architecture:**350- ❌ Fat controllers with business logic351- ❌ Direct database access from controllers352- ❌ Circular dependencies between modules353- ❌ Missing dependency injection354355**Performance:**356- ❌ Sequential execution of independent async operations357- ❌ Missing database indexes on frequently queried columns358- ❌ No connection pooling359- ❌ Missing caching for expensive operations360361**Security:**362- ❌ Storing passwords in plain text363- ❌ Missing input validation364- ❌ Exposing sensitive data in error messages365- ❌ Hardcoded secrets in code366367**Error Handling:**368- ❌ Swallowing errors silently369- ❌ Generic error messages that don't help debugging370- ❌ Missing try/catch blocks for async operations371- ❌ Improper HTTP status codes