Integrates the frontend template sync (a0fbafb → 5434760) into the TechLog UI migration. Merged in this direction so every conflict is resolved and proved in the worktree; main is only fast-forwarded afterwards and never holds a state that was not verified here. 15 conflicts. The rule throughout: keep the template's mechanism, keep the product's content, and never invent a third state neither branch would accept. The template's product manifest and its runtime feature kill switch are adopted. The route registry is deliberately not composed from contract.routes: the reference feature still declares screens this product deleted, and reducing over them would register paths with no component behind them. ROUTE_FEATURE_OWNER is narrowed to registered routes for the same reason. The first resolution did compose from contract.routes and was rejected by product-features.test.ts. Three files pinned counts and a digest describing the gate contract. Neither side's numbers describe the merged config/ci/gates.json, so they were recomputed from it rather than chosen: 27 gates, 82 commands, 94 command references, 107 evidence references, 128 artifacts, shape sha256 5063586d. README.md and docs/accessibility/manual-checklist.md now enumerate this product's 27 routes, which the template's own verify:documentation requires. product-feature-switch.test.tsx was rewritten around the invariant that still applies here — no registered route without a component — rather than deleted with the screens it used to exercise. docs/operations/template-merge-2026-08-17.md records every decision, the gate results, and the three follow-ups this merge deliberately did not decide. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
192 lines
8.8 KiB
Markdown
192 lines
8.8 KiB
Markdown
# Tech Log Frontend
|
|
|
|
Initialized from `clean-architecture-frontend-template` revision
|
|
`4dc033cf33a5b6173bbf960d5eb464a406dc4c92`. The exact source identity is
|
|
recorded in `template.lock.json`.
|
|
|
|
A React/Vite TechLog application where architecture boundaries, integration
|
|
behavior, release coherence, accessibility, performance, and operations are
|
|
executable contracts rather than conventions.
|
|
|
|
## Start locally
|
|
|
|
Requirements: the exact Node.js version in `.nvmrc` (currently 24.14.0) and
|
|
Corepack. The repository pins pnpm in `package.json`.
|
|
|
|
Product source, tests, build/quality scripts, and supported tool configuration
|
|
are TypeScript/TSX. `allowJs` is disabled. Node-side `.ts` scripts run directly
|
|
on the pinned Node 24 runtime and are checked with NodeNext resolution plus
|
|
erasable-syntax enforcement. Project-owned executable source contains no
|
|
JavaScript-family files; negative architecture, security, and type-compatibility
|
|
fixtures are TypeScript/TSX as well.
|
|
|
|
```bash
|
|
corepack pnpm install --frozen-lockfile
|
|
corepack pnpm dev
|
|
```
|
|
|
|
Runtime-public settings live in `public/config.json` and are validated before
|
|
the product tree mounts. Client secrets are forbidden.
|
|
|
|
## TechLog experience
|
|
|
|
The default build mounts the source-faithful TechLog Public and Studio
|
|
experience. Public routes provide discovery, search, documents, topics,
|
|
projects, releases, and profile content. `/studio` provides the session-scoped
|
|
mock authoring workflow: create, edit, validate, preview, publish, unpublish,
|
|
and immutable publication history.
|
|
|
|
The 27 canonical route definitions are divided into `PUBLIC` and `STUDIO`
|
|
nested layouts. Studio authentication remains deliberately deferred; its mock
|
|
gateway state lasts for one Studio shell session and resets on a full document
|
|
load. The exact route, dependency, stylesheet, asset, and parity inventory is
|
|
recorded in
|
|
[`docs/operations/techlog-ui-migration-baseline.md`](docs/operations/techlog-ui-migration-baseline.md).
|
|
|
|
`corepack pnpm build` emits a self-contained `dist/server.mjs` production
|
|
boundary. `corepack pnpm preview --host 127.0.0.1 --port 4174` serves known
|
|
Public and Studio routes as SPA documents, preserves the in-shell Studio 404,
|
|
and returns source-exact raw `404 text/plain` responses for missing Public
|
|
content. With the read-only source temp-copy server on `4375`, run:
|
|
|
|
```bash
|
|
TECH_LOG_SOURCE_URL=http://127.0.0.1:4375 \
|
|
TECH_LOG_TARGET_URL=http://127.0.0.1:4174 \
|
|
corepack pnpm verify:tech-log-source-parity
|
|
```
|
|
|
|
## Architecture
|
|
|
|
Dependencies point inward:
|
|
|
|
```text
|
|
presentation -> application -> domain
|
|
adapters -----^
|
|
bootstrap composes concrete adapters
|
|
contracts own cross-cutting registries
|
|
```
|
|
|
|
See `docs/architecture/overview.md`, `docs/architecture/layers.md`, and
|
|
`docs/architecture/starter-experience.md`. TechLog is one feature boundary
|
|
under `src/features/tech-log`. Its immutable Public catalog and session-scoped
|
|
Studio mock gateway are injected through the application feature input;
|
|
Public and Studio presentation code shares the typed content renderer without
|
|
importing concrete adapters. The retained reference feature remains a
|
|
non-product platform contract fixture and can be removed without changing the
|
|
TechLog route set.
|
|
|
|
### Platform capability review
|
|
|
|
The starter shell is implemented, but the repository review also records the
|
|
remaining work required before feature teams can use every declared contract
|
|
through one end-to-end application path:
|
|
|
|
- [platform capability review](docs/architecture/frontend-platform-capability-review.md)
|
|
- [ports, adapters, and feature boundaries](docs/architecture/frontend-ports-adapters-and-boundaries.md)
|
|
- [REST, GraphQL, Connect/gRPC-Web, Schema, Mapper, and Server State](docs/architecture/api-contract-schema-mapper-and-server-state.md)
|
|
- [Protobuf browser transports and REST Gateway](docs/architecture/protobuf-browser-transport-and-rest-gateway.md)
|
|
- [backend API and Server State handoff contract](docs/architecture/backend-api-and-server-state-contract.md)
|
|
- [TypeScript, state ownership, and data flow](docs/architecture/typescript-state-and-data-flow.md)
|
|
- [routing, page templates, and reusable patterns](docs/architecture/routing-pages-and-patterns.md)
|
|
- [browser data capability completion ledger](docs/architecture/browser-data-capability-completion-ledger.md)
|
|
- [browser file and origin-storage platform](docs/architecture/browser-file-and-origin-storage.md)
|
|
- [client cache and storage](docs/architecture/client-cache-and-storage.md)
|
|
- [realtime events, Web Push, and bounded polling](docs/architecture/realtime-events-web-push-and-bounded-polling.md)
|
|
- [presigned transfer, resumable upload, streaming download, and Image CDN](docs/architecture/presigned-transfer-and-image-cdn.md)
|
|
- [server file capability infrastructure](docs/architecture/server-file-capability-infrastructure.md)
|
|
- [design-system platform](docs/styling/design-system-platform.md)
|
|
- [frontend platform testing strategy](docs/testing/frontend-platform-testing-strategy.md)
|
|
- [implementation roadmap](docs/architecture/frontend-platform-implementation-roadmap.md)
|
|
|
|
These documents distinguish repository defaults from opt-in adapters and
|
|
project-owned integrations. They are target designs and review findings; a
|
|
capability is not treated as implemented until its branch acceptance criteria
|
|
and executable gates pass.
|
|
|
|
## Verification
|
|
|
|
Common local checks:
|
|
|
|
```bash
|
|
corepack pnpm lint
|
|
corepack pnpm check:types
|
|
corepack pnpm check:types:app
|
|
corepack pnpm check:types:node
|
|
corepack pnpm check:types:test
|
|
corepack pnpm check:architecture
|
|
corepack pnpm test:all
|
|
corepack pnpm test:e2e
|
|
corepack pnpm test:a11y
|
|
corepack pnpm build
|
|
corepack pnpm check:bundle
|
|
corepack pnpm test:performance
|
|
corepack pnpm verify:compatibility
|
|
corepack pnpm verify:release
|
|
corepack pnpm check:registries
|
|
corepack pnpm drill:runbooks
|
|
corepack pnpm check:ci
|
|
corepack pnpm exec vitest run tests/features/tech-log
|
|
corepack pnpm exec playwright test tests/e2e/tech-log-public-discovery.spec.ts tests/e2e/tech-log-studio-workflow.spec.ts tests/e2e/tech-log-responsive.spec.ts tests/e2e/tech-log-accessibility.spec.ts --project=chromium
|
|
corepack pnpm test:visual
|
|
```
|
|
|
|
`check:types`는 source, Node scripts/config와 tests를 분리된 TypeScript
|
|
project로 모두 검사한다. type/architecture/security/registry의 invalid
|
|
fixture는 `config/ci/gates.json`에서 “실패해야 통과”하는 negative gate로
|
|
실행된다. 도구 호환성 결정은
|
|
[VD-01](docs/architecture/decisions/VD-01-typescript-lint-tooling.md)에 기록돼
|
|
있다.
|
|
|
|
Application feature input은 module augmentation으로 닫힌 ID와 정확한 input
|
|
shape를 제공하며, 공통 `Result<Value, Failure = AppFailure>`는 error registry의
|
|
failure kind만 application/presentation 경계를 통과시킨다. Architecture gate는
|
|
TypeScript/TSX의 static, dynamic, type import를 별도 정적 그래프로 분석하고
|
|
runtime/source 영역의 JavaScript 재유입도 거절한다. 해석되지 않은 import,
|
|
parse failure, 금지 계층 edge와 순환 의존은 모두 fail-closed이며 전용
|
|
TypeScript/TSX negative fixture로도 검증된다.
|
|
|
|
Install the pinned Playwright browser engines before the first cross-browser
|
|
run:
|
|
|
|
```bash
|
|
corepack pnpm exec playwright install --with-deps chromium firefox webkit
|
|
```
|
|
|
|
Two gates intentionally need external evidence:
|
|
|
|
- `review:a11y-manual` needs a signed human keyboard/focus/screen-reader review
|
|
for all 27 registered routes:
|
|
`NOT_FOUND`, `TECH_LOG_CASE`, `TECH_LOG_EXPLORE`, `TECH_LOG_EXPLORE_KIND`,
|
|
`TECH_LOG_HOME`, `TECH_LOG_PROFILE`, `TECH_LOG_PROJECT`,
|
|
`TECH_LOG_PROJECTS`, `TECH_LOG_PROJECT_ACTIVITY`,
|
|
`TECH_LOG_PROJECT_DECISIONS`, `TECH_LOG_PROJECT_RECORDS`,
|
|
`TECH_LOG_QUESTION`, `TECH_LOG_REFERENCE`, `TECH_LOG_RELEASE`,
|
|
`TECH_LOG_RELEASES`, `TECH_LOG_SEARCH`, `TECH_LOG_STUDIO_DOCUMENTS`,
|
|
`TECH_LOG_STUDIO_DOCUMENT_EDIT`, `TECH_LOG_STUDIO_DOCUMENT_NEW`,
|
|
`TECH_LOG_STUDIO_DOCUMENT_PREVIEW`, `TECH_LOG_STUDIO_DOCUMENT_PUBLISH`,
|
|
`TECH_LOG_STUDIO_DOCUMENT_VALIDATION`, `TECH_LOG_STUDIO_HOME`,
|
|
`TECH_LOG_STUDIO_NOT_FOUND`, `TECH_LOG_STUDIO_PUBLICATIONS`,
|
|
`TECH_LOG_STUDIO_PUBLICATION_PREVIEW`, `TECH_LOG_TOPIC`.
|
|
`verify:documentation` derives that list from the route registry and fails if
|
|
this paragraph falls behind it.
|
|
- `collect:web-vitals-evidence` stays `FAIL_UNVERIFIED` until a reviewed minimum
|
|
eligible-sample threshold and 28 days of production data exist.
|
|
|
|
Live release verification additionally requires `HOSTING_BASE_URL`.
|
|
|
|
## CI and evidence
|
|
|
|
The 26-gate registry is `config/ci/gates.json`; the Gitea workflow is
|
|
`.gitea/workflows/quality-gates.yml`. It follows:
|
|
|
|
```text
|
|
MERGE_READY -> RELEASE_READY -> PROD_PROMOTION_READY -> FIELD_SLO_READY
|
|
```
|
|
|
|
`DOCUMENTATION_READY` is independent. No gate is downgraded to a warning.
|
|
Machine-readable evidence is written below `artifacts/`; generated evidence is
|
|
ignored by Git while `.gitkeep` files preserve the taxonomy.
|
|
|
|
Operational details are in `docs/operations/`, with incident procedures in
|
|
`docs/runbooks/`.
|