refactor: 프론트 템플릿 리펙토링

This commit is contained in:
donghyeon-ka
2026-09-18 15:16:58 +09:00
parent c10a709f2c
commit 5cc41467ae
80 changed files with 7227 additions and 4672 deletions
+110
View File
@@ -0,0 +1,110 @@
# Contract ownership
`src/contracts` is not a default destination for every shared-looking type.
A contract belongs there only when the change authority is genuinely shared
across layers, capabilities, build tooling, or runtime composition.
## Decision rule
For every proposed contract, ask:
1. Which requirement can cause this type or policy to change?
2. Is there one clear capability or feature owner?
3. Does another runtime/tooling boundary consume the same semantic contract?
4. Is the contract a wire/artifact authority shared by browser runtime and
build/release tooling?
The placement rule is:
- one feature owner -> keep it under that feature,
- one reusable capability owner -> keep it under that adapter/capability and
export it through the capability public entry point,
- multiple independent capability/layer owners -> `src/contracts`,
- browser/build/release wire or artifact authority -> `src/contracts` even
when the browser source graph alone looks small.
Consumer count alone is not sufficient. Scripts, generated artifacts and
release gates are semantic consumers too.
## Audit result
The September 2026 architecture review triggered an import-graph audit of all
39 contract files.
### Capability-owned contract moved
`cursor-pagination.ts` had one production owner:
`src/adapters/query-cache/cursor-pagination-runtime.ts`.
It moved to:
`src/adapters/query-cache/cursor-pagination-contract.ts`
and is exported through:
`src/adapters/query-cache/index.ts`
Tests use that public capability entry point. Pagination vocabulary no longer
occupies the global contract bucket merely because it is reusable inside one
adapter.
### Contracts intentionally kept global
The following examples have multiple semantic owners and remain global:
- `errors.ts` — application, presentation and several adapters,
- `result.ts` — common success/failure carrier below application,
- `boundary-mapper.ts` — HTTP, browser RPC, realtime and feature registries,
- `mutation-intent.ts` — application, presentation, HTTP, platform and
bootstrap,
- `exact-snapshot.ts` — HTTP, query-cache and browser-transfer,
- `rest-profiles.ts` — auth, HTTP, bootstrap and feature contract validation,
- `query-invalidation.ts` / `query-keys.ts` — query-cache, presentation,
bootstrap and features,
- `cache-invalidation.ts` — cross-context wire protocol plus query
invalidation policy,
- `storage-keys.ts` — browser storage and cross-context invalidation,
- `telemetry.ts` / `diagnostics.ts` — runtime adapters, application and
bootstrap.
Some contracts appear to have few browser-source consumers but are still shared
authorities:
- `env.ts` is consumed by bootstrap, runtime-schema/security tests and
registry governance,
- `deployment-admission.ts` is shared by runtime-config generation and release
admission,
- `release-tokens.ts` is shared by runtime coherence tooling and tests,
- `service-worker-static-manifest.ts` is a runtime-neutral canonical format
shared by build generation, validation and service-worker evidence.
Moving those based only on `src/**` import counts would split one semantic
authority across processes.
## Feature contracts
Feature-specific contracts stay inside the vertical slice:
`features/<feature>/contracts`
The reference feature owns routes, schemas, mapper definitions, message
catalogs and contribution identities. Central installed files aggregate those
contributions; they do not own their semantics.
The message catalog is a deliberate special case: the compiled catalog remains
total even when a feature is build-time disabled so the typed message lookup
does not become partial. The central message file therefore aggregates compiled
message keys rather than treating runtime installation as message ownership.
## Review rule for future additions
A new file under `src/contracts` should be rejected during review when all of
the following are true:
- one feature or one capability is the only semantic owner,
- no build/release/runtime wire authority needs the same definition,
- moving the definition to that owner does not create an inward dependency
violation.
Do not move a contract merely to reduce the number 39. The goal is explicit
ownership, not a smaller directory.