feat: web, websocket 어댑터 추가 구현

This commit is contained in:
DongHyeonka
2026-08-28 17:01:27 +09:00
parent 0137263441
commit a24ece9cf7
883 changed files with 100584 additions and 2623 deletions
@@ -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 153
→ Stable Release Gate
→ Advanced Task 122
→ 기능별 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 153 번호 연속성
- Advanced Task 122 번호 연속성
- 모든 Task의 `Files`, `Interfaces`, `Implementation requirements`, Step 15, 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
```
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)