refactor: 프론트 템플릿 리펙토링
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user