feat: web, websocket 어댑터 추가 구현
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
f145f6b13d665c52edd061695fd384825891ea6146946c81dae438c1cb9ee4c3 README.md
|
||||
bceb2d92489db305aa07f9f6a51fe6cb40e9971cee600275887192caff220e31 VALIDATION.md
|
||||
fdc801db5190213d213eb59e16a289acd22096bcdba4cd1b3e89ca98a1af45a2 docs/superpowers/plans/2026-08-14-websocket-advanced-capabilities-expansion-plan.md
|
||||
97969421447fc3b54ca5b18baacd13e84ebad1e2c8ab054a977e488daba02e4c docs/superpowers/plans/2026-08-14-websocket-realtime-connection-platform-implementation-plan.md
|
||||
8a49c95ef8bec0312ca028f80302332ef811c12d578ff8a89b7843c966f44ff9 docs/superpowers/specs/2026-08-14-websocket-realtime-connection-platform-design.md
|
||||
57dedc7fd8e6f5de96a61a7295a1d4b474507cdd9029760e1907f5f47abc6de8 research/source-websocket-deep-research.md
|
||||
459a713434fa74c7182b947fdf79d6b89a7aa9c7f5070d26903744bc722be5b1 validate_websocket_docs.py
|
||||
@@ -0,0 +1,28 @@
|
||||
# WebSocket Superpowers Package
|
||||
|
||||
이 패키지는 WebSocket 실시간 양방향 연결 실행 플랫폼의 설계서, Stable 구현 계획, Advanced 확장 계획, 요구사항 원본과 정적 검증 도구를 포함한다.
|
||||
|
||||
## 적용 순서
|
||||
|
||||
```text
|
||||
Stable Task 1–53
|
||||
→ Stable Release Gate
|
||||
→ Advanced Task 1–22
|
||||
→ 기능별 Promotion Gate
|
||||
```
|
||||
|
||||
## 문서
|
||||
|
||||
- `docs/superpowers/specs/2026-08-14-websocket-realtime-connection-platform-design.md`
|
||||
- `docs/superpowers/plans/2026-08-14-websocket-realtime-connection-platform-implementation-plan.md`
|
||||
- `docs/superpowers/plans/2026-08-14-websocket-advanced-capabilities-expansion-plan.md`
|
||||
- `research/source-websocket-deep-research.md`
|
||||
|
||||
## 검증
|
||||
|
||||
```bash
|
||||
python validate_websocket_docs.py
|
||||
sha256sum -c MANIFEST.sha256
|
||||
```
|
||||
|
||||
이 검증은 문서 구조·계약 일관성·패키지 무결성 검증이며 실제 Gradle compile, Browser, Nginx, Container, Fault, Performance 실행을 대체하지 않는다.
|
||||
@@ -0,0 +1,47 @@
|
||||
# WebSocket Superpowers 문서 정적 검증 결과
|
||||
|
||||
- **검증일:** 2026-08-14
|
||||
- **검증 명령:** `python validate_websocket_docs.py`
|
||||
- **검증 출력:** `checks=719 passed=719 failed=0`
|
||||
- **결과:** PASS
|
||||
|
||||
## 문서 규모
|
||||
|
||||
| 문서 | 행 | Task | Create 경로 |
|
||||
|---|---:|---:|---:|
|
||||
| 설계서 | 2,810 | - | - |
|
||||
| Stable 구현 계획 | 4,293 | 53 | 121 |
|
||||
| Advanced 확장 계획 | 1,817 | 22 | 48 |
|
||||
|
||||
## 검증 항목
|
||||
|
||||
- Stable Task 1–53 번호 연속성
|
||||
- Advanced Task 1–22 번호 연속성
|
||||
- 모든 Task의 `Files`, `Interfaces`, `Implementation requirements`, Step 1–5, commit 명령
|
||||
- Stable·Advanced Create 경로 중복 및 충돌 부재
|
||||
- `TODO`, `TBD`, `FIXME` placeholder 부재
|
||||
- Markdown code fence 균형
|
||||
- Stable Raw Typed JSON·Evidence·Ticket·Queue·Runtime·Nginx·Browser 계약 포함
|
||||
- Advanced Resume·Cluster·STOMP·Broker Relay·Binary·Compression·HTTP/2·3 계약 포함
|
||||
- 요구사항 원본 Appendix 및 research file 보존
|
||||
- SHA-256 manifest와 ZIP CRC 검증 가능 구조
|
||||
|
||||
## 검증 범위의 한계
|
||||
|
||||
현재 검증은 설계서와 구현 계획서의 정적 구조·내부 계약·패키지 무결성 검증이다. 실제 Backend Skeleton 저장소가 제공되지 않았으므로 다음은 실행하지 않았다.
|
||||
|
||||
```text
|
||||
Gradle configuration·compile
|
||||
Spring Boot ApplicationContext
|
||||
Tomcat·Jetty·Reactor Netty WebSocket contract
|
||||
Nginx TLS Upgrade path
|
||||
Chromium·Firefox·WebKit browser matrix
|
||||
Redis ticket·session index integration
|
||||
JPA result ledger transaction
|
||||
Messaging replay/fan-out
|
||||
Commit 후 socket reset fault
|
||||
Slow consumer·memory·latency performance
|
||||
STOMP·RabbitMQ broker relay
|
||||
HTTP/2·HTTP/3 compatibility
|
||||
Git commit
|
||||
```
|
||||
+1817
File diff suppressed because it is too large
Load Diff
+4293
File diff suppressed because it is too large
Load Diff
+2810
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
from __future__ import annotations
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
root = Path(__file__).resolve().parent
|
||||
if (root / 'docs').exists():
|
||||
design = root / 'docs/superpowers/specs/2026-08-14-websocket-realtime-connection-platform-design.md'
|
||||
stable = root / 'docs/superpowers/plans/2026-08-14-websocket-realtime-connection-platform-implementation-plan.md'
|
||||
advanced = root / 'docs/superpowers/plans/2026-08-14-websocket-advanced-capabilities-expansion-plan.md'
|
||||
else:
|
||||
design = Path('/mnt/data/websocket-realtime-connection-platform-design.md')
|
||||
stable = Path('/mnt/data/websocket-realtime-connection-platform-implementation-plan.md')
|
||||
advanced = Path('/mnt/data/websocket-advanced-capabilities-expansion-plan.md')
|
||||
|
||||
checks = []
|
||||
def check(name, condition):
|
||||
checks.append((name, bool(condition)))
|
||||
|
||||
for path in (design, stable, advanced):
|
||||
check(f'exists:{path.name}', path.exists())
|
||||
if not path.exists():
|
||||
continue
|
||||
text = path.read_text(encoding='utf-8')
|
||||
check(f'code-fence:{path.name}', text.count('```') % 2 == 0)
|
||||
check(f'no-placeholders:{path.name}', not re.search(r'\b(TODO|TBD|FIXME)\b', text))
|
||||
check(f'nontrivial:{path.name}', len(text.splitlines()) > 300)
|
||||
|
||||
stable_text = stable.read_text(encoding='utf-8')
|
||||
advanced_text = advanced.read_text(encoding='utf-8')
|
||||
design_text = design.read_text(encoding='utf-8')
|
||||
|
||||
stable_tasks = [int(n) for n in re.findall(r'^### Task (\d+):', stable_text, re.M)]
|
||||
advanced_tasks = [int(n) for n in re.findall(r'^### Task (\d+):', advanced_text, re.M)]
|
||||
check('stable-task-sequence', stable_tasks == list(range(1, 54)))
|
||||
check('advanced-task-sequence', advanced_tasks == list(range(1, 23)))
|
||||
|
||||
for label, text, expected in [('stable', stable_text, 53), ('advanced', advanced_text, 22)]:
|
||||
sections = re.split(r'(?=^### Task \d+:)', text, flags=re.M)[1:]
|
||||
check(f'{label}-task-count', len(sections) == expected)
|
||||
for idx, section in enumerate(sections, 1):
|
||||
for token in ['**Files:**', '**Interfaces:**', '**Implementation requirements:**',
|
||||
'Step 1:', 'Step 2:', 'Step 3:', 'Step 4:', 'Step 5:',
|
||||
'git commit -m']:
|
||||
check(f'{label}-task-{idx}-{token}', token in section)
|
||||
|
||||
create_pattern = re.compile(r'^- Create: `([^`]+)`', re.M)
|
||||
stable_paths = create_pattern.findall(stable_text)
|
||||
advanced_paths = create_pattern.findall(advanced_text)
|
||||
check('stable-create-unique', len(stable_paths) == len(set(stable_paths)))
|
||||
check('advanced-create-unique', len(advanced_paths) == len(set(advanced_paths)))
|
||||
check('stable-advanced-create-disjoint', set(stable_paths).isdisjoint(set(advanced_paths)))
|
||||
|
||||
required_design = [
|
||||
'Inbound Evidence', 'Outbound Evidence', 'Connection Evidence',
|
||||
'hyeonworks.realtime.v1.json', 'ONE_TIME_TICKET',
|
||||
'APPLICATION_COMMITTED', 'WRITTEN_LOCALLY',
|
||||
'Outbound Queue·Backpressure', 'Nginx', 'Tomcat', 'Jetty',
|
||||
'Reactor Netty', 'WebSocket exactly-once', 'Appendix A'
|
||||
]
|
||||
for token in required_design:
|
||||
check(f'design-token:{token}', token in design_text)
|
||||
|
||||
required_stable = [
|
||||
'Commit 후 Response Loss', 'Slow Consumer', 'Browser Matrix',
|
||||
'MVC·WebFlux Stack 상호 배타성', 'Stable Release Gate'
|
||||
]
|
||||
for token in required_stable:
|
||||
check(f'stable-token:{token}', token in stable_text)
|
||||
|
||||
required_advanced = [
|
||||
'Resume Token', 'Messaging 기반 Durable Replay', 'STOMP 1.2',
|
||||
'RabbitMQ STOMP Broker Relay', 'HTTP/3 WebSocket Experimental',
|
||||
'GraphQL WebSocket Transport Bridge'
|
||||
]
|
||||
for token in required_advanced:
|
||||
check(f'advanced-token:{token}', token in advanced_text)
|
||||
|
||||
failed = [name for name, ok in checks if not ok]
|
||||
print(f'checks={len(checks)} passed={len(checks)-len(failed)} failed={len(failed)}')
|
||||
for name in failed:
|
||||
print('FAIL', name)
|
||||
sys.exit(1 if failed else 0)
|
||||
Reference in New Issue
Block a user