import { Result } from "@repo/rdx-utils"; import { z } from "zod/v4"; import { COMPANY_LOGO_LIMITS } from "../../common/company-logo"; import { CompanyLogoError } from "../domain/company-logo-error"; export type CompanyLogo = Readonly<{ data: Uint8Array; version: string }>; export interface ICompanyLogoRepository { exists(companyId: string): Promise; get(companyId: string): Promise; replace(companyId: string, logo: CompanyLogo | null): Promise; } export interface ICompanyLogoProcessor { optimize(data: Uint8Array): Promise>; } export class CompanyLogoUseCases { constructor( private readonly repository: ICompanyLogoRepository, private readonly processor: ICompanyLogoProcessor ) {} async get(companyId: string): Promise> { if (!z.uuid().safeParse(companyId).success) { return Result.fail(new CompanyLogoError("INVALID_REQUEST")); } const logo = await this.repository.get(companyId); return logo ? Result.ok(logo) : Result.fail(new CompanyLogoError("LOGO_NOT_FOUND")); } async save( companyId: string, data: Uint8Array ): Promise> { if (!z.uuid().safeParse(companyId).success) { return Result.fail(new CompanyLogoError("INVALID_REQUEST")); } if (data.length > COMPANY_LOGO_LIMITS.inputBytes) { return Result.fail(new CompanyLogoError("LOGO_TOO_LARGE")); } if (!(await this.repository.exists(companyId))) { return Result.fail(new CompanyLogoError("COMPANY_NOT_FOUND")); } const processed = await this.processor.optimize(data); if (!processed.isSuccess) { return Result.fail(processed.error); } return (await this.repository.replace(companyId, processed.data)) ? Result.ok(processed.data.version) : Result.fail(new CompanyLogoError("COMPANY_NOT_FOUND")); } async remove(companyId: string): Promise> { if (!z.uuid().safeParse(companyId).success) { return Result.fail(new CompanyLogoError("INVALID_REQUEST")); } return (await this.repository.replace(companyId, null)) ? Result.ok(null) : Result.fail(new CompanyLogoError("COMPANY_NOT_FOUND")); } }