PrismaService에 트랜잭션 기반 시드 추가, 또는 NestJS CLI 커맨드로 실행하는 방법도 확장해주시고. 그리고 seed.ts에 타입 안전성과 트랜잭션까지 적용된 버전도 만들어주시고, .env 설정 자동 전환 스크립트도 추가해 주세요.
응답:
1. PrismaService에 트랜잭션 기반 시드 지원 추가
🔹 prisma.service.ts 확장
// src/prisma/prisma.service.ts
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
async onModuleInit() {
await this.$connect();
}
async enableShutdownHooks() {
process.on('beforeExit', async () => {
await this.$disconnect();
});
}
async transaction<T>(callback: (prisma: PrismaClient) => Promise<T>): Promise<T> {
return this.$transaction(async (tx) => {
return callback(tx);
});
}
async onModuleDestroy() {
await this.$disconnect();
}
}
🔸 이제 PrismaService.transaction() 메서드로 안전한 트랜잭션 실행 가능
2. 타입 안전성 + 트랜잭션 적용된 seed.ts
// prisma/seed/seed.ts
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function seedData(prisma: PrismaClient) {
// 타입 자동 인식 가능
const user = await prisma.user.upsert({
where: { email: 'test@example.com' },
update: {},
create: {
email: 'test@example.com',
name: 'Test User',
},
});
console.log('Seeded user:', user);
}
export async function seed(prisma?: PrismaClient) {
const client = prisma ?? new PrismaClient();
await client.$transaction(async (tx) => {
await seedData(tx);
});
if (!prisma) await client.$disconnect();
}
if (require.main === module) {
// CLI로 직접 실행될 때
seed()
.then(() => console.log('✅ Seeding complete'))
.catch((e) => {
console.error(e);
process.exit(1);
});
}
3. NestJS CLI 명령으로 시드 실행하기
🔹 별도 커맨드 파일 생성
// scripts/seed.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from '../src/app.module';
import { PrismaService } from '../src/prisma/prisma.service';
import { seed } from '../prisma/seed/seed';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const prisma = app.get(PrismaService);
await prisma.enableShutdownHooks();
console.log('🌱 Starting seed...');
await seed(prisma);
console.log('✅ Seed completed!');
await app.close();
}
bootstrap();
🔹 package.json 스크립트에 등록
"scripts": {
"start:dev": "nest start --watch",
"seed": "ts-node scripts/seed.ts"
}
npm run seed
4. .env 자동 전환 스크립트
🔹 scripts/set-env.ts 추가
// scripts/set-env.ts
import { writeFileSync } from 'fs';
const env = process.argv[2] || 'development';
const envFile = `.env.${env}`;
const target = '.env';
try {
const content = require('fs').readFileSync(envFile);
writeFileSync(target, content);
console.log(`🔄 Switched to ${envFile}`);
} catch (e) {
console.error(`❌ Failed to switch to ${envFile}`);
}
🔹 package.json에 명령어 추가
"scripts": {
"env:dev": "ts-node scripts/set-env.ts development",
"env:prod": "ts-node scripts/set-env.ts production"
}
🔹 사용 예시
npm run env:dev # .env 파일을 .env.development 내용으로 대체
npm run env:prod # .env 파일을 .env.production 내용으로 대체
정리된 디렉토리 구조 예시
/prisma
├─ schema.prisma
├─ seed/
│ ├─ seed.ts
│ └─ data.ts
/scripts
├─ seed.ts # NestJS CLI 기반 시드
└─ set-env.ts # .env 자동 전환
/src/prisma
├─ prisma.module.ts
└─ prisma.service.ts