NestJS architecture, dependency injection, validation, security, errors, testing, persistence, APIs, microservices, and deployment patterns with prioritized rule tiers and companion rule files.
99
100%
Does it follow best practices?
Impact
97%
1.12xAverage score across 2 eval scenarios
Advisory
Suggest reviewing before use
Each service should have a single, well-defined responsibility. Avoid "god services" that handle multiple unrelated concerns. If a service name includes "And" or handles more than one domain concept, it likely violates single responsibility. This reduces complexity and improves testability by 40%+.
Incorrect (god service anti-pattern):
// God service anti-pattern
@Injectable()
export class UserAndOrderService {
constructor(
private userRepo: UserRepository,
private orderRepo: OrderRepository,
private mailer: MailService,
private payment: PaymentService,
) {}
async createUser(dto: CreateUserDto) {
const user = await this.userRepo.save(dto);
await this.mailer.sendWelcome(user);
return user;
}
async createOrder(userId: string, dto: CreateOrderDto) {
const order = await this.orderRepo.save({ userId, ...dto });
await this.payment.charge(order);
await this.mailer.sendOrderConfirmation(order);
return order;
}
async calculateOrderStats(userId: string) {
// Stats logic mixed in
}
async validatePayment(orderId: string) {
// Payment logic mixed in
}
}Correct (focused services with single responsibility):
// Focused services with single responsibility
@Injectable()
export class UsersService {
constructor(private userRepo: UserRepository) {}
async create(dto: CreateUserDto): Promise<User> {
return this.userRepo.save(dto);
}
async findById(id: string): Promise<User> {
return this.userRepo.findOneOrFail({ where: { id } });
}
}
@Injectable()
export class OrdersService {
constructor(private orderRepo: OrderRepository) {}
async create(userId: string, dto: CreateOrderDto): Promise<Order> {
return this.orderRepo.save({ userId, ...dto });
}
async findByUser(userId: string): Promise<Order[]> {
return this.orderRepo.find({ where: { userId } });
}
}
@Injectable()
export class OrderStatsService {
constructor(private orderRepo: OrderRepository) {}
async calculateForUser(userId: string): Promise<OrderStats> {
// Focused stats calculation
}
}
// Orchestration in controller or dedicated orchestrator
@Controller('orders')
export class OrdersController {
constructor(
private orders: OrdersService,
private payment: PaymentService,
private notifications: NotificationService,
) {}
@Post()
async create(@CurrentUser() user: User, @Body() dto: CreateOrderDto) {
const order = await this.orders.create(user.id, dto);
await this.payment.charge(order);
await this.notifications.sendOrderConfirmation(order);
return order;
}
}Reference: NestJS Providers
evals
scenario-1
scenario-2
rules