60 lines
2.3 KiB
TypeScript
60 lines
2.3 KiB
TypeScript
import { Resolver, Query, Mutation, Args, ID, Int, ResolveField, Parent } from '@nestjs/graphql';
|
|
import { GraphQLUpload } from 'graphql-upload-ts';
|
|
import type { FileUpload } from 'graphql-upload-ts';
|
|
import { CasesService } from './cases.service';
|
|
import { CaseLaw } from './entities/case-law.entity';
|
|
import { StorageService } from '../common/storage/storage.service';
|
|
import { CaseFileValidationPipe } from '../common/pipes/file-validation.pipe';
|
|
import { CaseStatus } from '../generated/prisma/client.js';
|
|
|
|
@Resolver(() => CaseLaw)
|
|
export class CasesResolver {
|
|
constructor(
|
|
private readonly casesService: CasesService,
|
|
private readonly storage: StorageService,
|
|
) {}
|
|
|
|
@Query(() => CaseLaw, { name: 'caseLaw', nullable: true })
|
|
async findOne(
|
|
@Args('id', { type: () => String, nullable: true }) id?: string,
|
|
@Args('caseNumber', { type: () => String, nullable: true }) caseNumber?: string,
|
|
) {
|
|
return this.casesService.findOne(id, caseNumber);
|
|
}
|
|
|
|
@ResolveField(() => String, { name: 'downloadUrl', nullable: true })
|
|
async getDownloadUrl(@Parent() caseLaw: CaseLaw): Promise<string | null> {
|
|
const key = caseLaw.storageKey;
|
|
if (!key) return null;
|
|
|
|
return this.storage.getPresignedUrl(key);
|
|
}
|
|
|
|
@Mutation(() => CaseLaw)
|
|
async uploadCase(
|
|
@Args({ name: 'file', type: () => GraphQLUpload }, CaseFileValidationPipe)
|
|
{ createReadStream, filename, mimetype }: FileUpload,
|
|
) {
|
|
const chunks: any[] = [];
|
|
for await (const chunk of createReadStream()) {
|
|
chunks.push(chunk);
|
|
}
|
|
|
|
const buffer = Buffer.concat(chunks);
|
|
// Buffering into memory like this might not be perfectly "scalable" for 1GB files,
|
|
// but for this project and 10MB limit it's simpler to handle than passing a stream.
|
|
return this.casesService.processAndSave(buffer, mimetype, filename);
|
|
}
|
|
|
|
|
|
// An additional simple fetch all endpoint to demonstrate pagination
|
|
@Query(() => [CaseLaw], { name: 'caseLaws' })
|
|
async findAll(
|
|
@Args('status', { type: () => CaseStatus, nullable: true }) status?: CaseStatus,
|
|
@Args('take', { type: () => Int, nullable: true, defaultValue: 20 }) take?: number,
|
|
@Args('skip', { type: () => Int, nullable: true, defaultValue: 0 }) skip?: number,
|
|
) {
|
|
return this.casesService.findAll(status, take, skip);
|
|
}
|
|
}
|