import { BadRequestException, Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { ActiveUserPayload } from '../auth/decorator/current-user.decorator'; import { RekammedisService } from '../rekammedis/rekammedis.service'; import { CreateRekamMedisDto } from '../rekammedis/dto/create-rekammedis.dto'; @Injectable() export class ValidationService { constructor( private prisma: PrismaService, private rekamMedisService: RekammedisService, ) {} private handlers: Record< string, { approveCreate?: (queue: any) => Promise; approveUpdate?: (queue: any) => Promise; approveDelete?: (queue: any) => Promise; } > = { rekam_medis: { approveCreate: async (queue: any) => { const payload = queue.dataPayload as Partial; const result = await this.rekamMedisService.createRekamMedisToDBAndBlockchain( payload as CreateRekamMedisDto, Number(queue.user_id_request), ); return { ...result, id: result.id_visit, }; }, approveUpdate: async (queue: any) => { const payload = queue.dataPayload as Partial; return this.rekamMedisService.updateRekamMedisToDBAndBlockchain( queue.record_id, payload as CreateRekamMedisDto, Number(queue.user_id_request), ); }, approveDelete: async (queue: any) => { return this.rekamMedisService.deleteRekamMedisFromDB(queue.record_id, { sub: queue.user_id_request.toString(), } as ActiveUserPayload); }, }, pemberian_tindakan: { approveCreate: async (queue: any) => { const payload = queue.dataPayload; console.log('Approving create for pemberian_tindakan:', payload); // return this.prisma.pemberian_tindakan.create({ // data: { // ...payload, // }, // }); }, }, pemberian_obat: {}, }; async getAllValidationsQueue() { const result = await this.prisma.validation_queue.findMany({ where: { status: 'PENDING' }, }); const totalCount = await this.prisma.validation_queue.count({ where: { status: 'PENDING' }, }); return { data: result, totalCount }; } async getAllValidationQueueDashboard() { const result = await this.prisma.validation_queue.findMany({ where: { status: 'PENDING' }, take: 5, orderBy: { created_at: 'desc' }, }); const totalCount = await this.prisma.validation_queue.count({ where: { status: 'PENDING' }, }); return { data: result, totalCount }; } // For service internal use async getValidationQueueById(id: number) { return await this.prisma.validation_queue.findUnique({ where: { id }, }); } // For front-end detail view async getValidationQueue(id: number) { const result = await this.getValidationQueueById(id); if (!result) return null; if (result.action !== 'UPDATE') return result; const previousLog = await this.fetchPreviousLog( result.table_name, result.record_id, ); return { previousLog, ...result }; } private async fetchPreviousLog(tableName: string, recordId: string) { if (!recordId) return null; switch (tableName) { case 'pemberian_tindakan': return this.prisma.pemberian_tindakan.findUnique({ where: { id: Number(recordId) }, }); case 'rekam_medis': return this.prisma.rekam_medis.findUnique({ where: { id_visit: recordId }, }); case 'pemberian_obat': return this.prisma.pemberian_obat.findUnique({ where: { id: Number(recordId) }, }); default: return null; } } private async approveWithHandler(queue: any) { const handler = this.handlers[queue.table_name]; if (!handler) throw new Error('Unsupported table'); switch (queue.action) { case 'CREATE': if (!handler.approveCreate) throw new Error('Create not implemented for table'); return handler.approveCreate(queue); case 'UPDATE': if (!handler.approveUpdate) throw new Error('Update not implemented for table'); return handler.approveUpdate(queue); case 'DELETE': if (!handler.approveDelete) throw new Error('Delete not implemented for table'); return handler.approveDelete(queue); default: throw new Error('Unknown action'); } } async approveValidation(id: number, user: ActiveUserPayload) { const validationQueue = await this.getValidationQueueById(id); if (!validationQueue) { throw new BadRequestException('Validation queue not found'); } if (!validationQueue.dataPayload) { throw new Error('Data payload is missing'); } try { const approvalResult = await this.approveWithHandler(validationQueue); console.log('Approval result:', approvalResult); const updated = await this.prisma.validation_queue.update({ where: { id: validationQueue.id }, data: { record_id: approvalResult.id, status: 'APPROVED', user_id_process: Number(user.sub), processed_at: new Date(), }, }); return { ...updated, approvalResult }; } catch (error) { console.error('Error approving validation:', (error as Error).message); throw error; } } async rejectValidation(id: number, user: ActiveUserPayload) { const validationQueue = await this.getValidationQueueById(id); if (!validationQueue) { throw new Error('Validation queue not found'); } const updated = await this.prisma.validation_queue.update({ where: { id: validationQueue.id }, data: { status: 'REJECTED', user_id_process: Number(user.sub), processed_at: new Date(), }, }); return updated; } }