refactor: 프론트엔드 리펙토링

This commit is contained in:
donghyeon-ka
2026-09-18 22:05:42 +09:00
parent 5cc41467ae
commit ec7f20e2ee
100 changed files with 6005 additions and 2867 deletions
@@ -32,7 +32,7 @@ describe("reference feature boundary contracts", () => {
effect: "MAYBE_APPLIED" as const,
}));
const installed = createReferenceFeatureInstalledInput({
contractOperations: { execute },
http: { execute },
});
await expect(
@@ -3,7 +3,6 @@ import { describe, expect, it, vi } from "vitest";
import { createContractHttpExecutor } from "../../../src/adapters/http/index.ts";
import { createHttpObservationProjector } from "../../../src/bootstrap/runtime-adapters.ts";
import { createReferenceFeatureInstalledInput } from "../../../src/features/reference-feature/adapters/create-reference-feature-input.ts";
import { REFERENCE_FEATURE_TEMPLATE_CONTRIBUTION } from "../../../src/features/reference-feature/contracts/reference-feature-contract-contribution.ts";
function scopeSnapshot() {
return Object.freeze({
@@ -34,17 +33,9 @@ describe("reference feature HTTP diagnostics", () => {
telemetry: { emit: vi.fn() },
}),
});
const operations = new Map(
REFERENCE_FEATURE_TEMPLATE_CONTRIBUTION.http.map((operation) => [
operation.contract.operationId,
operation,
]),
);
const installed = createReferenceFeatureInstalledInput({
contractOperations: Object.freeze({
async execute(operationId, input, context) {
const operation = operations.get(operationId);
if (!operation) throw new Error("Unregistered reference operation");
http: Object.freeze({
async execute(operation, input, context) {
return contractHttp.execute(operation, input, {
routeId: context.routeId,
scope: scopeSnapshot(),
@@ -0,0 +1,135 @@
import { describe, expect, it } from "vitest";
import {
createFeatureHttpBinding,
type InstalledHttpOperationExecutor,
} from "../../../src/adapters/http/index.ts";
import {
createReferenceHttpGateway,
REFERENCE_HTTP_OPERATIONS,
} from "../../../src/features/reference-feature/adapters/reference-http-gateway.ts";
function executorReturning(
outcome: Readonly<Record<string, unknown>>,
): InstalledHttpOperationExecutor {
const execute = (async () => outcome) as unknown as
InstalledHttpOperationExecutor["execute"];
return Object.freeze({ execute });
}
describe("reference HTTP business problem mapping", () => {
it("maps a typed 409 reference problem to the feature-owned business code", async () => {
const executor = executorReturning(
Object.freeze({
kind: "PROBLEM",
problem: Object.freeze({
type: "https://example.test/problems/reference-conflict",
title: "Reference conflict",
status: 409,
code: "REFERENCE_NAME_ALREADY_EXISTS",
}),
metadata: Object.freeze({ status: 409 }),
effect: "NOT_APPLIED",
}),
);
const gateway = createReferenceHttpGateway(
createFeatureHttpBinding(executor, REFERENCE_HTTP_OPERATIONS),
);
await expect(
gateway.create({ name: "duplicate" }),
).resolves.toMatchObject({
ok: false,
error: {
kind: "CONFLICT",
code: "REFERENCE_NAME_ALREADY_EXISTS",
httpStatus: 409,
},
});
});
it.each([
{
status: 409,
code: undefined,
expectedKind: "CONFLICT",
expectedCode: "REFERENCE_RESOURCE_CONFLICT",
},
{
status: 422,
code: "REFERENCE_NAME_REJECTED",
expectedKind: "VALIDATION_REJECTED",
expectedCode: "REFERENCE_NAME_REJECTED",
},
{
status: 422,
code: undefined,
expectedKind: "VALIDATION_REJECTED",
expectedCode: "REFERENCE_RESOURCE_REJECTED",
},
{
status: 400,
code: "REFERENCE_BAD_REQUEST",
expectedKind: "UNKNOWN_CLIENT_FAILURE",
expectedCode: "CONTRACT_PROBLEM",
},
] as const)(
"projects create problem status $status through the feature-owned mapper/fallback",
async ({ status, code, expectedKind, expectedCode }) => {
const executor = executorReturning(
Object.freeze({
kind: "PROBLEM",
problem: Object.freeze({
type: "https://example.test/problems/reference-" + status,
title: "Reference request rejected",
status,
...(code === undefined ? {} : { code }),
}),
metadata: Object.freeze({ status }),
effect: "NOT_APPLIED",
}),
);
const gateway = createReferenceHttpGateway(
createFeatureHttpBinding(executor, REFERENCE_HTTP_OPERATIONS),
);
await expect(
gateway.create({ name: "rejected" }),
).resolves.toMatchObject({
ok: false,
error: {
kind: expectedKind,
code: expectedCode,
httpStatus: status,
},
});
},
);
it("keeps the platform status fallback when the operation has no problem mapper", async () => {
const executor = executorReturning(
Object.freeze({
kind: "PROBLEM",
problem: Object.freeze({
type: "https://example.test/problems/not-found",
title: "Not found",
status: 404,
}),
metadata: Object.freeze({ status: 404 }),
effect: "NOT_APPLIED",
}),
);
const gateway = createReferenceHttpGateway(
createFeatureHttpBinding(executor, REFERENCE_HTTP_OPERATIONS),
);
await expect(gateway.get("missing")).resolves.toMatchObject({
ok: false,
error: {
kind: "NOT_FOUND",
code: "CONTRACT_PROBLEM",
httpStatus: 404,
},
});
});
});
@@ -1,5 +1,8 @@
import { describe, expect, it } from "vitest";
import {
type InstalledHttpOperationExecutor,
} from "../../../src/adapters/http/index.ts";
import { createReferenceFeatureInstalledInput } from "../../../src/features/reference-feature/adapters/create-reference-feature-input.ts";
/**
@@ -14,22 +17,31 @@ import { createReferenceFeatureInstalledInput } from "../../../src/features/refe
describe("reference feature installed operation executor", () => {
it("preserves the feature route id through the installed operation executor", async () => {
const seen: Array<Readonly<Record<string, unknown>>> = [];
const implementation = async (
contract: Readonly<{ contract: Readonly<{ operationId: string }> }>,
_input: unknown,
context: Readonly<Record<string, unknown>>,
) => {
seen.push(Object.freeze({ ...context }));
const value =
contract.contract.operationId === "LIST_REFERENCE_RESOURCES"
? []
: {
id: "resource-1",
name: "Resource",
};
return Object.freeze({
kind: "SUCCESS" as const,
value,
metadata: Object.freeze({ status: 200 }),
effect: "NOT_APPLICABLE" as const,
});
};
const execute = implementation as unknown as
InstalledHttpOperationExecutor["execute"];
const installed = createReferenceFeatureInstalledInput({
contractOperations: Object.freeze({
async execute(
_operationId: string,
_input: unknown,
context?: Readonly<Record<string, unknown>>,
) {
seen.push(Object.freeze({ ...(context ?? {}) }));
return Object.freeze({
kind: "SUCCESS" as const,
value: [],
metadata: Object.freeze({ status: 200 }),
effect: "NOT_APPLICABLE" as const,
});
},
}),
http: Object.freeze({ execute }),
});
await installed.input.listResources({ limit: 20 });