57 lines
2.2 KiB
TypeScript
57 lines
2.2 KiB
TypeScript
import { Result } from "@repo/rdx-utils";
|
|
import { z } from "zod/v4";
|
|
import { PERSON_PHOTO_LIMITS } from "../../common/person-photo";
|
|
import { PersonPhotoError } from "../domain/person-photo-error";
|
|
|
|
export type PersonPhoto = Readonly<{ data: Uint8Array; version: string }>;
|
|
|
|
export interface IPersonPhotoRepository {
|
|
exists(companyId: string, personId: string): Promise<boolean>;
|
|
get(personId: string): Promise<PersonPhoto | null>;
|
|
replace(companyId: string, personId: string, photo: PersonPhoto | null): Promise<boolean>;
|
|
}
|
|
|
|
export interface IPersonPhotoProcessor {
|
|
optimize(data: Uint8Array): Promise<Result<PersonPhoto, PersonPhotoError>>;
|
|
}
|
|
|
|
export class PersonPhotoUseCases {
|
|
constructor(
|
|
private readonly repository: IPersonPhotoRepository,
|
|
private readonly processor: IPersonPhotoProcessor
|
|
) {}
|
|
|
|
async get(personId: string) {
|
|
if (!z.uuid().safeParse(personId).success)
|
|
return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
|
|
const photo = await this.repository.get(personId);
|
|
|
|
return photo ? Result.ok(photo) : Result.fail(new PersonPhotoError("PHOTO_NOT_FOUND"));
|
|
}
|
|
|
|
async save(companyId: string, personId: string, data: Uint8Array) {
|
|
if (!z.uuid().safeParse(companyId).success || !z.uuid().safeParse(personId).success)
|
|
return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
|
|
if (data.length > PERSON_PHOTO_LIMITS.inputBytes)
|
|
return Result.fail(new PersonPhotoError("PHOTO_TOO_LARGE"));
|
|
if (!(await this.repository.exists(companyId, personId)))
|
|
return Result.fail(new PersonPhotoError("PERSON_NOT_FOUND"));
|
|
const processed = await this.processor.optimize(data);
|
|
|
|
if (!processed.isSuccess) return Result.fail(processed.error);
|
|
|
|
return (await this.repository.replace(companyId, personId, processed.data))
|
|
? Result.ok(processed.data.version)
|
|
: Result.fail(new PersonPhotoError("PERSON_NOT_FOUND"));
|
|
}
|
|
|
|
async remove(companyId: string, personId: string) {
|
|
if (!z.uuid().safeParse(companyId).success || !z.uuid().safeParse(personId).success)
|
|
return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
|
|
|
|
return (await this.repository.replace(companyId, personId, null))
|
|
? Result.ok(null)
|
|
: Result.fail(new PersonPhotoError("PERSON_NOT_FOUND"));
|
|
}
|
|
}
|