pandektes-challenge/src/cases/cases.service.ts
2026-03-01 14:01:15 +01:00

69 lines
2.2 KiB
TypeScript

import { Injectable, NotFoundException, BadRequestException, Logger, Inject } from '@nestjs/common';
import { PRISMA_CLIENT, type PrismaClientInstance } from '@app/common/prisma/prisma.service';
import { isUuid } from '@app/common/utils/string.utils';
import { Queue } from 'bullmq';
import { StorageService } from '@app/common/storage/storage.service';
import { InjectQueue } from '@nestjs/bullmq';
import { CaseStatus } from '../generated/prisma/client.js';
@Injectable()
export class CasesService {
private readonly logger = new Logger(CasesService.name);
constructor(
@Inject(PRISMA_CLIENT) private prisma: PrismaClientInstance,
private storage: StorageService,
@InjectQueue('case-processing') private caseQueue: Queue,
) {}
async processAndSave(buffer: Buffer, mimetype: string, filename: string) {
this.logger.log(`Upload received: ${filename} (${mimetype}, ${(buffer.length / 1024).toFixed(1)} KB)`);
const storageKey = await this.storage.upload(buffer, filename, mimetype);
const fileType = mimetype === 'application/pdf' ? 'PDF' : 'HTML';
const caseLaw = await this.prisma.caseLaw.create({
data: {
title: `Processing: ${filename}`,
fileType,
storageKey,
status: CaseStatus.PENDING,
},
});
const workerDownloadUrl = await this.storage.getPresignedUrl(storageKey);
await this.caseQueue.add('parse-case', {
caseId: caseLaw.id,
downloadUrl: workerDownloadUrl,
mimetype,
});
return caseLaw;
}
async findOne(id?: string, caseNumber?: string) {
if (!id && !caseNumber) throw new BadRequestException('Provide ID or Case Number');
const caseLaw = await this.prisma.caseLaw.findFirst({
where: {
OR: [
id && isUuid(id) ? { id } : undefined,
caseNumber ? { caseNumber } : undefined,
].filter(Boolean) as any,
},
});
if (!caseLaw) throw new NotFoundException('Case not found');
return caseLaw;
}
async findAll(status?: CaseStatus, take = 20, skip = 0) {
return this.prisma.caseLaw.findMany({
where: status ? { status } : undefined,
orderBy: { createdAt: 'desc' },
take: Math.min(take, 100),
skip,
});
}
}