feat: 기능 추가 과정중
This commit is contained in:
@@ -157,19 +157,19 @@ CI gate를 통과하게 한다. 애플리케이션 전체를 일괄 변환하지
|
||||
|
||||
- root, application/source, tests용 TypeScript project/reference를 분리한다.
|
||||
- `src`, `tests`, `scripts`의 허용 확장자와 build output 제외 범위를 명시한다.
|
||||
- ESLint, dependency-cruiser, registry scanner와 architecture script의 JS-only
|
||||
glob 및 `.js` 고정 경로를 JS/TS 양쪽으로 확장한다.
|
||||
- ESLint, dependency-cruiser, registry scanner와 architecture script의 검색
|
||||
범위를 TS/TSX source와 fixture로 통일한다.
|
||||
- Vite, Vitest와 Playwright config가 TS source/test 오류를 우회하지 않게 한다.
|
||||
- 기존 JS에는 `checkJs`, 새 TS에는 strict 정책을 적용한다.
|
||||
- 기존 fixture까지 TS/TSX로 전환하고 strict 정책을 적용한다.
|
||||
- port, registry와 forbidden import용 `.ts`/`.tsx` fixture를 추가한다.
|
||||
|
||||
**자동 테스트와 negative test**
|
||||
|
||||
- JS와 TS source/test를 함께 typecheck하는 smoke
|
||||
- TS/TSX source/test를 함께 typecheck하는 smoke
|
||||
- TSX presentation의 concrete HTTP adapter import를 architecture gate가 거절
|
||||
- 잘못된 port 구현과 discriminated union 사용이 typecheck 실패
|
||||
- TS registry row의 누락 필드, 중복 ID와 unknown reference가 gate 실패
|
||||
- 기존 JS invalid-call fixture도 계속 실패
|
||||
- 변환된 TS invalid-call fixture도 계속 실패
|
||||
- `pnpm lint`, `pnpm check:types`, `pnpm check:architecture`,
|
||||
`pnpm check:registries`, `pnpm test:all`, `pnpm build`
|
||||
|
||||
@@ -177,7 +177,7 @@ CI gate를 통과하게 한다. 애플리케이션 전체를 일괄 변환하지
|
||||
|
||||
- 허용된 모든 source/test 확장자가 typecheck, lint, architecture, registry gate
|
||||
중 필요한 검색 범위에 포함된다.
|
||||
- JS 안전망이 약해지지 않은 상태에서 TS fixture가 CI에 의해 차단된다.
|
||||
- 모든 TS/TSX negative fixture가 CI에 의해 차단된다.
|
||||
- 광범위한 unchecked cast나 임시 `any`로 통과시키지 않는다.
|
||||
- production source 대량 변환 없이 독립적으로 revert할 수 있다.
|
||||
|
||||
@@ -296,6 +296,29 @@ adapter로 연결한다.
|
||||
표준 API를 제공한다.
|
||||
- `AsyncSurface`의 모든 action이 실제 command와 검증된 state transition을 가진다.
|
||||
|
||||
**구현 증거 (2026-07-28)**
|
||||
|
||||
- installed `QUERY_REGISTRY`가 namespace와 별도의 versioned invalidation topic,
|
||||
`crossContext: "invalidate-only"`와 `persistence: "disabled"`를 소유한다.
|
||||
- `tanstack-cache-coordinator.ts`가 mutation lease, local active-query
|
||||
invalidation, remote hint coalescing, sequence-gap 전체 reconciliation과
|
||||
idempotent dispose를 구현한다.
|
||||
- production bootstrap/provider tree가 coordinator를 실제 조립한다.
|
||||
native `BroadcastChannel`을 우선하고 실패하면 exact localStorage pulse로
|
||||
fallback하며 둘 다 없으면 local-only로 degrade한다.
|
||||
- wire contract는 2,048 bytes, exact field set, release cache epoch, topic
|
||||
allowlist, TTL, self/duplicate/stale sequence를 검증하고 query key/data를
|
||||
허용하지 않는다.
|
||||
- `storage-keys.ts`와 browser storage adapter가 key별 closed value codec,
|
||||
schema/TTL, 기본 16,384-byte cap과 memory fallback envelope를 적용한다.
|
||||
- `cross-tab-invalidation.test.ts`, `tanstack-cache-coordinator.test.ts`,
|
||||
`storage-registry.test.ts`, runtime adapter/component test가 deterministic
|
||||
동작과 production wiring을 검증한다.
|
||||
- 상세 상태와 남은 session/account epoch, native multi-tab evidence 및 optional
|
||||
IndexedDB query persistence는
|
||||
[Client cache and browser storage platform](./client-cache-and-storage.md)에
|
||||
기록한다.
|
||||
|
||||
**Rollback**
|
||||
|
||||
RP-03은 application port를 유지하면서 이전 HTTP compatibility adapter 또는
|
||||
@@ -826,11 +849,11 @@ owner와 만료 시한이 있는 quarantine만 허용한다.
|
||||
사용한다.
|
||||
- 기본 Playwright는 `build` + `preview`의 실제 `dist`를 Chromium, Firefox,
|
||||
WebKit에서 검사하고 별도 compact project를 제공한다. 개발 피드백용 Vite
|
||||
profile은 `playwright.dev.config.js`로 분리했다.
|
||||
profile은 `playwright.dev.config.ts`로 분리했다.
|
||||
- Storybook public primitive story, interaction과 axe test, wide/compact/
|
||||
pseudo/dark/state surface의 pinned Chromium visual baseline 4종을 CI evidence로
|
||||
연결했다.
|
||||
- V8 coverage와 9개 high-risk module을 대상으로 40개 scoped threshold를
|
||||
- V8 coverage와 12개 high-risk module을 대상으로 52개 scoped threshold를
|
||||
적용하고 threshold 미달 fixture를 차단한다.
|
||||
- deterministic clock/random/scheduler/storage, unexpected console/page error/
|
||||
request failure 정책, 무소유 skip과 full-screen mask 금지 gate를 제공한다.
|
||||
@@ -959,10 +982,10 @@ gate 없이는 production promotion을 통과했다고 보지 않는다.
|
||||
|
||||
| recipe | 기본 경계 | 반드시 다룰 실패 |
|
||||
| --- | --- | --- |
|
||||
| realtime | subscribe/unsubscribe, reconnect, resume, heartbeat | disconnect, duplicate/out-of-order, auth expiry |
|
||||
| offline/IndexedDB | versioned repository와 migration | quota, corruption, migration rollback |
|
||||
| Service Worker/PWA | cache ownership와 update controller | stale worker, update loop, offline fallback |
|
||||
| file transfer | upload/download, progress, cancel | size/type rejection, abort, expired URL |
|
||||
| realtime | SSE/WebSocket connection + inbound event, Web Push window/worker, bounded Poll lease | disconnect, duplicate/out-of-order/gap, cursor/auth expiry, queue overflow, permission/subscription failure |
|
||||
| offline/IndexedDB/OPFS | feature repository, resumable migration, journal-backed large-object store | blocked/versionchange, quota, corruption, revision/generation conflict, partial object write |
|
||||
| Service Worker/Cache Storage | public response cache ownership와 update controller | stale worker, incomplete candidate, integrity/policy rejection, offline fallback |
|
||||
| File/Blob/picker/download | opaque file vault, upload session, browser handoff/streamed save | dismissal/permission, size/type/signature, abort/session expiry, integrity/partial save |
|
||||
| generated API | generated client를 gateway 뒤에 감싸는 facade | contract drift, unsupported field |
|
||||
| feature flag | typed key, default와 stale policy | provider unavailable, unknown flag |
|
||||
| Web Worker | request/result/cancel protocol | crash, stale result, transfer failure |
|
||||
@@ -1027,6 +1050,137 @@ revert하고 RP-11을 유지한다. 여러 vendor를 되돌릴 수 없는 한 co
|
||||
sentinel이 built `dist`에 없는지 검사한다.
|
||||
- 상세 도입/배치/검증/제거 절차는
|
||||
`docs/architecture/optional-adapter-recipes.md`에 기록했다.
|
||||
- 2026-07-27 후속 설계에서 VD-11을 추가하고 File/Blob/picker/download를
|
||||
picker/content/upload-session/download-delivery로 분리했다. IndexedDB는
|
||||
schema/codec, transaction complete, blocked/versionchange, resumable migration
|
||||
계약으로 보강하고, OPFS는 IndexedDB journal 기반 crash-safe large-object
|
||||
sub-capability, Cache Storage는 public response 전용 release-candidate
|
||||
sub-capability로 명시했다.
|
||||
- 같은 후속 구현에서 해당 browser-native sub-capability를 정책 주입형
|
||||
`AVAILABLE_NOT_COMPOSED` reference runtime으로 `src/adapters`에 구현했다.
|
||||
제품별 schema/codec/query/retention/cache allowlist는 주입하며, 선택 전에는
|
||||
bootstrap import를 정적 gate로 금지하고 실제 browser conformance suite로
|
||||
native API 경로를 검증한다.
|
||||
- `browser-file-storage-contracts.ts`와 deterministic fake/test가 CAS/idempotency,
|
||||
quota, picker dismissal, bounded range/stream, partial OPFS write visibility,
|
||||
generation conflict, cache exact query/integrity policy를 실행 가능하게 검증한다.
|
||||
reference runtime source는 존재하지만 production composition의 optional
|
||||
runtime module 수는 계속 0개이며, 실제 선택 branch는
|
||||
real-browser/fault/runbook evidence 없이 `INSTALLED`로 승격할 수 없다.
|
||||
- 2026-07-28 후속 설계와 구현에서 VD-12를 추가했다. presigned capability는
|
||||
BFF control plane과 browser/object-storage data plane을 분리하고, multipart
|
||||
upload는 server-authoritative reconcile과 non-secret IndexedDB checkpoint,
|
||||
streaming download는 bounded closed-result source, Image CDN은 opaque asset과
|
||||
named preset 기반 responsive descriptor로 구현한다. 제품 endpoint/CDN policy가
|
||||
없으므로 모두 `AVAILABLE_NOT_COMPOSED`이며 bootstrap에는 연결하지 않는다.
|
||||
- generic multi-tab recipe와 별도로, installed TanStack query의 좁은
|
||||
invalidate-only protocol은 2026-07-28 RP-03 infrastructure로 선택·조립했다.
|
||||
query state/payload를 복제하지 않고 persistence는 계속 disabled다. 기존
|
||||
IndexedDB reference runtime은 이 선택 때문에 bootstrap에 조립되지 않는다.
|
||||
- 같은 날 VD-28과
|
||||
[Realtime events, Web Push, and bounded polling](./realtime-events-web-push-and-bounded-polling.md)을
|
||||
추가했다. SSE, WebSocket, Web Push와 Polling을 별도 delivery capability로
|
||||
분리하고 공통 delivery guarantee 없음, duplicate-tolerant CURSOR 처리,
|
||||
gap/snapshot checkpoint, scope generation, bounded lifecycle과 promotion 계약을
|
||||
닫았다. 후속 RT-01~04에서 공통 authority, fetch-stream SSE, bounded Polling,
|
||||
closed WebSocket, Web Push window/worker와 단일 writer handoff/reconnect
|
||||
coordinator를 구현해 reusable runtime은 `AVAILABLE_NOT_COMPOSED`로 올렸다.
|
||||
제품 endpoint/event registry/provider selection과 production composition은
|
||||
없으므로 product는 계속 `NOT_SELECTED`다.
|
||||
- 2026-07-28 API-05/API-06 공통 선행 구현으로 Browser RPC V3 operation/provider
|
||||
registry, typed application port, provider-neutral unary/server-stream lifecycle
|
||||
coordinator와 fail-closed unavailable adapter를 추가했다. exact registry join,
|
||||
bounded retry/deadline/abort, stream idle/total/message/terminal, scope generation을
|
||||
test하므로 이 공통 층만 `AVAILABLE_NOT_COMPOSED`다. descriptor/codegen,
|
||||
Connect-Web/official grpc-web transport와 실제 proxy/browser conformance는
|
||||
포함하지 않는다.
|
||||
|
||||
### 12.1 Browser data 후속 work package
|
||||
|
||||
RP-12의 reference runtime 존재는 browser data platform 전체의 구현 완료를
|
||||
뜻하지 않는다. 현재 상태와 상세 exit criteria는
|
||||
[Browser data capability completion ledger](./browser-data-capability-completion-ledger.md)를
|
||||
단일 기준으로 사용한다. 후속 구현은 다음 독립 package로 진행한다.
|
||||
|
||||
| 순서 | work package | 핵심 exit |
|
||||
| --- | --- | --- |
|
||||
| BD-01 | scope-safe client cache | logout/account switch의 cancel/fence/clear/dispose와 late-result 차단 |
|
||||
| BD-02 | Range resumable download | precondition-mode별 allowed `200/206/412/416`, seek/truncate와 final integrity |
|
||||
| BD-03 | origin storage lifecycle | cross-store pressure/GC, bounded maintenance와 N-1 migration/rollback |
|
||||
| BD-04 | transfer operational composition | atomic config/factory, account teardown, pause/retention과 provider harness |
|
||||
| BD-05 | Image descriptor delivery | fixed BFF provider, refresh fence, safe picture projection과 actual CDN 증거 |
|
||||
|
||||
각 package는 다음 순서를 지킨다.
|
||||
|
||||
```text
|
||||
ledger + ADR accepted
|
||||
-> closed port/policy/schema
|
||||
-> deterministic contract/fault evidence
|
||||
-> reference runtime + boundary/removal gate
|
||||
-> AVAILABLE_NOT_COMPOSED
|
||||
-> product/provider selection
|
||||
-> bootstrap composition + three-engine evidence
|
||||
-> COMPOSED
|
||||
```
|
||||
|
||||
directory/persistent file handle, Query persistence, offline mutation,
|
||||
Service Worker fetch interception, private/range Cache와 app-managed background
|
||||
transfer는 위 package에 암묵적으로 포함하지 않는다. 각각 `NOT_SELECTED`에서
|
||||
별도 ADR과 owner 승인을 거쳐야 한다.
|
||||
|
||||
### 12.2 API·Schema·Mapper·Server State 후속 work package
|
||||
|
||||
REST reference vertical의 `COMPOSED` 판정과 multi-protocol production hardening을
|
||||
구분한다. 현재/목표 상태, protocol 선택 기준과 완료 조건은
|
||||
[API contract, Schema, Mapper와 Server State](./api-contract-schema-mapper-and-server-state.md)가
|
||||
소유한다. Browser Protobuf runtime과 gateway branch의 세부 기준은
|
||||
[Protobuf browser transport와 REST Gateway](./protobuf-browser-transport-and-rest-gateway.md)를
|
||||
따른다.
|
||||
|
||||
| 순서 | work package | 핵심 exit |
|
||||
| --- | --- | --- |
|
||||
| API-01 | REST v2 execution | auth fail-close/final invariant, collision-free registry, total deadline, bounded status/media decoder |
|
||||
| API-02 | typed Schema·Mapper | codec/mapper type proof, semantic fingerprint/provenance, scalar/null/enum/collection ceiling |
|
||||
| API-03 | strict Server State | bound query definition/key/policy, cursor page, mutation concurrency와 revision/CAS optimistic rollback |
|
||||
| API-04 | persisted GraphQL | allowlisted manifest, data/errors/partial state, cost/auth/CSRF와 actual router conformance |
|
||||
| API-05 | gRPC-Web | descriptor/codegen, frame/trailer/status, unary/server-stream budget와 actual proxy/browser conformance |
|
||||
| API-06 | Connect-Web | exact Connect/gRPC-Web transport row, JSON/binary/GET/EndStream, bounded decode와 actual server/browser conformance |
|
||||
| API-07 | Protobuf REST Gateway | schema/codegen provenance, HttpRule/ProtoJSON/OpenAPI와 selected gateway conformance |
|
||||
| API-08 | operations/composition | contract-set release binding, provider kill switch, coherent rollback과 protocol dependency removal |
|
||||
|
||||
API-05/API-06가 공유하는 provider-neutral registry와 lifecycle coordinator는
|
||||
`AVAILABLE_NOT_COMPOSED`다. 그러나 각 package의 wire adapter exit는 아직
|
||||
충족되지 않았으므로 API-05/API-06 전체를 완료로 표시하지 않는다.
|
||||
|
||||
GraphQL, Connect, gRPC-Web과 REST Gateway는 제품 operation/provider 선택 전
|
||||
`NOT_SELECTED`다. 설계 문서가 있다는 이유로 dependency/generated source/proxy
|
||||
config를 기본 bundle에 넣지 않는다. browser client/bidirectional streaming은
|
||||
구현 backlog가 아니라 `PLATFORM_LIMITED`이며 별도 transport 요구로 다시 설계한다.
|
||||
|
||||
권장 순서는 API-01 → API-02 → API-03이다. API-04~07은 실제 backend contract가
|
||||
선택된 branch만 구현한다.
|
||||
|
||||
### 12.3 Realtime delivery 후속 work package
|
||||
|
||||
copyable recipe의 교육용 `RealtimePort`와 fake는 production runtime 증거가
|
||||
아니다. 현재 상태,
|
||||
transport 선택, event authority와 완료 기준은
|
||||
[Realtime events, Web Push, and bounded polling](./realtime-events-web-push-and-bounded-polling.md)이
|
||||
소유한다.
|
||||
|
||||
| 순서 | work package | 핵심 exit |
|
||||
| --- | --- | --- |
|
||||
| RT-01 | common event authority | closed registry/envelope, scope generation, sequential apply, dedupe/gap/cursor와 snapshot reset |
|
||||
| RT-02 | SSE + bounded polling | bounded fetch-stream parser, reconnect/heartbeat와 visible-only single-flight Poll lease |
|
||||
| RT-03 | WebSocket | fixed subprotocol, heartbeat/close, bounded inbound/outbound queue와 resume |
|
||||
| RT-04 | Web Push | permission/subscription facade, worker push/click, safe notification와 provider lifecycle |
|
||||
| RT-05 | product composition/operations | backend replay/outbox/auth, hosting/provider/browser evidence, canary/kill switch/drill |
|
||||
|
||||
RT-01~04의 source, contract/native test, boundary/bundle/removal gate가 통과한
|
||||
runtime만 `AVAILABLE_NOT_COMPOSED`로 올린다. 실제 event/notification registry와
|
||||
provider가 bootstrap/worker에 조립된 선택 capability만 `COMPOSED`다.
|
||||
exactly-once/global ordering, always-on background connection과 timely
|
||||
cross-browser Web Push guarantee는 구현 backlog가 아니라 `PLATFORM_LIMITED`다.
|
||||
|
||||
## 11. Vendor decision gate
|
||||
|
||||
@@ -1042,6 +1196,14 @@ revert하고 RP-11을 유지한다. 여러 vendor를 되돌릴 수 없는 한 co
|
||||
| VD-08 | 10 전 | Storybook/visual 방식 | dev-only Storybook + local Playwright baseline | cloud review/별도 배포 |
|
||||
| VD-09 | 11 전 | vulnerability/license/SBOM/provenance | 임의 PASS 금지, `FAIL_UNVERIFIED` | release promotion |
|
||||
| VD-10 | 12 전 | optional capability 요구 | 설치하지 않음 | 해당 recipe만 |
|
||||
| VD-23 | API-01 전 | protocol 선택과 REST execution | operation별 protocol 고정, installed REST 유지 | REST v2 hardening |
|
||||
| VD-24 | API-02 전 | runtime Schema와 Mapper proof | typed codec → pure Result mapper | multi-protocol contract/codegen |
|
||||
| VD-25 | API-03 전 | Server State Cache lifecycle | TanStack sole owner, bound query/mutation profile | query/cache/mutation hardening |
|
||||
| VD-26 | API-04 전 | GraphQL | persisted operation only, 기본 미선택 | GraphQL operation family |
|
||||
| VD-27 | API-05 전 | gRPC-Web | unary/server-stream만, 기본 미선택 | gRPC-Web operation family |
|
||||
| VD-29 | API-06 전 | Connect-Web/Connect | exact runtime/wire profile, 기본 미선택 | Connect operation family |
|
||||
| VD-30 | API-07 전 | Protobuf/REST Gateway | current REST는 BFF 유지, direct gateway 기본 미선택 | schema/codegen/gateway branch |
|
||||
| VD-28 | RT-01 전 | realtime/Web Push/Polling | focus refetch 우선, transport별 opt-in과 bounded fallback | realtime delivery capability |
|
||||
|
||||
각 decision에는 실제 요구, bundle/runtime/a11y/security 영향, local facade 방식,
|
||||
대안, fallback/migration/removal, owner와 재검토 시점을 기록한다.
|
||||
@@ -1054,7 +1216,7 @@ revert하고 RP-11을 유지한다. 여러 vendor를 되돌릴 수 없는 한 co
|
||||
|
||||
| checkpoint | 포함 범위 | 다음 단계 진입 조건 | 대표 rollback 사유 |
|
||||
| --- | --- | --- | --- |
|
||||
| RP-01 | tooling | TS/JS fixture와 gate 통과 | TS 파일이 검사에서 누락 |
|
||||
| RP-01 | tooling | TS/TSX fixture와 gate 통과 | TS 파일이 검사에서 누락 |
|
||||
| RP-02 | application boundary | composition integration 통과 | UI가 raw adapter에 의존 |
|
||||
| RP-03 | HTTP/query | request/state negative matrix 통과 | query 손실, retry/submit 폭주 |
|
||||
| RP-04 | routing/recovery | registry와 reload-loop drill 통과 | invalid URL API 호출, reload loop |
|
||||
|
||||
Reference in New Issue
Block a user