refactor: 프론트 템플릿 리펙토링
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
# Capability consumer experience baseline
|
||||
|
||||
Correctness inside a reusable capability is not sufficient. The platform is
|
||||
also evaluated by how much of that correctness a normal feature developer must
|
||||
understand.
|
||||
|
||||
These measurements are baselines, not score targets. A lower line count is not
|
||||
automatically better if it hides business semantics or creates a universal
|
||||
repository abstraction.
|
||||
|
||||
## Scenario A — reference REST feature
|
||||
|
||||
The existing reference feature is the executable REST consumer.
|
||||
|
||||
It covers list/detail/create behavior, mapping, typed operation inputs,
|
||||
application ports and an optimistic mutation path.
|
||||
|
||||
Current source size:
|
||||
|
||||
| Feature-owned area | LOC |
|
||||
| --- | ---: |
|
||||
| `application/reference-feature-api.ts` | 91 |
|
||||
| `contracts/reference-mapper.ts` | 109 |
|
||||
| `adapters/reference-http-gateway.ts` | 65 |
|
||||
| `adapters/create-reference-feature-input.ts` | 41 |
|
||||
| Total measured boundary/application source | 306 |
|
||||
|
||||
The important boundary metric is not the raw total. It is what those files need
|
||||
to know about the platform.
|
||||
|
||||
Current result:
|
||||
|
||||
- HTTP platform imports in the feature adapter layer: 2 files,
|
||||
- canonical import path used by both:
|
||||
`src/adapters/http/index.ts`,
|
||||
- direct imports of `http-execution-v3.ts`, retry scheduler, response reader,
|
||||
auth admission or effect-certainty internals: 0,
|
||||
- feature gateway owns transport failure projection: 0,
|
||||
- feature gateway chooses operation ID, route ID, exact input/value type and
|
||||
mapper: yes,
|
||||
- central installed files own feature-specific adapter/runtime wiring: no;
|
||||
feature-owned contributions are aggregated centrally.
|
||||
|
||||
The reusable HTTP capability now owns execution-outcome normalization through
|
||||
`createFeatureHttpBinding`. A feature may still implement a custom outbound
|
||||
adapter behind its application port when the reusable contract does not match
|
||||
its business requirement.
|
||||
|
||||
## Scenario B — IndexedDB local draft
|
||||
|
||||
An executable consumer probe lives at:
|
||||
|
||||
`tests/contract/consumer-experience/indexeddb-local-draft.test.ts`
|
||||
|
||||
with the feature-owned fixture:
|
||||
|
||||
`tests/contract/consumer-experience/fixtures/local-draft-feature.ts`
|
||||
|
||||
The fixture models a small local-draft feature with save/find/remove and
|
||||
optimistic revision checking.
|
||||
|
||||
Measured result:
|
||||
|
||||
| Metric | Result |
|
||||
| --- | ---: |
|
||||
| feature-owned fixture LOC | 97 |
|
||||
| platform import statements | 1 |
|
||||
| native IndexedDB API references | 0 |
|
||||
| `src/adapters/storage/indexeddb/**` imports | 0 |
|
||||
| runtime-internal IndexedDB types imported by feature | 0 |
|
||||
|
||||
The feature depends only on the public application boundary:
|
||||
|
||||
`src/application/ports/browser-file-storage/index.ts`
|
||||
|
||||
and specifically `IndexedDbRepositoryPort<LocalDraft, never>`.
|
||||
|
||||
The contract test rejects feature source that reaches for
|
||||
`globalThis.indexedDB`, `IDBFactory`, `IDBDatabase`, `IDBTransaction`,
|
||||
`IDBObjectStore` or the concrete IndexedDB adapter directory.
|
||||
|
||||
## What this does and does not prove
|
||||
|
||||
The probe confirms that **feature business code does not need native IndexedDB
|
||||
knowledge** once an `IndexedDbRepositoryPort` has been composed.
|
||||
|
||||
It does not prove that composition of `createIndexedDbRuntime` is cheap.
|
||||
That constructor still owns substantial infrastructure policy:
|
||||
|
||||
- dataset scope and storage policy,
|
||||
- physical store governance,
|
||||
- retention/idempotency stores,
|
||||
- schema migrations,
|
||||
- codec and query policy,
|
||||
- lifecycle authority,
|
||||
- durability, scheduling and observation.
|
||||
|
||||
That complexity belongs at the composition/platform boundary, not in the
|
||||
feature. A new `create...Repository<T>` convenience factory should be added
|
||||
only when a second real product consumer demonstrates which subset is stable
|
||||
enough to become a reusable profile. Creating one now would guess at policy and
|
||||
risk producing a universal storage abstraction.
|
||||
|
||||
## Consumer-quality review checklist
|
||||
|
||||
For each new product feature, record:
|
||||
|
||||
- feature-owned adapter LOC,
|
||||
- platform glue LOC,
|
||||
- files changed,
|
||||
- central catalog edits,
|
||||
- direct imports from capability-internal modules,
|
||||
- native browser/network API references,
|
||||
- duplicated failure/retry/lifecycle policy.
|
||||
|
||||
A healthy feature path should look like:
|
||||
|
||||
1. domain type and invariant,
|
||||
2. use case,
|
||||
3. business port,
|
||||
4. feature-owned mapper/codec and policy,
|
||||
5. capability-specific binding,
|
||||
6. presentation controller/page.
|
||||
|
||||
The feature should not need the retry scheduler, abort ownership,
|
||||
effect-certainty machinery, IndexedDB transaction lifecycle, OPFS journal,
|
||||
reconnect coordinator or provider process model.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,219 @@
|
||||
# Frontend Application Foundation
|
||||
|
||||
This repository is not treated as a minimal React project template and it is not
|
||||
an independent general-purpose SDK. Its architectural role is:
|
||||
|
||||
> Frontend Application Foundation = Starter / Composition Skeleton + Reusable Capability Platform
|
||||
|
||||
The starter side owns bootstrap, routing, providers, project conventions and a
|
||||
removable reference feature. The capability side owns reusable technical
|
||||
problems such as HTTP execution, Server State, authentication boundaries,
|
||||
IndexedDB/OPFS, Cache Storage, realtime, browser RPC, transfer and diagnostics.
|
||||
|
||||
The cost of a sophisticated capability is acceptable only when product features
|
||||
do not have to understand that internal sophistication.
|
||||
|
||||
## Hybrid architecture
|
||||
|
||||
Platform code is horizontal:
|
||||
|
||||
- `application`: generic application inputs/policies/ports
|
||||
- `contracts`: genuinely cross-capability shared vocabulary and registries
|
||||
- `adapters`: reusable capability runtimes
|
||||
- `presentation`: generic UI/routing/query integration
|
||||
- `bootstrap`: concrete composition
|
||||
|
||||
Product business code is vertical:
|
||||
|
||||
- `features/<feature>/domain`
|
||||
- `features/<feature>/application`
|
||||
- `features/<feature>/contracts`
|
||||
- `features/<feature>/adapters`
|
||||
- `features/<feature>/presentation`
|
||||
|
||||
The dependency model is:
|
||||
|
||||
Domain / Use case
|
||||
|
|
||||
| owns
|
||||
v
|
||||
Business port
|
||||
^
|
||||
| implements / binds
|
||||
|
|
||||
Feature-owned adapter binding
|
||||
|
|
||||
| generic type + mapper/codec + policy
|
||||
v
|
||||
Reusable capability runtime
|
||||
|
|
||||
v
|
||||
Browser / network / native API
|
||||
|
||||
A use case never imports a platform adapter. Generic binding happens in the
|
||||
feature adapter/composition seam.
|
||||
|
||||
## Capability-specific typed bindings
|
||||
|
||||
Do not introduce one universal `Repository<TKey, TValue>` abstraction for HTTP,
|
||||
storage, realtime and transfer. Their lifecycle and failure semantics differ.
|
||||
|
||||
A reusable capability boundary is composed from:
|
||||
|
||||
- generic input/output types,
|
||||
- feature-owned mapper or codec,
|
||||
- feature-selected policy,
|
||||
- one capability-specific runtime.
|
||||
|
||||
The HTTP reference path is the first concrete example.
|
||||
`src/adapters/http/feature-http-binding.ts` owns transport/outcome
|
||||
normalization. The reference feature contributes only:
|
||||
|
||||
- operation ID,
|
||||
- route ID,
|
||||
- exact request input type,
|
||||
- exact success value type,
|
||||
- wire-to-domain mapper.
|
||||
|
||||
The feature gateway therefore does not reimplement timeout, cancellation,
|
||||
transport failure, authentication failure or contract-violation projection.
|
||||
|
||||
Storage, realtime and transfer may gain their own typed binders only after
|
||||
actual feature repetition demonstrates the need. They must not be forced
|
||||
through the HTTP abstraction.
|
||||
|
||||
## Custom adapter escape hatch
|
||||
|
||||
A product feature uses a reusable capability when the capability preserves the
|
||||
business requirement.
|
||||
|
||||
If a platform contract would require changing or weakening the business model,
|
||||
the feature implements a custom outbound adapter behind the same application
|
||||
port. The architecture boundary remains stable; platform reuse is optional.
|
||||
|
||||
## Feature installation
|
||||
|
||||
A feature owns its contract, runtime and adapter contributions.
|
||||
|
||||
Central installed catalogs are aggregation points only:
|
||||
|
||||
- `installed-product-manifest.ts`: which product features are compiled/selected
|
||||
- `installed-feature-contracts.ts`: contract aggregation
|
||||
- `installed-feature-runtimes.tsx`: runtime contribution aggregation
|
||||
- `installed-feature-adapters.ts`: application-input contribution aggregation
|
||||
|
||||
Feature-specific composition belongs under the feature itself. Central
|
||||
catalogs must not grow feature-specific branching logic.
|
||||
|
||||
## Presentation consumer surface
|
||||
|
||||
`ApplicationProvider` remains the composition root for presentation, but new
|
||||
consumers should not navigate a root `ApplicationApi` service locator.
|
||||
|
||||
Use the narrow hooks in
|
||||
`src/presentation/providers/application-provider.tsx`:
|
||||
|
||||
- `useApplicationSession`
|
||||
- `useApplicationPreferences`
|
||||
- `useApplicationDiagnostics`
|
||||
- `useApplicationRuntime`
|
||||
- `useApplicationRecovery`
|
||||
- `useApplicationFeature`
|
||||
|
||||
`useApplication` exists only as a deprecated compatibility escape hatch.
|
||||
|
||||
## Canonical imports
|
||||
|
||||
New feature code should use capability public entry points rather than deep
|
||||
runtime modules. For HTTP the canonical path is
|
||||
`src/adapters/http/index.ts`.
|
||||
|
||||
Compatibility re-exports may exist during a migration window, but they must be
|
||||
marked as compatibility/deprecated paths and should not expand into an
|
||||
unbounded public barrel.
|
||||
|
||||
## Policy ownership
|
||||
|
||||
Duplication is judged by ownership, not by syntax percentage.
|
||||
|
||||
Small local validators can remain duplicated when locality improves auditing.
|
||||
Business or concurrency policy must have one owner. For example the reference
|
||||
create mutation keeps definition ID, idempotency requirement, duplicate policy
|
||||
and invalidation policy in one feature-owned definition and binds only
|
||||
`scope` and `execute` per usage site.
|
||||
|
||||
## Runtime decomposition rule
|
||||
|
||||
Large runtime files are not split by line count.
|
||||
|
||||
Extract a boundary when it has its own state machine, lifecycle owner, failure
|
||||
model or compensation/recovery responsibility. Candidate seams include:
|
||||
|
||||
- connection/open/upgrade lifecycle,
|
||||
- transaction ownership,
|
||||
- migration state machine,
|
||||
- reconnect/backoff and heartbeat,
|
||||
- subscription ownership,
|
||||
- retry/deadline/cancellation ownership,
|
||||
- settlement/reconciliation/cleanup.
|
||||
|
||||
A cohesive 2,000-line state machine can remain together. A 300-line file with
|
||||
multiple lifecycle owners is a better extraction candidate.
|
||||
|
||||
### Current runtime boundary audit
|
||||
|
||||
The current large-runtime inventory was reviewed using that rule.
|
||||
|
||||
- IndexedDB remains large, but connection, transaction, migration, maintenance
|
||||
and failure translation already have separate owners/modules.
|
||||
- resumable upload already separates runtime policy, checkpoint persistence,
|
||||
HTTP control-plane transport, part execution, cancellation and mutation
|
||||
locking.
|
||||
- realtime already separates reconnect policy/coordinator, event codec/consumer
|
||||
and stream coordination.
|
||||
- OPFS is separated into browser runtime, journal, byte-store, policy and worker
|
||||
protocol/runtime responsibilities.
|
||||
- HTTP V3 still owned retry eligibility/backoff inside the execution state
|
||||
machine, so that responsibility moved to
|
||||
`src/adapters/http/http-retry-lifecycle.ts`.
|
||||
|
||||
No other runtime is split merely because of its line count.
|
||||
|
||||
## Consumer quality metrics
|
||||
|
||||
Before adding another abstraction, implement or model multiple real feature
|
||||
uses and measure:
|
||||
|
||||
- feature-owned adapter LOC,
|
||||
- repeated platform glue,
|
||||
- number of platform-internal types exposed to the feature,
|
||||
- central catalog edits,
|
||||
- files changed for one normal query/command,
|
||||
- whether native browser/network APIs leak into the feature.
|
||||
|
||||
The target feature-development path is:
|
||||
|
||||
1. domain type and invariant,
|
||||
2. use case,
|
||||
3. port,
|
||||
4. transport/storage schema plus mapper/codec,
|
||||
5. capability binding,
|
||||
6. presentation controller/page.
|
||||
|
||||
A product feature should not need to know the retry scheduler, abort ownership,
|
||||
effect-certainty machinery, transaction leases, reconnect coordinator, OPFS
|
||||
journal or provider lifecycle.
|
||||
|
||||
The executable REST and IndexedDB consumer baselines are recorded in
|
||||
[`capability-consumer-experience.md`](./capability-consumer-experience.md).
|
||||
Contract placement and the global-vs-owner-local audit are recorded in
|
||||
[`contract-ownership.md`](./contract-ownership.md).
|
||||
|
||||
## Verification paths
|
||||
|
||||
Product-development verification, capability verification and release assurance
|
||||
are intentionally separate. See
|
||||
[`docs/testing/taxonomy.md`](../testing/taxonomy.md).
|
||||
|
||||
Host-level CI-runner tests belong to `tests/system`, not `tests/unit`.
|
||||
Reusable capability consumer contracts belong to `tests/contract`.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -90,11 +90,19 @@ production Playwright profile은 source fixture가 아니라 `build` + `preview`
|
||||
|
||||
#### TanStack Query의 React integration test 기반
|
||||
|
||||
`tests/component/application-query.test.tsx`는 production query inbound
|
||||
adapter의 query/mutation lifecycle을 검증한다. cancellation, initial terminal
|
||||
failure, background stale-failure latch와 retry 복구, duplicate submit,
|
||||
optimistic commit/rollback, conflict 해제와 namespace invalidation이 실제
|
||||
QueryClient 위에서 실행된다. HTTP 자동 retry가 소유자이므로 이 adapter의
|
||||
production query inbound adapter의 React integration은 behavior owner별
|
||||
component suite로 분리되어 있다.
|
||||
|
||||
- `application-query-bridge.test.tsx`: initial/background state, cancellation
|
||||
- `application-query-scope-fence.test.tsx`: scope commit fence와 result budget
|
||||
- `application-mutation-scope-fence.test.tsx`: mutation scope fence
|
||||
- `application-query.test.tsx`: unknown-effect reconciliation
|
||||
- `application-mutation-admission.test.tsx`: intent/duplicate admission
|
||||
- `application-mutation-optimistic-cache.test.tsx`: optimistic cache commit/rollback
|
||||
- `application-query-fixture.tsx`: 공통 QueryClient/scope fixture
|
||||
|
||||
각 실패 파일명이 깨진 behavior contract를 직접 드러내며, 동일한 52개 계약을
|
||||
실제 QueryClient 위에서 검증한다. HTTP 자동 retry가 소유자이므로 이 adapter의
|
||||
query/mutation vendor retry는 꺼져 있다.
|
||||
|
||||
#### Form과 route 위험
|
||||
|
||||
+65
-14
@@ -3,14 +3,68 @@
|
||||
Each gate is blocking in its declared scope. Failures are not downgraded with
|
||||
`continue-on-error` or warning-only scripts.
|
||||
|
||||
| Level | Command | Evidence |
|
||||
| --- | --- | --- |
|
||||
| runtime schema | `pnpm test:runtime-schema` | `artifacts/tests/runtime-schema.xml` |
|
||||
| unit | `pnpm test:unit` | `artifacts/tests/unit.xml` |
|
||||
| component | `pnpm test:component` | `artifacts/tests/component.xml` |
|
||||
| integration | `pnpm test:integration` | `artifacts/tests/integration.xml` |
|
||||
| end-to-end | `pnpm test:e2e` | `artifacts/tests/e2e/` |
|
||||
| accessibility | `pnpm test:a11y` | `artifacts/tests/a11y.json` |
|
||||
## Executable levels
|
||||
|
||||
| Level | Command | Ownership / prerequisite | Evidence |
|
||||
| --- | --- | --- | --- |
|
||||
| runtime schema | `pnpm test:runtime-schema` | pure runtime schema contracts | `artifacts/tests/runtime-schema.xml` |
|
||||
| unit | `pnpm test:unit` | Node-only domain/application/pure policy/runtime units; no systemd/bwrap/cgroup prerequisite | `artifacts/tests/unit.xml` |
|
||||
| capability contract | `pnpm test:contract` | reusable capability consumer contracts | `artifacts/tests/contract.xml` |
|
||||
| component | `pnpm test:component` | React/hook/UI behavior | `artifacts/tests/component.xml` |
|
||||
| integration | `pnpm test:integration` | HTTP/MSW, IndexedDB and composed browser-runtime boundaries | `artifacts/tests/integration.xml` |
|
||||
| system / CI runner | `pnpm test:system` | compatible Linux host with systemd, bubblewrap, cgroup v2 and CI-provider process controls | `artifacts/tests/system.xml` |
|
||||
| end-to-end | `pnpm test:e2e` | pinned browser engines | `artifacts/tests/e2e/` |
|
||||
| accessibility | `pnpm test:a11y` | pinned browser engines | `artifacts/tests/a11y.json` |
|
||||
|
||||
`test:all` is the normal product-development loop. It intentionally includes
|
||||
runtime-schema, unit, capability-contract, component, integration, reference
|
||||
feature and recipe suites, but does not include `test:system`. CI-runner and
|
||||
supply-chain assurance has different host prerequisites and is invoked
|
||||
explicitly in the assurance path.
|
||||
|
||||
## Deterministic test process
|
||||
|
||||
All Vitest package scripts launch through `scripts/run-vitest.ts`.
|
||||
|
||||
That runner:
|
||||
|
||||
1. rejects Node versions outside the repository-supported
|
||||
`>=24.11.0 <25.0.0` range before the suite starts,
|
||||
2. owns `NODE_ENV=test` rather than trusting the parent shell,
|
||||
3. removes host-specific `npm_config_userconfig`, `npm_config_prefix` and
|
||||
`npm_config_globalconfig` values before Vitest starts.
|
||||
|
||||
`vitest.config.ts` also fixes `NODE_ENV=test` so a direct Vitest invocation
|
||||
cannot accidentally select React's production behavior.
|
||||
|
||||
The system suite additionally runs
|
||||
`scripts/check-system-test-prerequisites.ts` and fails with one prerequisite
|
||||
report when the CI-runner host does not provide its required Linux facilities.
|
||||
|
||||
## Development paths
|
||||
|
||||
Product feature:
|
||||
|
||||
- focused feature/unit/component test
|
||||
- capability contract test when a reusable boundary changes
|
||||
- type/lint/architecture
|
||||
- `test:all`
|
||||
|
||||
Reusable capability:
|
||||
|
||||
- focused unit tests
|
||||
- capability contract tests
|
||||
- integration tests
|
||||
- type/lint/architecture
|
||||
|
||||
CI / release assurance:
|
||||
|
||||
- `test:system`
|
||||
- supply-chain / promotion / release gates
|
||||
|
||||
A host-level process/sandbox test must not be placed in `tests/unit` merely
|
||||
because it uses Vitest. The classification follows the system boundary and
|
||||
prerequisites, not the test framework.
|
||||
|
||||
End-to-end and automated accessibility scenarios run on the pinned Chromium,
|
||||
Firefox, and WebKit engines. The responsive contract explicitly exercises
|
||||
@@ -30,9 +84,6 @@ Promotion is an AND graph:
|
||||
3. release gates plus rollback/runbook drills
|
||||
4. production promotion plus eligible field Web Vitals evidence
|
||||
|
||||
This file describes the currently registered taxonomy. The
|
||||
[frontend platform testing strategy](./frontend-platform-testing-strategy.md)
|
||||
documents the target additions: test TypeScript projects, real bootstrap
|
||||
composition tests, shared MSW scenarios, query/mutation/form/router coverage,
|
||||
Storybook interaction and accessibility checks, visual regression, and a
|
||||
built-output Playwright profile.
|
||||
The [frontend platform testing strategy](./frontend-platform-testing-strategy.md)
|
||||
contains the broader testing design. This file is the executable taxonomy for
|
||||
where a test belongs and which environment is allowed to run it.
|
||||
|
||||
Reference in New Issue
Block a user