import { EventEmitter2 } from '@nestjs/event-emitter'; import { AggregateRoot, Mapper, RepositoryPort } from '../ddd'; import { ObjectLiteral } from '../types'; import { LoggerPort } from '../ports/logger.port'; import { None, Option, Some } from 'oxide.ts'; import { PrismaRawRepositoryPort, PrismaRepositoryPort, } from '../ports/prisma-repository.port'; import { Prisma } from '@prisma/client'; import { ConflictException, DatabaseErrorException } from '@libs/exceptions'; export abstract class PrismaRepositoryBase< Aggregate extends AggregateRoot, DbReadModel extends ObjectLiteral, DbWriteModel extends ObjectLiteral, > implements RepositoryPort { protected constructor( protected readonly prisma: PrismaRepositoryPort | any, protected readonly prismaRaw: PrismaRawRepositoryPort, protected readonly mapper: Mapper, protected readonly eventEmitter: EventEmitter2, protected readonly logger: LoggerPort, ) {} async findOneById(id: string, include?: any): Promise> { const entity = await this.prisma.findUnique({ where: { uuid: id }, include, }); return entity ? Some(this.mapper.toDomain(entity)) : None; } async insert(entity: Aggregate): Promise { try { await this.prisma.create({ data: this.mapper.toPersistence(entity), }); } catch (e) { if (e instanceof Prisma.PrismaClientKnownRequestError) { if (e.message.includes('Already exists')) { throw new ConflictException('Record already exists', e); } } throw e; } } async healthCheck(): Promise { try { await this.prisma.$queryRaw`SELECT 1`; return true; } catch (e) { console.log(e); if (e instanceof Prisma.PrismaClientKnownRequestError) { throw new DatabaseErrorException(e.message); } throw new DatabaseErrorException(); } } }