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
+3 -3
View File
@@ -443,7 +443,7 @@ export type LoadCiGateContractOptions = Readonly<{
}>;
const CANONICAL_GATE_SHAPE_SHA256 =
"372959f50b9c5a228bdc85dce33ca7968c72414ce3b6d5534c9e6eaf554f6ce4";
"43dc4ed1cdaf21a674bd069d42eb2c32276afd8f763d72e52c9f7c3adccbeb58";
function canonicalGateShapeSha256(gates: CiGateContract["gates"]): string {
const normalized = gates.map(
@@ -477,9 +477,9 @@ function canonicalAuthorityBaselineFailures(contract: CiGateContract): string[]
if (contract.gates.length !== 27) {
failures.push(`gate authority baseline must contain exactly 27 gates; received ${contract.gates.length}`);
}
if (contract.commands.length !== 84 || commandReferenceCount !== 96) {
if (contract.commands.length !== 91 || commandReferenceCount !== 103) {
failures.push(
`command authority baseline must contain exactly 84 definitions and 96 references; received ${contract.commands.length} definitions and ${commandReferenceCount} references`,
`command authority baseline must contain exactly 91 definitions and 103 references; received ${contract.commands.length} definitions and ${commandReferenceCount} references`,
);
}
if (contract.artifacts.length !== 109) {
+109 -12
View File
@@ -42,18 +42,39 @@ const featureOwnedPaths = [
featureSource,
featureTests,
"tests/integration/http-scenario-catalog.test.ts",
"tests/component/product-feature-switch.test.tsx",
"tests/e2e/reference-form.spec.ts",
"tests/e2e/reference-route.spec.ts",
"tests/mocks",
"tests/fixtures/typecheck/invalid-feature-input.ts",
"tests/fixtures/typecheck/invalid-reference-operation.ts",
"tests/fixtures/typecheck/invalid-http-operation-input.ts",
"tests/fixtures/typecheck/invalid-http-wire-mapper.ts",
"tests/fixtures/typecheck/invalid-http-operation-id.ts",
"tests/fixtures/typecheck/invalid-http-route-id.ts",
"tests/fixtures/typecheck/invalid-feature-contribution-input.ts",
"tests/fixtures/typecheck/invalid-feature-capability-selection.ts",
"tests/fixtures/typecheck/tsconfig.feature-input.json",
"tests/fixtures/typecheck/tsconfig.reference-operation.json",
"tests/fixtures/typecheck/tsconfig.http-operation-input.json",
"tests/fixtures/typecheck/tsconfig.http-wire-mapper.json",
"tests/fixtures/typecheck/tsconfig.http-operation-id.json",
"tests/fixtures/typecheck/tsconfig.http-route-id.json",
"tests/fixtures/typecheck/tsconfig.feature-contribution-input.json",
"tests/fixtures/typecheck/tsconfig.feature-capability-selection.json",
];
const emptyProductManifest = `export const COMPILED_PRODUCT_FEATURE_IDS: readonly string[] = Object.freeze([]);
export const INSTALLED_PRODUCT_FEATURES: readonly never[] = Object.freeze([]);
export const INSTALLED_PRODUCT_FEATURE_IDS: readonly string[] = Object.freeze([]);
`;
const emptyContracts = `import { PLATFORM_ROUTE_RUNTIME_CONTRACT } from "../contracts/route-runtime-contract.ts";
import { PLATFORM_ROUTE_REGISTRY, type RouteDefinition } from "../contracts/routes.ts";
import { PLATFORM_SCHEMA_REGISTRY } from "../contracts/schema-registry.ts";
import { INSTALLED_PRODUCT_FEATURES } from "./installed-product-manifest.ts";
export const INSTALLED_FEATURE_CONTRACTS: readonly unknown[] = Object.freeze([]);
export const INSTALLED_FEATURE_CONTRACTS = INSTALLED_PRODUCT_FEATURES;
export const ROUTE_REGISTRY = PLATFORM_ROUTE_REGISTRY;
export const ROUTE_RUNTIME_CONTRACT = PLATFORM_ROUTE_RUNTIME_CONTRACT;
export const API_OPERATIONS = Object.freeze({});
@@ -64,6 +85,7 @@ export const INVALIDATION_REGISTRY = Object.freeze({
});
export const INVALIDATION_TOPIC_VERSIONS = Object.freeze([]);
export const SCHEMA_REGISTRY = PLATFORM_SCHEMA_REGISTRY;
export const ROUTE_FEATURE_OWNER: Readonly<Record<string, string>> = Object.freeze({});
export const NAVIGATION_ROUTES = Object.freeze(
Object.values(ROUTE_REGISTRY)
.filter((definition) => definition.navigationOrder !== null)
@@ -85,14 +107,39 @@ export function routePath(routeId: string): string {
const emptyRuntimes = `import { PLATFORM_ROUTE_CODECS } from "../presentation/routes/platform-route-codecs.ts";
import { PLATFORM_ROUTE_RUNTIME } from "../presentation/routes/route-runtime.tsx";
import { INSTALLED_PRODUCT_FEATURE_IDS } from "./installed-product-manifest.ts";
const COMPILED_FEATURE_RUNTIME_CONTRIBUTIONS: readonly Readonly<{
featureId: string;
}>[] = Object.freeze([]);
const INSTALLED_FEATURE_RUNTIME_CONTRIBUTIONS =
COMPILED_FEATURE_RUNTIME_CONTRIBUTIONS.filter((contribution) =>
INSTALLED_PRODUCT_FEATURE_IDS.includes(contribution.featureId),
);
void INSTALLED_FEATURE_RUNTIME_CONTRIBUTIONS;
export const ROUTE_CODECS = PLATFORM_ROUTE_CODECS;
export const ROUTE_RUNTIME = PLATFORM_ROUTE_RUNTIME;
`;
const emptyAdapters = `export function createInstalledFeatureInputs(_context: unknown) {
void _context;
return Object.freeze({});
const emptyAdapters = `import {
composeFeatureAdapterInputs,
type InstalledFeatureInputs,
} from "./feature-adapter-contribution.ts";
import { INSTALLED_PRODUCT_FEATURE_IDS } from "./installed-product-manifest.ts";
const COMPILED_FEATURE_ADAPTER_CONTRIBUTIONS = Object.freeze([] as const);
export function createInstalledFeatureInputs(
context: Readonly<Record<never, never>>,
): InstalledFeatureInputs {
return composeFeatureAdapterInputs(
COMPILED_FEATURE_ADAPTER_CONTRIBUTIONS,
INSTALLED_PRODUCT_FEATURE_IDS,
context,
);
}
`;
@@ -101,9 +148,17 @@ const emptyContractContributions = `import {
type InstalledContractContribution,
type InstalledContractPackageIdentity,
} from "../contracts/external-contract-runtime.ts";
import { INSTALLED_PRODUCT_FEATURE_IDS } from "./installed-product-manifest.ts";
const COMPILED_CONTRACT_CONTRIBUTIONS: readonly InstalledContractContribution[] =
Object.freeze([]);
export const INSTALLED_CONTRACT_CONTRIBUTIONS: readonly InstalledContractContribution[] =
Object.freeze([]);
Object.freeze(
COMPILED_CONTRACT_CONTRIBUTIONS.filter((contribution) =>
INSTALLED_PRODUCT_FEATURE_IDS.includes(contribution.featureId),
),
);
export const COMPOSED_CONTRACT_CONTRIBUTIONS = composeContractContributions(
INSTALLED_CONTRACT_CONTRIBUTIONS,
@@ -181,6 +236,10 @@ try {
force: true,
});
}
await writeFile(
path.join(fixtureRoot, "src/features/installed-product-manifest.ts"),
emptyProductManifest,
);
await writeFile(
path.join(fixtureRoot, "src/features/installed-feature-contracts.ts"),
emptyContracts,
@@ -202,6 +261,34 @@ try {
emptyContractContributions,
);
// Runtime profiles are product configuration. Once the feature is physically
// removed, its override key must disappear too or the built config still
// advertises a source capability that no longer exists.
for (const profile of [
"local",
"development",
"staging",
"production",
] as const) {
const profilePath = path.join(
fixtureRoot,
"config/runtime",
`${profile}.json`,
);
const runtimeConfig = JSON.parse(
await readFile(profilePath, "utf8"),
) as {
FEATURE_OVERRIDES?: Record<string, string>;
};
if (runtimeConfig.FEATURE_OVERRIDES) {
delete runtimeConfig.FEATURE_OVERRIDES["reference-feature"];
}
await writeFile(
profilePath,
`${JSON.stringify(runtimeConfig, null, 2)}\n`,
);
}
const retainedCriticalModules = coveragePolicy.criticalModules.filter(
(modulePolicy) => !modulePolicy.path?.startsWith(`${featureSource}/`),
);
@@ -296,6 +383,12 @@ try {
const removedCiScripts = new Set([
"check:types:fixture:feature-input",
"check:types:fixture:reference-operation",
"check:types:fixture:http-operation-input",
"check:types:fixture:http-wire-mapper",
"check:types:fixture:http-operation-id",
"check:types:fixture:http-route-id",
"check:types:fixture:feature-contribution-input",
"check:types:fixture:feature-capability-selection",
"test:http-scenario-evidence",
"test:reference-feature",
]);
@@ -370,13 +463,17 @@ try {
["build", runPnpm("build")],
];
const builtResidue: string[] = [];
for (const file of await filesBelow(path.join(fixtureRoot, "dist"))) {
if (!/\.(?:js|css|html|json)$/.test(file)) continue;
const content = await readFile(file, "utf8");
if (
/REFERENCE_RESOURCE|reference-feature|reference-resource/i.test(content)
) {
builtResidue.push(path.relative(fixtureRoot, file));
const buildSucceeded =
checks.find(([name]) => name === "build")?.[1] === true;
if (buildSucceeded) {
for (const file of await filesBelow(path.join(fixtureRoot, "dist"))) {
if (!/\.(?:js|css|html|json)$/.test(file)) continue;
const content = await readFile(file, "utf8");
if (
/REFERENCE_RESOURCE|reference-feature|reference-resource/i.test(content)
) {
builtResidue.push(path.relative(fixtureRoot, file));
}
}
}
const routeCatalog = await import(