metis-desk/modules/companies/src/api/application/company-input.mapper.ts

105 lines
3.2 KiB
TypeScript

import { EmailAddress, Name, UniqueID } from "@repo/rdx-ddd";
import { Maybe, Result } from "@repo/rdx-utils";
import type {
AssignmentUpdateRequestDTO,
CompanyRequestDTO,
ContactRequestDTO,
DepartmentRequestDTO,
PersonRequestDTO,
SiteRequestDTO,
} from "../../common";
import { CompanyError } from "../domain/company-error";
import { CalendarDate } from "../domain/value-objects/calendar-date.vo";
import { PhoneNumber } from "../domain/value-objects/phone-number.vo";
import { SiteAddress } from "../domain/value-objects/site-address.vo";
function optional<T>(
value: string | null,
create: (value: string) => Result<T, Error>
): Result<Maybe<T>, CompanyError> {
if (value === null || !value.trim()) {
return Result.ok(Maybe.none<T>());
}
const parsed = create(value);
return parsed.isSuccess
? Result.ok(Maybe.some(parsed.data))
: Result.fail(new CompanyError("INVALID_REQUEST"));
}
export class CompanyInputMapper {
id(value: string): Result<UniqueID, CompanyError> {
const result = UniqueID.create(value);
return result.isSuccess
? Result.ok(result.data)
: Result.fail(new CompanyError("INVALID_REQUEST"));
}
company(dto: CompanyRequestDTO) {
const name = Name.create(dto.name, 100);
return name.isSuccess
? Result.ok({ name: name.data, active: dto.active })
: Result.fail(new CompanyError("INVALID_REQUEST"));
}
department(dto: DepartmentRequestDTO) {
return this.company(dto);
}
contact(dto: ContactRequestDTO) {
return this.person({ ...dto, isContact: true });
}
person(dto: PersonRequestDTO) {
const name = Name.create(dto.name, 100);
const position = optional(dto.position, (value) => Name.create(value, 100));
const email = optional(dto.email, (value) => EmailAddress.create(value));
const phone = optional(dto.phone, (value) => PhoneNumber.create(value));
if (!(name.isSuccess && position.isSuccess && email.isSuccess && phone.isSuccess)) {
return Result.fail(new CompanyError("INVALID_REQUEST"));
}
return Result.ok({
name: name.data,
position: position.data,
email: email.data,
phone: phone.data,
active: dto.active,
isContact: dto.isContact,
});
}
assignment(dto: AssignmentUpdateRequestDTO) {
const position = optional(dto.position, (value) => Name.create(value, 100));
const startDate = CalendarDate.create(dto.startDate);
const endDate = optional(dto.endDate, (value) => CalendarDate.create(value));
if (!(position.isSuccess && startDate.isSuccess && endDate.isSuccess)) {
return Result.fail(new CompanyError("INVALID_REQUEST"));
}
return Result.ok({
position: position.data,
startDate: startDate.data,
endDate: endDate.data,
isPrimary: dto.isPrimary,
});
}
site(dto: SiteRequestDTO) {
const name = Name.create(dto.name, 100);
const address = optional(dto.address ?? null, (value) => SiteAddress.create(value));
const phone = optional(dto.phone ?? null, (value) => PhoneNumber.create(value));
if (!(name.isSuccess && address.isSuccess && phone.isSuccess)) {
return Result.fail(new CompanyError("INVALID_REQUEST"));
}
return Result.ok({ name: name.data, address: address.data, phone: phone.data });
}
}