<a id="http-web"></a>
# HTTP server·SSE·Web UI 모듈

Go `http.ServeMux`가 261개 API operation을 등록하고 `/api/*`에 CORS와 JWT wrapper를 적용한 뒤, 나머지 경로에는 embedded Next.js static export를 제공한다. Web client는 `web/src/lib/api.ts`의 fetch helper와 여러 SSE 경로로 같은 API를 소비한다. Operation 전수는 [API 독립 진입](../contracts/http-ui.md#route-families), source provider는 [58개 handler group](http-handlers.md#http-handler-providers), request/response는 [semantic schema](../contracts/api/schema-reference.md#api-schema-reference)를 본다.

<a id="router"></a>
## Router와 middleware

```mermaid
flowchart TD
  Request[HTTP request] --> Root{path}
  Root -->|/api/*| CORS[CORS]
  CORS --> Auth[requireAuth]
  Auth -->|auth/* or health| Public[public handler]
  Auth -->|valid JWT| Mux[API ServeMux]
  Auth -->|missing/invalid| E401[JSON 401]
  Root -->|other| UI[embedded static UI handler]
  Mux --> JSON[JSON/file response]
  Mux --> SSE[SSE stream]

  click Auth "../security-boundaries.md#auth-boundary" "인증 경계"
  click Mux "../contracts/http-ui.md#route-families" "API 영역"
  click UI "#ui-routes" "UI route"
```

`/api/auth/*`와 `/api/health`는 wrapper 예외다. `change-password`는 예외 route 안에서 token과 현재 password를 직접 검증한다. 그 외 `/api/*`는 Bearer, `artex_token` cookie 또는 query `token` 중 하나를 읽는다. UI static file 자체는 공개이며 데이터 권한은 API가 강제한다. [Router](evidence:http-routes) [Auth](evidence:auth)

<a id="http-completion"></a>
## 응답과 후속 완료

| 응답 형태 | 의미 | 추가 확인 |
|---|---|---|
| 일반 2xx JSON | 해당 handler의 동기 단계 완료 | background engine/worker/external delivery가 남는지 operation별 확인 |
| archive/action queue 응답 | persistent job 접수 | archive `state/phase/progress/error` |
| task create response | task row/runtime launch 요청 | admission queue, goal decomposition, engine 상태 |
| chat/message response | session 실행 경로의 handler 결과 | activity/terminal/cancel 상태 |
| SSE open | stream 연결과 cursor 전달 | 최종 event/재연결·gap 처리 |
| file/download | server가 bytes를 전송 | client 저장·외부 제출 완료는 아님 |
| update apply/rollback | stage/restart protocol 시작 | supervisor relaunch와 settle/rollback |

<a id="sse"></a>
## SSE cursor와 인증

Activity, logs, update, side-question event 등은 장기 HTTP stream을 사용한다. frontend `EventSource`는 이 네 경로에 query token을 붙이며 reverse proxy buffering을 꺼야 실시간 event가 보인다. 서버 `extractToken`의 query fallback은 SSE 외 보호 API에도 적용된다. History endpoint와 cursor를 함께 사용해 reconnect gap을 채우는 경로가 있고, UI의 현재 화면 auto-refresh가 서버 event 보존 전체를 대신하지 않는다. [Activity stream](evidence:activity-stream)

Query token은 URL/access log/referrer 노출 가능성이 있어 HTTPS와 log redaction이 필요하다. Same-origin production과 cross-origin development의 CORS/cookie 동작을 구분한다.

<a id="ui-routes"></a>
## Next.js 사용자 영역

| UI 영역 | 주요 route | 소비 API/상태 |
|---|---|---|
| setup/login | `/setup`, `/login` | auth status/init/login, local token |
| dashboard | `/dashboard` | stats, token usage, recent task/activity |
| tasks | `/function/tasks`, detail | task CRUD/control, goals/constraints, sessions, graph, coverage, archive |
| findings | `/function/findings` | finding groups/tree/detail/retest/evidence/export |
| assets | `/function/assets` | assets, companies/scope, ScopeSentry sync |
| traffic | `/function/traffic` | exchange filters/detail/body/delete |
| chat | `/chat` | conversations/messages/side questions/uploads |
| agents/tools/skills/MCP | system pages | runtime catalog, prompts, visibility, triggers |
| LLM/settings | system pages | profiles/pool/retry/search/proxy/update/config |
| intercept/asset intercept | system pages | rules, pending/history/execution/judge |
| notifications/logs/records | system pages | channel/delivery, logs, LLM records/usage |

화면 route는 API operation이나 authorization boundary가 아니다. 같은 API를 다른 화면과 agent tool이 소비할 수 있고, UI에 노출되지 않은 route도 등록돼 있다. 27개 `page.tsx` entry와 화면별 wrapper/API/SSE/state/error 소비는 [프런트엔드 소비 지도](../contracts/api/frontend-consumers.md#frontend-screens)가 소유한다. [Web API client](evidence:web-api) [Web layout](evidence:web-layout)

<a id="client-state"></a>
## Client token·cache·navigation

Frontend auth helper는 token을 localStorage와 JavaScript-readable cookie에 저장한다. API helper가 Authorization header를 구성하고, SSE는 필요할 때 query token을 사용한다. Cookie에는 HttpOnly를 적용할 수 없고 Secure 여부도 배포 경로에 따라 달라져 XSS·HTTP 배포 위험을 고려해야 한다. [Web auth](evidence:web-auth)

Task detail의 polling/SSE, finding/traffic pagination, graph UI의 local expansion은 view state다. 서버 DB state와 충돌하면 새 fetch/stream cursor를 기준으로 다시 확인해야 한다.

<a id="code-first-contract"></a>
## Code-first API 계약의 한계

저장소에는 OpenAPI/GraphQL/proto 명세가 없다. 실제 등록 route, inline request struct, DTO/JSON marshal, handler error branch와 web client type이 계약 원본이다. [API 전수 참조](../contracts/http-ui.md#route-families)는 등록 261개를, [요청·응답 semantic 참조](../contracts/api/schema-reference.md#api-schema-reference)는 field와 직접 variant를 모두 목적지로 제공한다. 다음은 P/U 표시와 원본 대조가 필요하다.

- helper 함수 안의 추가 validation/status
- inline JSON struct의 생략/null/default와 unknown field 처리
- response DTO와 map의 조건부 필드
- async job의 후속 오류·재시도
- frontend TypeScript type과 server JSON의 차이
- runtime configuration에 따른 route 효과

<a id="http-failures"></a>
## 실패 조건

- `/api/health` 성공은 DB/LLM/MCP/target/proxy readiness 전체를 뜻하지 않는다.
- API auth가 있어도 UI static file 자체와 page bundle은 공개될 수 있다.
- SSE connection success를 작업 완료로 해석하면 안 된다.
- browser token 저장 방식은 XSS 발생 시 탈취 면을 만든다.
- reverse proxy가 SSE를 buffer하거나 timeout하면 backend가 정상이어도 UI가 멈춘 것처럼 보인다.
- operation의 method/path만으로 요청 schema와 side effect를 추론하지 말고 handler/DTO를 확인한다.
