본문으로 건너뛰기

System Architecture — HeyMoa

⚠︎ 지난 판 — 2026-08-03. 현재 판은 여기다. 이 문서는 그때의 기록이고 고치지 않는다.

이 판은 사이트 버저닝을 보이려고 채운 자리다. 그날 실제로 쓰인 문서가 아니고, 앞뒤 판과 그 사이의 결정 기록에서 끌어와 재구성했다. 지우거나 진짜 기록으로 갈아끼워도 된다.

갱신일 2026-08-03 · 기준: 세 저장소 워킹트리 + 결정 원장 (ADR 0005·0006·0007) 이 문서가 갖는 것: 액터, 컨테이너, 외부 시스템, 경계별 프로토콜·인증, 확장 천장. 여기 없는 것: 화면(information-architecture) · 내부 모듈(application-architecture) · AWS 리소스(cloud-architecture).

확인한 사실

경계 다섯

#구간프로토콜인증
web → serverREST /v1/**access_token HttpOnly 쿠키
web ↔ serverSTOMP over WebSocket쿠키 (핸드셰이크)
web ← serverSSE (POST 응답이 text/event-stream)쿠키
server → aiREST /internal/v1/** + SSE 소비없음 — 보안그룹 하나가 막고 있다
ai → serverREST /internal/v1/**X-Internal-Token

④는 2026-07-26 판에서 "미확인"으로 두었던 항목이다. 그 뒤 운영 형상을 확인해 네트워크로만 막혀 있다는 것이 사실로 굳었다. 애플리케이션 인증은 여전히 없다.

같은 시크릿을 양쪽이 다른 이름의 환경변수로 읽는다 — server는 INTERNAL_API_TOKEN, ai는 INTERNAL_TOKEN. 회전할 때 두 이름을 같이 봐야 한다.

7월 말에 굳은 런타임 상수 셋

무엇값·규칙원장
checkpoint 커넥션안정화 인자 넷(pool pre-ping · recycle · timeout · statement timeout)을 줄이지 않는다. 하나라도 빼면 유휴 커넥션이 끊긴 뒤 채팅이 죽는다ADR 0005
분석 동시 실행상한을 두지 않는다. 회의 종료가 몰리는 일이 실측되지 않았고, 상한은 큐 지연을 숨긴다ADR 0006
OpenAI 호출Responses API로 부르되 서버에 상태를 남기지 않는다. 대화 상태는 우리 checkpoint가 갖는다ADR 0007

확장 천장

앱 인스턴스 1개가 기능 정확성의 조건이다. 전사 팬아웃이 enableSimpleBroker — JVM 내부 브로커다. 인스턴스를 둘로 늘리면 다른 인스턴스에 붙은 참가자에게 이벤트가 안 간다. 에러도 안 난다. 조용히 반쪽만 간다.

넘으려면 외부 브로커(Redis Pub/Sub·RabbitMQ STOMP relay)를 먼저 세워야 한다. 지금은 필요가 실측되지 않았다.

설계 전제

  • server가 유일한 public edge다. ai는 인증도 CORS도 구현하지 않는다.
  • 브로커가 없다. 비동기는 DB row와 HTTP callback으로 처리한다.
  • SSE는 변환 없이 통과시킨다. 변환을 시작하는 순간 계약이 둘로 갈라진다.
  • 외부 의존은 소유자가 하나씩만 진다. 음성·OAuth는 server, LLM·관측은 ai.

미확인

무엇지금 아는 것어디를 봐야 하나
④에 애플리케이션 인증을 붙일지보안그룹만으로 막고 있다는 것까지결정 필요 — ADR 자리
ai의 운영 base-url 실주입값저장소에는 로컬 기본값만 있다EC2의 .env.prod
분석 완료 push 채널설계 스펙은 STOMP push, 구현은 폴링이다스펙 정정과 push 구현 중 택일