import { Injectable } from "@nestjs/common"; import type { Prisma } from "@prisma/client"; import { cvMapper } from "@/modules/cv-template/cv.mapper"; import { VacancyMapper } from "@/modules/vacancies/vacancy.mapper"; import { Application, type ApplicationStatusRelation, } from "./application.entity"; type PrismaApplicationWithRelations = Prisma.ApplicationGetPayload<{ include: { user: true; status: true; vacancy: { include: { company: true; role: true; level: true; jobType: true; skills: true; }; }; cv: { include: { template: true; }; }; }; }>; @Injectable() export class ApplicationMapper { constructor(private readonly vacancyMapper: VacancyMapper) {} toDomain( prismaApplication: PrismaApplicationWithRelations | null, ): Application | null { if (!prismaApplication) { return null; } const status: ApplicationStatusRelation = { id: prismaApplication.status.id, name: prismaApplication.status.name, description: prismaApplication.status.description, createdAt: prismaApplication.status.createdAt, updatedAt: prismaApplication.status.updatedAt, }; const vacancy = this.vacancyMapper.toDomain(prismaApplication.vacancy); if (!vacancy) { throw new Error("Vacancy is required for Application"); } const cv = prismaApplication.cv ? cvMapper.toDomain(prismaApplication.cv) : null; return new Application( prismaApplication.id, prismaApplication.userId, prismaApplication.profileId, vacancy, prismaApplication.statusId, status, prismaApplication.appliedAt, prismaApplication.createdAt, prismaApplication.updatedAt, cv, prismaApplication.coverLetter ?? undefined, ); } mapToDomainWithRelations( prismaApplications: PrismaApplicationWithRelations[], ): Application[] { return prismaApplications .map((application) => this.toDomain(application)) .filter( (application): application is Application => application !== null, ); } }