NestJS microservices development. Use when creating controllers, services, modules, guards, interceptors, or working with NestJS patterns in auth, order, or product services.
This project uses NestJS for three microservices:
apps/auth - Authentication (JWT, Passport)apps/order - Order management (integrates with Temporal)apps/product - Product catalogShared modules are in packages/core.
// feature/feature.module.ts
import { Module } from '@nestjs/common';
import { FeatureController } from './feature.controller';
import { FeatureService } from './feature.service';
@Module({
controllers: [FeatureController],
providers: [FeatureService],
exports: [FeatureService],
})
export class FeatureModule {}
// feature/feature.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from '@projectx/db';
@Injectable()
export class FeatureService {
constructor(private readonly prisma: PrismaService) {}
async findAll() {
return this.prisma.feature.findMany();
}
async findOne(id: string) {
return this.prisma.feature.findUnique({ where: { id } });
}
async create(data: CreateFeatureDto) {
return this.prisma.feature.create({ data });
}
}
// feature/feature.controller.ts
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { FeatureService } from './feature.service';
@ApiTags('features')
@Controller('features')
export class FeatureController {
constructor(private readonly featureService: FeatureService) {}
@Get()
@ApiOperation({ summary: 'Get all features' })
@ApiResponse({ status: 200, description: 'Returns all features' })
findAll() {
return this.featureService.findAll();
}
@Get(':id')
@ApiOperation({ summary: 'Get feature by ID' })
findOne(@Param('id') id: string) {
return this.featureService.findOne(id);
}
@Post()
@ApiOperation({ summary: 'Create a feature' })
create(@Body() createFeatureDto: CreateFeatureDto) {
return this.featureService.create(createFeatureDto);
}
}
// feature/dto/create-feature.dto.ts
import { IsString, IsNotEmpty, IsOptional } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
export class CreateFeatureDto {
@ApiProperty({ description: 'Feature name' })
@IsString()
@IsNotEmpty()
name: string;
@ApiPropertyOptional({ description: 'Feature description' })
@IsString()
@IsOptional()
description?: string;
}
Use guards from @projectx/core:
import { UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from '@projectx/core';
@Controller('protected')
@UseGuards(JwtAuthGuard)
export class ProtectedController {
// All routes require authentication
}
import { NotFoundException, BadRequestException } from '@nestjs/common';
// In service
async findOne(id: string) {
const item = await this.prisma.feature.findUnique({ where: { id } });
if (!item) {
throw new NotFoundException(`Feature with ID ${id} not found`);
}
return item;
}
import { Test, TestingModule } from '@nestjs/testing';
import { FeatureService } from './feature.service';
import { PrismaService } from '@projectx/db';
describe('FeatureService', () => {
let service: FeatureService;
let prisma: PrismaService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
FeatureService,
{
provide: PrismaService,
useValue: {
feature: {
findMany: jest.fn(),
findUnique: jest.fn(),
create: jest.fn(),
},
},
},
],
}).compile();
service = module.get<FeatureService>(FeatureService);
prisma = module.get<PrismaService>(PrismaService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
# Run specific service
pnpm dev:auth
pnpm dev:order
pnpm dev:product
# Run all services
pnpm dev
@projectx/db@projectx/core for authenticationSearch for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer