prisma-nestjs-patterns について
Clean Architecture に沿って Prisma と NestJS を統合する開発者向けのガイドです。セットアップ、リポジトリ、トランザクション、クエリ最適化、テストを分野別の資料で扱います。
主な機能
- 01NestJS での Prisma 設定
- 02Clean Architecture のリポジトリパターン
- 03アトミックトランザクションと並行処理
- 04クエリ最適化と N+1 防止
- 05単体・統合テストのガイド
活用シーン
- 01NestJS プロジェクトへの Prisma 導入
- 02スキーマ設計とマイグレーション作成
- 03予約などの並行書き込み処理
- 04クエリ最適化や Prisma コードのテスト
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ davidcastagnetoa/ skills --skill prisma-nestjs-patternsインストール後、Claude Code で/prisma-nestjs-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/query-patterns.mdrepository-pattern.mdschema-and-migrations.mdsetup-and-service.mdtesting.mdtransactions.md詳細
Prisma ORM + NestJS — 本番環境向けパターン
Clean Architecture に沿った、Prisma と NestJS の包括的な統合ガイドです。基本設定から、重要なアトミックトランザクション、リポジトリ、クエリの最適化、テストまでを扱います。
利用可能な参考資料
特定の分野について詳しく知りたい場合は、該当するファイルを参照してください。
references/setup-and-service.md— インストール、PrismaService、グローバルモジュール、ヘルスチェックreferences/schema-and-migrations.md— スキーマ設計、型、リレーション、インデックス、マイグレーションreferences/repository-pattern.md— インフラストラクチャ層のアダプターとしてのリポジトリ(Clean Architecture)references/transactions.md— アトミックトランザクション、SELECT FOR UPDATE、同時実行の処理references/query-patterns.md— N+1 の防止、include/select、ページネーション、複雑なクエリreferences/testing.md— jest-mock-extended、prisma-mock を使ったテスト、testcontainers との統合
各参考資料を使う場面
| 作業 | 参考資料 |
|---|---|
| NestJS で初めて Prisma を設定する | setup-and-service.md |
| スキーマを設計または変更する、マイグレーションを作成する | schema-and-migrations.md |
| ドメインモジュール用のリポジトリを作成する | repository-pattern.md |
| 予約、ロック、同時実行操作 | transactions.md |
| 遅いクエリを最適化する、N+1 を解消する | query-patterns.md |
| 単体テスト/統合テストで Prisma をモックする | testing.md |
重要なルール(常に守ること)
1. PrismaService はグローバルにし、PrismaClient を直接インスタンス化しない
// ❌ Nunca
const prisma = new PrismaClient();
// ✅ Siempre via inyección de dependencias
constructor(private readonly prisma: PrismaService) {}
2. 複合的な書き込み操作にはアトミックトランザクションを使う
// ✅ Patrón correcto para cualquier operación que modifique >1 tabla
await this.prisma.$transaction(async (tx) => {
const gift = await tx.gift.findUnique({ where: { id: giftId } });
if (gift.status !== 'AVAILABLE') throw new ConflictException();
await tx.gift.update({ where: { id: giftId }, data: { status: 'RESERVED' } });
await tx.reservation.create({ data: { giftId, reservedById: userId } });
});
3. リポジトリはインフラストラクチャ層に置き、コントローラーやドメインサービスには置かない
// La interfaz vive en el dominio
export interface ReservationRepository {
findActiveByGiftId(giftId: string): Promise<Reservation | null>;
create(data: CreateReservationData): Promise<Reservation>;
}
// La implementación Prisma vive en infraestructura
@Injectable()
export class PrismaReservationRepository implements ReservationRepository { ... }
4. PrismaClient をインフラストラクチャモジュールの外部に公開しない
ドメイン層とアプリケーション層は、Prisma ではなくインターフェースを介して処理します。
5. 常に明示的な select または include を使い、モデル全体を返さない
// ❌ Retorna passwordHash, campos internos
return this.prisma.user.findUnique({ where: { id } });
// ✅ Solo los campos necesarios
return this.prisma.user.findUnique({
where: { id },
select: { id: true, nombre: true, email: true, createdAt: true }
});
公式の情報源とドキュメント
- Prisma Docs — NestJS Integration: https://www.prisma.io/docs/guides/other/nestjs
- Prisma Docs — Transactions: https://www.prisma.io/docs/orm/prisma-client/queries/transactions
- Prisma Docs — Interactive Transactions: https://www.prisma.io/docs/orm/prisma-client/queries/transactions#interactive-transactions
- Prisma Docs — Select/Include: https://www.prisma.io/docs/orm/prisma-client/queries/select-fields
- Prisma Docs — Relation Queries: https://www.prisma.io/docs/orm/prisma-client/queries/relation-queries
- Prisma Docs — Migrations: https://www.prisma.io/docs/orm/prisma-migrate
- NestJS Docs — Database: https://docs.nestjs.com/techniques/database
- Prisma Blog — NestJS Best Practices: https://www.prisma.io/blog/nestjs-prisma-rest-api-7D056s1BmOL0
- jest-mock-extended: https://github.com/marchaos/jest-mock-extended
コメント
Markdown 対応