Loading...
Loading...
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.
npx skill4agent add vong3432/vibemark nestjs-typeorm-integrationnestjs-project-scaffoldnestjs-modules-services-controllersnestjs-authenticationCLAUDE.mdTypeOrmModule@nestjs/config.envsrc/modules/<feature>/entitiessrc/entitiessrc/migrationsmigrationsproject-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.tsTypeOrmModuleAppModuleDatabaseModule@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 {}synchronize: falseautoLoadEntities: true.env.env.exampleDB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_NAME=app_db// 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;
}// 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;
}uuidonDeleteeagerlazyTypeOrmModule.forFeature// 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 {}UserService// 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<User>,
) {}
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...
}synchronizedata-source.ts// 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}"],
});{
"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"
}
}migration:generateQueryRunnermanager.transactionimport { 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;
});
}
}selectgetRepositorysynchronize: trueTypeOrmModuleRepository<T>DataSourcenestjs-project-scaffoldnestjs-modules-services-controllersnestjs-authenticationtypeorm-schema-designtypeorm-migrations-workflow