Agent Skills

nestjs

Provides comprehensive NestJS framework patterns with Drizzle ORM integration for building scalable server-side applications. Generates REST/GraphQL APIs, implements authentication guards, creates database schemas, and sets up microservices. Use when building NestJS applications, setting up APIs, implementing authentication, working with databases, or integrating Drizzle ORM.

Install

npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill nestjs
SKILL.md

NestJS Framework with Drizzle ORM

Overview

Provides NestJS patterns with Drizzle ORM for building production-ready server-side applications. Covers CRUD modules, JWT authentication, database operations, migrations, testing, microservices, and GraphQL integration.

When to Use

  • Building REST APIs or GraphQL servers with NestJS
  • Setting up authentication and authorization with JWT
  • Implementing database operations with Drizzle ORM
  • Creating microservices with TCP/Redis transport
  • Writing unit and integration tests
  • Running database migrations with drizzle-kit

Instructions

  1. Install dependencies: npm i drizzle-orm pg && npm i -D drizzle-kit tsx
  2. Define schema: Create src/db/schema.ts with Drizzle table definitions
  3. Create DatabaseService: Inject Drizzle client as a NestJS provider
  4. Build CRUD module: Controller → Service → Repository pattern
  5. Add validation: Use class-validator DTOs with ValidationPipe
  6. Implement guards: Create JWT/Roles guards for route protection
  7. Write tests: Use @nestjs/testing with mocked repositories
  8. Run migrations: npx drizzle-kit generate → Verify SQL → npx drizzle-kit migrate

Examples

Complete CRUD Module with Drizzle

// src/db/schema.ts
export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  createdAt: timestamp('created_at').defaultNow(),
});

// src/users/dto/create-user.dto.ts
export class CreateUserDto {
  @IsString() @IsNotEmpty() name: string;
  @IsEmail() email: string;
}

// src/users/user.repository.ts
@Injectable()
export class UserRepository {
  constructor(private db: DatabaseService) {}

  async findAll() {
    return this.db.database.select().from(users);
  }

  async create(data: typeof users.$inferInsert) {
    return this.db.database.insert(users).values(data).returning();
  }
}

// src/users/users.service.ts
@Injectable()
export class UsersService {
  constructor(private repo: UserRepository) {}

  async create(dto: CreateUserDto) {
    return this.repo.create(dto);
  }
}

// src/users/users.controller.ts
@Controller('users')
export class UsersController {
  constructor(private service: UsersService) {}

  @Post()
  create(@Body() dto: CreateUserDto) {
    return this.service.create(dto);
  }
}

// src/users/users.module.ts
@Module({
  controllers: [UsersController],
  providers: [UsersService, UserRepository, DatabaseService],
  exports: [UsersService],
})
export class UsersModule {}

JWT Authentication Guard

@Injectable()
export class JwtAuthGuard implements CanActivate {
  constructor(private jwtService: JwtService) {}

  canActivate(context: ExecutionContext) {
    const token = context.switchToHttp().getRequest()
      .headers.authorization?.split(' ')[1];
    if (!token) return false;
    try {
      const decoded = this.jwtService.verify(token);
      context.switchToHttp().getRequest().user = decoded;
      return true;
    } catch {
      return false;
    }
  }
}

Database Transactions

async transferFunds(fromId: number, toId: number, amount: number) {
  return this.db.database.transaction(async (tx) => {
    await tx.update(accounts)
      .set({ balance: sql`${accounts.balance} - ${amount}` })
      .where(eq(accounts.id, fromId));
    await tx.update(accounts)
      .set({ balance: sql`${accounts.balance} + ${amount}` })
      .where(eq(accounts.id, toId));
  });
}

Unit Testing with Mocks

describe('UsersService', () => {
  let service: UsersService;
  let repo: jest.Mocked<UserRepository>;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [
        UsersService,
        { provide: UserRepository, useValue: { findAll: jest.fn(), create: jest.fn() } },
      ],
    }).compile();
    service = module.get(UsersService);
    repo = module.get(UserRepository);
  });

  it('should create user', async () => {
    const dto = { name: 'John', email: 'john@example.com' };
    repo.create.mockResolvedValue({ id: 1, ...dto, createdAt: new Date() });
    expect(await service.create(dto)).toMatchObject(dto);
  });
});

Constraints and Warnings

  • DTOs required: Always use DTOs with class-validator, never accept raw objects
  • Transactions: Keep transactions short; avoid nested transactions
  • Guards order: JWT guard must run before Roles guard
  • Environment variables: Never hardcode DATABASE_URL or JWT_SECRET
  • Migrations: Run drizzle-kit generate after schema changes before deploying
  • Circular dependencies: Use forwardRef() carefully; prefer module restructuring

Best Practices

  • Validate all inputs with global ValidationPipe
  • Use transactions for multi-table operations
  • Document APIs with OpenAPI/Swagger decorators

References

Advanced patterns and detailed examples available in:

  • references/reference.md - Core patterns, guards, interceptors, microservices, GraphQL
  • references/drizzle-reference.md - Drizzle ORM installation, configuration, queries
  • references/workflow-optimization.md - Development workflows, parallel execution strategies

Related skills

entra-app-registrationmicrosoft606KGuides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.azure-messagingmicrosoft595KTroubleshoot and resolve issues with Azure Messaging SDKs for Event Hubs and Service Bus. Covers connection failures, authentication errors, message processing issues, and SDK configuration problems. WHEN: event hub SDK error, service bus SDK issue, messaging connection failure, AMQP error, event processor host issue, message lock lost, message lock expired, lock renewal, lock renewal batch, send timeout, receiver disconnected, SDK troubleshooting, azure messaging SDK, event hub consumer, servicentra-agent-idmicrosoft328KProvision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmi_path, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmi_path token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registsupabasesupabase298KUse when doing ANY task involving Supabase. Triggers: Supabase products (Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues); client libraries and SSR integrations (supabase-js, @supabase/ssr) in Next.js, React, SvelteKit, Astro, Remix; auth issues (login, logout, sessions, JWT, cookies, getSession, getUser, getClaims, RLS); Supabase CLI or MCP server; schema changes, migrations, declarative schemas, security audits, Postgres extensions (pg_graphql, pg_cron, pg_vector); deb

Search skills and MCP servers

Fuzzy search across 23,137 skills and servers