🎁 Get the FREE AI Skills Starter GuideSubscribe →
BytesAgainBytesAgain
🦀 ClawHub

test2

by @theanswerss

Use this skill whenever the user wants to set up, configure, or refactor TypeORM within a NestJS TypeScript project, including data sources, entities, migrat...

Versionv1.0.0
Downloads267
TERMINAL
clawhub install tianchenwei3

📖 About This Skill


name: "nestjs-typeorm-integration" description: "Use this skill whenever the user wants to set up, configure, or refactor TypeORM within a NestJS TypeScript project, including data sources, entities, migrations, repositories, relations, and transactional patterns."

NestJS + TypeORM Integration Skill

Purpose

You are a specialized assistant for integrating TypeORM with NestJS in a clean, scalable, and production-friendly way.

Use this skill to:

  • Set up TypeORM in a NestJS project (data source, modules, config)
  • Define or refactor entities and their relations
  • Configure migrations and environment-specific DB settings
  • Wire repositories into services using Nest DI
  • Implement transactions and query patterns safely
  • Optimize DB usage (indexes, query patterns, relations loading) at a structural level
  • Do not use this skill for:

  • General NestJS module/service/controller scaffolding → use nestjs-project-scaffold / nestjs-modules-services-controllers
  • Authentication logic → use nestjs-authentication
  • Supabase-specific flows → use Supabase skills (unless Supabase Postgres is accessed via TypeORM as a plain DB)
  • If CLAUDE.md exists, follow its rules on database choice, naming conventions, and directory layout.


    When To Apply This Skill

    Trigger this skill when the user asks for things like:

  • “Set up TypeORM in this NestJS API.”
  • “Create entities and migrations for these tables in NestJS + TypeORM.”
  • “Wire repositories into my Nest services.”
  • “Fix or refactor our NestJS TypeORM config.”
  • “Add relations between these entities and update the service logic.”
  • “Handle transactions for this multi-step operation.”
  • Avoid using this skill when:

  • Only high-level REST API contracts are changing without DB impact.
  • Only pure in-memory logic is being implemented.

  • Assumptions & Defaults

    Unless the project states otherwise, assume:

  • Database: Postgres (can be adapted to MySQL, SQLite, etc.)
  • TypeORM version: current stable for NestJS
  • Connection is configured via Nest’s TypeOrmModule
  • Config is environment-driven via @nestjs/config and .env files
  • Entities live in src/modules//entities or src/entities depending on project style
  • Migrations live in src/migrations or migrations directory

  • High-Level Architecture

    Recommended structure (adapt as needed):

    project-root/
      src/
        config/
          database.config.ts
        modules/
          user/
            user.module.ts
            user.service.ts
            user.controller.ts
            entities/
              user.entity.ts
          post/
            post.module.ts
            post.service.ts
            post.controller.ts
            entities/
              post.entity.ts
        infrastructure/
          database/
            ormconfig.ts or data-source.ts (optional central place)
      migrations/
        1710000000000-CreateUserTable.ts
        1710000001000-CreatePostTable.ts
    

    This skill should align with the existing structure rather than forcing a totally new one, unless the project is greenfield.


    Step-by-Step Workflow

    When this skill is active, follow these steps:

    1. Set Up TypeORM Module Configuration

    If TypeORM is not configured yet:

  • Install TypeORM + DB driver for the chosen database.
  • Configure TypeOrmModule in AppModule or a dedicated DatabaseModule.
  • Example using @nestjs/config:

    // src/config/database.config.ts
    import { registerAs } from "@nestjs/config";

    export default registerAs("database", () => ({ type: "postgres", host: process.env.DB_HOST ?? "localhost", port: parseInt(process.env.DB_PORT ?? "5432", 10), username: process.env.DB_USERNAME ?? "postgres", password: process.env.DB_PASSWORD ?? "postgres", database: process.env.DB_NAME ?? "app_db", }));

    // src/app.module.ts
    import { Module } from "@nestjs/common";
    import { ConfigModule, ConfigService } from "@nestjs/config";
    import databaseConfig from "./config/database.config";
    import { TypeOrmModule } from "@nestjs/typeorm";

    @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, load: [databaseConfig], }), TypeOrmModule.forRootAsync({ inject: [ConfigService], useFactory: (config: ConfigService) => { const db = config.get("database"); return { ...db, autoLoadEntities: true, synchronize: false, // prefer migrations in production }; }, }), // feature modules... ], }) export class AppModule {}

    Key rules:

  • synchronize: false in all non-dev environments (this skill encourages migrations).
  • autoLoadEntities: true is acceptable for many apps; for stricter control, explicitly list entities.
  • 2. Environment Variables

    Ensure .env (and .env.example) contain:

    DB_HOST=localhost
    DB_PORT=5432
    DB_USERNAME=postgres
    DB_PASSWORD=postgres
    DB_NAME=app_db
    

    This skill should help keep secrets out of code and only in env/config.

    3. Entities Design

    For each feature, create entity classes:

    // src/modules/user/entities/user.entity.ts
    import {
      Column,
      CreateDateColumn,
      Entity,
      PrimaryGeneratedColumn,
      UpdateDateColumn,
    } from "typeorm";

    @Entity({ name: "users" }) export class User { @PrimaryGeneratedColumn("uuid") id!: string;

    @Column({ unique: true }) email!: string;

    @Column() passwordHash!: string;

    @Column({ default: true }) isActive!: boolean;

    @CreateDateColumn() createdAt!: Date;

    @UpdateDateColumn() updatedAt!: Date; }

    Relations example:

    // src/modules/post/entities/post.entity.ts
    import {
      Column,
      CreateDateColumn,
      Entity,
      ManyToOne,
      PrimaryGeneratedColumn,
    } from "typeorm";
    import { User } from "../../user/entities/user.entity";

    @Entity({ name: "posts" }) export class Post { @PrimaryGeneratedColumn("uuid") id!: string;

    @Column() title!: string;

    @Column({ type: "text" }) content!: string;

    @ManyToOne(() => User, (user) => user.posts, { onDelete: "CASCADE" }) author!: User;

    @CreateDateColumn() createdAt!: Date; }

    This skill should:

  • Encourage using uuid or bigint for IDs consistently (per project preference).
  • Use clear relation options (onDelete, eager, lazy) thoughtfully.
  • Avoid putting heavy business logic directly into entities.
  • 4. Module & Repository Wiring

    Use TypeOrmModule.forFeature to inject repositories into feature modules:

    // src/modules/user/user.module.ts
    import { Module } from "@nestjs/common";
    import { TypeOrmModule } from "@nestjs/typeorm";
    import { User } from "./entities/user.entity";
    import { UserService } from "./user.service";
    import { UserController } from "./user.controller";

    @Module({ imports: [TypeOrmModule.forFeature([User])], controllers: [UserController], providers: [UserService], exports: [UserService], }) export class UserModule {}

    In UserService, inject the repository:

    // src/modules/user/user.service.ts
    import { Injectable } from "@nestjs/common";
    import { InjectRepository } from "@nestjs/typeorm";
    import { Repository } from "typeorm";
    import { User } from "./entities/user.entity";
    import { CreateUserDto } from "./dto/create-user.dto";

    @Injectable() export class UserService { constructor( @InjectRepository(User) private readonly usersRepo: Repository, ) {}

    create(dto: CreateUserDto) { const entity = this.usersRepo.create({ email: dto.email, passwordHash: dto.passwordHash, }); return this.usersRepo.save(entity); }

    findAll() { return this.usersRepo.find(); }

    findOne(id: string) { return this.usersRepo.findOne({ where: { id } }); }

    // etc... }

    This skill should enforce:

  • Repositories are injected via DI, not instantiated manually.
  • Services depend on repositories, not on the data source directly (except in advanced scenarios).
  • 5. Migrations

    Encourage using migrations instead of synchronize for schema changes.

  • Create a data-source.ts file if needed for CLI migrations:
  • // data-source.ts (or src/infrastructure/database/data-source.ts)
    import "reflect-metadata";
    import { DataSource } from "typeorm";
    import databaseConfig from "./src/config/database.config";
    import { config as loadEnv } from "dotenv";

    loadEnv();

    const db = databaseConfig();

    export const AppDataSource = new DataSource({ type: "postgres", host: db.database.host, port: db.database.port, username: db.database.username, password: db.database.password, database: db.database.database, entities: ["src/**/*.entity.{ts,js}"], migrations: ["migrations/*.{ts,js}"], });

  • Add package.json scripts for migrations (exact form depends on project):
  • {
      "scripts": {
        "typeorm:run": "typeorm-ts-node-commonjs migration:run -d data-source.ts",
        "typeorm:revert": "typeorm-ts-node-commonjs migration:revert -d data-source.ts",
        "typeorm:generate": "typeorm-ts-node-commonjs migration:generate -d data-source.ts migrations/AutoMigration"
      }
    }
    

    This skill should:

  • Prefer explicit migration generation (migration:generate) over schema sync.
  • Keep migration files small, ordered, and committed to version control.
  • 6. Transactions & Complex Operations

    For operations that require multiple DB writes, this skill should:

  • Use QueryRunner or manager.transaction where needed.
  • Example:

    import { DataSource } from "typeorm";

    @Injectable() export class OrderService { constructor(private readonly dataSource: DataSource) {}

    async createOrderAndItems(dto: CreateOrderDto) { return this.dataSource.transaction(async (manager) => { const order = manager.create(Order, { /* ... */ }); await manager.save(order);

    const items = dto.items.map((itemDto) => manager.create(OrderItem, { order, // ... }), ); await manager.save(items);

    return order; }); } }

    Guidelines:

  • Use transactions only where needed; avoid wrapping everything by default.
  • Handle error propagation correctly; if the transaction throws, it rolls back.
  • 7. Performance & Query Patterns

    This skill should guide towards:

  • Using select and projections instead of always loading entire entities.
  • Avoiding N+1 queries with relation loading patterns when necessary.
  • Adding indexes in migrations for frequently queried columns.
  • Using pagination strategies (offset/limit or cursor-based) for large lists.
  • 8. Refactoring Existing TypeORM Usage

    When refactoring:

  • Identify anti-patterns:
  • - Manual connection creation (bypassing Nest DI) - Direct use of global getRepository instead of injected repositories - synchronize: true in production
  • Replace with:
  • - TypeOrmModule configuration - Injected Repository or DataSource - Migrations for schema changes

    This skill should try to minimize breaking changes while improving structure.


    Interaction with Other Skills

  • nestjs-project-scaffold:
  • - Provides the base Nest structure; this skill plugs DB configuration into it.
  • nestjs-modules-services-controllers:
  • - Uses modules/services; this skill adds entities + repositories behind those services.
  • nestjs-authentication:
  • - Depends on user entities and user repository; this skill provides that layer.
  • TypeORM-specific skills (typeorm-schema-design, typeorm-migrations-workflow):
  • - Can be used in addition for deeper DB design and migration strategies.


    Example Prompts That Should Use This Skill

  • “Connect this NestJS app to Postgres via TypeORM and create User & Post entities.”
  • “Refactor this hand-rolled DB code into proper TypeORM modules and services.”
  • “Add migrations for these schema changes and wire them into our NestJS project.”
  • “Implement a transactional operation that creates an order and its items.”
  • “Fix this TypeORM config; it works locally but fails in production.”
  • For such prompts, rely on this skill to design and implement NestJS + TypeORM integration that is robust, maintainable, and ready for production, while delegating non-DB concerns to other skills.