feat: 기능 추가 과정중

This commit is contained in:
donghyeon-ka
2026-07-30 15:58:20 +09:00
parent d3ef801fe6
commit 6c52cdb916
648 changed files with 126325 additions and 6680 deletions
@@ -1,7 +1,13 @@
import {
createReferenceResource,
type ReferenceResource,
} from "../domain/reference-resource.js";
} from "../domain/reference-resource.ts";
import {
mappingFailure,
mappingSuccess,
type MappingResult,
type InstalledBoundaryMapper,
} from "../../../contracts/boundary-mapper.ts";
export type ReferenceResourceView = Readonly<{
resourceId: string;
@@ -10,28 +16,43 @@ export type ReferenceResourceView = Readonly<{
optimistic?: boolean;
}>;
function mapReferenceDto(value: unknown): ReferenceResource {
function mapReferenceDto(value: unknown): MappingResult<ReferenceResource> {
if (!value || typeof value !== "object") {
throw new TypeError("Validated reference DTO is required");
return mappingFailure("MAPPING_INVARIANT_REJECTED");
}
const dto = value as Record<string, unknown>;
if (typeof dto.id !== "string" || typeof dto.name !== "string") {
throw new TypeError("Validated reference DTO invariants were breached");
return mappingFailure("MAPPING_INVARIANT_REJECTED");
}
try {
return mappingSuccess(
createReferenceResource({
id: dto.id,
displayName: dto.name,
createdAt: typeof dto.createdAt === "string" ? dto.createdAt : null,
}),
);
} catch {
return mappingFailure("MAPPING_INVARIANT_REJECTED");
}
return createReferenceResource({
id: dto.id,
displayName: dto.name,
createdAt: typeof dto.createdAt === "string" ? dto.createdAt : null,
});
}
export function mapReferenceOperation(
operationId: string,
payload: unknown,
): ReferenceResource | readonly ReferenceResource[] {
): MappingResult<ReferenceResource | readonly ReferenceResource[]> {
if (operationId === "LIST_REFERENCE_RESOURCES") {
if (!Array.isArray(payload)) throw new TypeError("Expected a reference list");
return payload.map(mapReferenceDto);
if (!Array.isArray(payload)) {
return mappingFailure("MAPPING_INVARIANT_REJECTED");
}
if (payload.length > 100) return mappingFailure("OUTPUT_LIMIT_EXCEEDED");
const output: ReferenceResource[] = [];
for (const item of payload) {
const mapped = mapReferenceDto(item);
if (!mapped.ok) return mapped;
output.push(mapped.value);
}
return mappingSuccess(Object.freeze(output));
}
if (
operationId === "CREATE_REFERENCE_RESOURCE" ||
@@ -39,9 +60,32 @@ export function mapReferenceOperation(
) {
return mapReferenceDto(payload);
}
throw new TypeError(`No reference mapper registered for ${operationId}`);
return mappingFailure("MAPPING_INVARIANT_REJECTED");
}
export const REFERENCE_BOUNDARY_MAPPERS = Object.freeze({
ReferenceResourceListMapper: Object.freeze({
mapperId: "ReferenceResourceListMapper",
mapperVersion: 1,
inputSchemaId: "ReferenceResourceListPayload",
outputContractId: "ReferenceResourceList",
owner: "feature-frontend-reference-feature-vertical-slice",
maxOutputItems: 100,
map: (input: unknown) =>
mapReferenceOperation("LIST_REFERENCE_RESOURCES", input),
}),
ReferenceResourceMapper: Object.freeze({
mapperId: "ReferenceResourceMapper",
mapperVersion: 1,
inputSchemaId: "ReferenceResourcePayload",
outputContractId: "ReferenceResource",
owner: "feature-frontend-reference-feature-vertical-slice",
maxOutputItems: 1,
map: (input: unknown) =>
mapReferenceOperation("GET_REFERENCE_RESOURCE", input),
}),
} satisfies Readonly<Record<string, InstalledBoundaryMapper>>);
export function toReferenceView(
resource: ReferenceResource,
): ReferenceResourceView {