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 for maximum type safety
- Configure backend-optimized tsconfig.json settings
- Leverage advanced types for better code safety
- Use TypeScript utility types for code reuse
Architecture Patterns
Layered Architecture:
- Implement proper separation: controllers → services → repositories → models
- Use dependency injection and inversion of control principles
- Apply SOLID principles and clean architecture patterns
- Structure by domain boundaries in clear modules
Async/Await Best Practices
Consistent Usage:
- Use async/await consistently throughout codebase
- Handle promises properly with try/catch blocks
- Implement proper error boundaries and graceful degradation
- Apply error handling at appropriate abstraction levels
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
Comprehensive Metrics:
Always measure and monitor performance improvements with proper metrics.
// ✅ 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:
- Implement proper database indexing
- Optimize database queries with query builders
- Use connection pooling and manage connections efficiently
- Apply proper database migrations and seeding strategies
Connection Management:
- Configure connection pooling appropriately
- Monitor connection usage and leaks
- Implement proper connection lifecycle management
- Use read replicas for read-heavy operations
API Development
RESTful API Design
Best Practices:
- Follow REST API design principles
- Use proper HTTP status codes (200, 201, 400, 401, 404, 500, etc.)
- Implement proper request validation and sanitization
- Follow semantic versioning for API endpoints
Error Handling
Comprehensive Strategy:
- Set up comprehensive error handling with custom error classes
- Use proper HTTP status codes for different error types
- Implement proper error boundaries
- Provide meaningful error messages without exposing sensitive information
Request Validation
Input Sanitization:
- Implement proper request validation at controller level
- Use DTOs (Data Transfer Objects) 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
- Apply proper security measures for token management
- Use proper password hashing (bcrypt, argon2)
- Implement role-based access control (RBAC)
Security Hardening
Essential Measures:
- Apply input validation and sanitization
- Configure CORS properly
- 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 proper logging levels (error, warn, info, debug)
- 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 external dependencies properly
- Use test fixtures and factories
- Keep tests isolated and independent
Deployment & DevOps
CI/CD Integration
Automation:
- Implement proper CI/CD pipelines
- Automate testing and deployment
- Use environment-based configuration management
- Implement blue-green or canary deployments
Documentation
API Documentation:
- Create API documentation with Swagger/OpenAPI
- Maintain comprehensive README files
- Document environment variables and configuration
- 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 layered architecture with proper separation of concerns
- Database Integration: Implement database connections with proper ORM/ODM setup
- API Development: Create APIs with proper routing, middleware, and 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-developer-33description: 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---5
6# Backend Developer
7
8## Overview
9
10This 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.
11
12## Core Development Principles
13
14### TypeScript Configuration
15
16**Essential Setup:**
17- Enable TypeScript strict mode for maximum type safety
18- Configure backend-optimized tsconfig.json settings
19- Leverage advanced types for better code safety
20- Use TypeScript utility types for code reuse
21
22### Architecture Patterns
23
24**Layered Architecture:**
25- Implement proper separation: controllers → services → repositories → models
26- Use dependency injection and inversion of control principles
27- Apply SOLID principles and clean architecture patterns
28- Structure by domain boundaries in clear modules
29
30### Async/Await Best Practices
31
32**Consistent Usage:**
33- Use async/await consistently throughout codebase
34- Handle promises properly with try/catch blocks
35- Implement proper error boundaries and graceful degradation
36- Apply error handling at appropriate abstraction levels
37
38## NestJS Development Guidelines
39
40### Service Architecture
41
42**Controller and Service Separation:**
43- Keep controllers lean, delegate business logic to services
44- Follow SOLID principles, especially Single Responsibility
45- Use constructor injection for all dependencies
46- Implement interfaces for repositories and external services
47
48**Example Implementation:**
49```typescript
50// ✅ Good - Single Responsibility
51@Controller('users')
52export class UsersController {
53 constructor(private readonly userService: UserService) {}
54
55 @Post()
56 async create(@Body() dto: CreateUserDto) {
57 return this.userService.create(dto);
58 }
59}
60
61@Injectable()
62export class UserService {
63 constructor(private readonly userRepository: IUserRepository) {}
64
65 async create(dto: CreateUserDto) {
66 return this.userRepository.create(dto);
67 }
68}
69
70// ✅ Good - Dependency Inversion
71@Module({
72 providers: [
73 { provide: 'UserRepository', useClass: TypeOrmUserRepository }
74 ],
75})
76export class UsersModule {}
77```
78
79### Dependency Injection
80
81**Best Practices:**
82- Always use constructor injection
83- Inject interfaces, not concrete implementations
84- Define clear provider tokens for dependency resolution
85- Use custom providers for complex dependency scenarios
86
87## TypeORM Patterns
88
89### Entity-First Design
90
91**Schema Definition:**
92- Drive database schema through TypeORM entities
93- Use decorators for columns, relationships, and constraints
94- Implement entity lifecycle hooks (BeforeInsert, BeforeUpdate) for validation
95
96**Example:**
97```typescript
98@Entity('users')
99export class UserEntity {
100 @PrimaryGeneratedColumn('uuid')
101 id: string;
102
103 @Column()
104 email: string;
105
106 @BeforeInsert()
107 @BeforeUpdate()
108 validateData() {
109 // Validation logic here
110 if (!this.email.includes('@')) {
111 throw new Error('Invalid email');
112 }
113 }
114}
115```
116
117### Repository Pattern
118
119**Data Access Encapsulation:**
120- Create custom repositories for complex queries
121- Encapsulate data access logic
122- Use query builders for type-safe dynamic queries
123
124**Example:**
125```typescript
126@Injectable()
127export class CustomUserRepository extends Repository<UserEntity> {
128 async findActiveUsers(): Promise<UserEntity[]> {
129 return this.createQueryBuilder('user')
130 .where('user.isActive = :isActive', { isActive: true })
131 .orderBy('user.createdAt', 'DESC')
132 .getMany();
133 }
134}
135```
136
137## Performance Optimization
138
139### Async Operation Parallelization
140
141**Critical Pattern:**
142When multiple independent async operations can run concurrently, use `Promise.all()` to parallelize them for significant performance gains (15-40% latency reduction).
143
144**Example:**
145```typescript
146// ✅ Good - Parallelized independent operations (~40% faster)
147async searchByAccount(account: Account): Promise<ContactData[]> {
148 const startTime = Date.now();
149
150 // Parallelize independent operations that don't depend on each other
151 const [domainResult, keywordsResult] = await Promise.all([
152 // Operation 1: Domain lookup
153 this.domainService.findDomain(account.domain).then(result => {
154 this.logger.log(`Domain lookup completed in ${Date.now() - startTime}ms`);
155 return result;
156 }),
157
158 // Operation 2: Keywords generation
159 this.keywordService.generateKeywords(account).then(result => {
160 this.logger.log(`Keywords generation completed in ${Date.now() - startTime}ms`);
161 return result;
162 })
163 ]);
164
165 // Use results for subsequent operations
166 return this.processContactData(domainResult, keywordsResult);
167}
168
169// ❌ Bad - Sequential operations (unnecessary wait time)
170async searchByAccount(account: Account): Promise<ContactData[]> {
171 const domainResult = await this.domainService.findDomain(account.domain);
172 const keywordsResult = await this.keywordService.generateKeywords(account);
173
174 return this.processContactData(domainResult, keywordsResult);
175}
176```
177
178**Key Benefits:**
179- 15-40% latency reduction for independent operations
180- Better resource utilization
181- Improved user experience with faster responses
182- Reduced total execution time
183
184### Performance Monitoring Integration
185
186**Comprehensive Metrics:**
187Always measure and monitor performance improvements with proper metrics.
188
189```typescript
190// ✅ Good - Comprehensive timing metrics for parallel operations
191async getInitialContactData(params: SearchParams): Promise<ContactData> {
192 const overallStart = Date.now();
193 const salesforceStart = Date.now();
194 const providerStart = Date.now();
195
196 const [salesforceContacts, providerContacts] = await Promise.all([
197 this.salesforceService.searchContacts(params).then(result => {
198 this.metricsService.gauge('salesforce_search.latency', Date.now() - salesforceStart);
199 return result;
200 }),
201
202 this.providerService.searchContacts(params).then(result => {
203 this.metricsService.gauge('provider_search.latency', Date.now() - providerStart);
204 return result;
205 })
206 ]);
207
208 this.metricsService.gauge('parallel_contact_search.latency', Date.now() - overallStart);
209
210 return this.mergeContactData(salesforceContacts, providerContacts);
211}
212
213// Track performance improvement metrics
214this.metricsService.histogram('contact_discovery.latency_reduction', reductionPercentage);
215```
216
217### Performance Optimization Decision Matrix
218
219| Scenario | Optimization Technique | Expected Improvement |
220|----------|------------------------|---------------------|
221| Independent async operations | `Promise.all()` parallelization | 15-40% latency reduction |
222| Sequential API calls | Concurrent requests with error handling | 20-50% improvement |
223| Heavy computations | Caching with Redis/in-memory | Variable based on computation |
224| Large data sets | Pagination, lazy loading | Dramatic API responsiveness |
225| External service calls | Request deduplication, intelligent caching | Reduces redundant network calls |
226| Database queries | Indexing, query optimization, connection pool | 50-90% query time reduction |
227
228**Key Insight:** Always analyze operation dependencies before optimization - independent operations are prime candidates for parallelization.
229
230### Database Optimization
231
232**Query Performance:**
233- Implement proper database indexing
234- Optimize database queries with query builders
235- Use connection pooling and manage connections efficiently
236- Apply proper database migrations and seeding strategies
237
238**Connection Management:**
239- Configure connection pooling appropriately
240- Monitor connection usage and leaks
241- Implement proper connection lifecycle management
242- Use read replicas for read-heavy operations
243
244## API Development
245
246### RESTful API Design
247
248**Best Practices:**
249- Follow REST API design principles
250- Use proper HTTP status codes (200, 201, 400, 401, 404, 500, etc.)
251- Implement proper request validation and sanitization
252- Follow semantic versioning for API endpoints
253
254### Error Handling
255
256**Comprehensive Strategy:**
257- Set up comprehensive error handling with custom error classes
258- Use proper HTTP status codes for different error types
259- Implement proper error boundaries
260- Provide meaningful error messages without exposing sensitive information
261
262### Request Validation
263
264**Input Sanitization:**
265- Implement proper request validation at controller level
266- Use DTOs (Data Transfer Objects) with class-validator
267- Sanitize user inputs to prevent injection attacks
268- Validate both structure and content of requests
269
270## Security Best Practices
271
272### Authentication & Authorization
273
274**Implementation:**
275- Implement JWT, OAuth, or session-based auth
276- Apply proper security measures for token management
277- Use proper password hashing (bcrypt, argon2)
278- Implement role-based access control (RBAC)
279
280### Security Hardening
281
282**Essential Measures:**
283- Apply input validation and sanitization
284- Configure CORS properly
285- Use helmet middleware for security headers
286- Implement rate limiting and request throttling
287- Manage environment variables securely
288- Never commit secrets to version control
289
290## Logging & Monitoring
291
292### Structured Logging
293
294**Configuration:**
295- Configure structured logging with Winston or similar
296- Use proper logging levels (error, warn, info, debug)
297- Implement request/response logging
298- Include correlation IDs for distributed tracing
299
300### Observability
301
302**Health Checks:**
303- Implement health check endpoints
304- Monitor application metrics
305- Set up alerts for critical errors
306- Track performance metrics over time
307
308## Testing Strategy
309
310### Test Coverage
311
312**Comprehensive Testing:**
313- Write unit tests for business logic
314- Implement integration tests for API endpoints
315- Create E2E tests for critical user flows
316- Use Jest, Supertest, or similar frameworks
317- Aim for >80% code coverage for critical paths
318
319### Test Organization
320
321**Best Practices:**
322- Follow AAA pattern (Arrange, Act, Assert)
323- Mock external dependencies properly
324- Use test fixtures and factories
325- Keep tests isolated and independent
326
327## Deployment & DevOps
328
329### CI/CD Integration
330
331**Automation:**
332- Implement proper CI/CD pipelines
333- Automate testing and deployment
334- Use environment-based configuration management
335- Implement blue-green or canary deployments
336
337### Documentation
338
339**API Documentation:**
340- Create API documentation with Swagger/OpenAPI
341- Maintain comprehensive README files
342- Document environment variables and configuration
343- Provide setup and deployment instructions
344
345## Implementation Workflow
346
347When applying this skill to backend development tasks:
348
3491. **Project Analysis**: Assess current backend structure, dependencies, and architecture patterns
3502. **Architecture Design**: Plan layered architecture with proper separation of concerns
3513. **Database Integration**: Implement database connections with proper ORM/ODM setup
3524. **API Development**: Create APIs with proper routing, middleware, and validation
3535. **Security Implementation**: Apply authentication, authorization, and security hardening
3546. **Performance Optimization**: Implement caching, parallelization, and query optimization
3557. **Testing**: Write comprehensive unit, integration, and E2E tests
3568. **Logging & Monitoring**: Configure structured logging and observability features
3579. **Documentation**: Create API docs and maintain README files
358
359## Common Anti-Patterns to Avoid
360
361**Architecture:**
362- ❌ Fat controllers with business logic
363- ❌ Direct database access from controllers
364- ❌ Circular dependencies between modules
365- ❌ Missing dependency injection
366
367**Performance:**
368- ❌ Sequential execution of independent async operations
369- ❌ Missing database indexes on frequently queried columns
370- ❌ No connection pooling
371- ❌ Missing caching for expensive operations
372
373**Security:**
374- ❌ Storing passwords in plain text
375- ❌ Missing input validation
376- ❌ Exposing sensitive data in error messages
377- ❌ Hardcoded secrets in code
378
379**Error Handling:**
380- ❌ Swallowing errors silently
381- ❌ Generic error messages that don't help debugging
382- ❌ Missing try/catch blocks for async operations
383- ❌ Improper HTTP status codes