본문으로 건너뛰기

시스템 아키텍처 — 3-서비스 설계 확정

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

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

갱신일 2026-07-22 · 기준: 2026-07-21-heymoa-service-contracts-design.md + 그날의 결정 둘 이 문서가 갖는 것: 서비스를 왜 셋으로 갈랐고, 무엇이 무엇과 어떤 프로토콜로 붙는가. 아직 구현 실측이 아니다 — 계약과 결정만 있고 돌아가는 코드로 확인한 것은 다음 판부터다.

확인한 사실

서비스 셋

서비스무엇을 진다왜 따로
web화면, 마이크 캡처브라우저 능력이 필요하고 서버와 수명주기가 다르다
server인증·권한·도메인 상태·외부 OAuthpublic edge를 혼자 진다. 감사와 잠금이 한 곳에 모여야 한다
aiLLM 실행, 전사 분석초 단위로 느리고 실패율이 다르다. 같은 프로세스면 요청 스레드를 묶는다

그날 정해진 것 둘

결정무엇원장
분석 실행 엔진브로커를 두지 않고 in-process 큐 + LangGraph fan-out으로 돌린다. 잡 상태는 DB row가 갖는다ADR 0001
관측LLM 실행 추적은 Langfuse. 키가 있을 때만 붙는다ADR 0002

비동기를 어떻게 끊는가

분석은 동기로 기다리지 않는다. server가 ai에 던지면 ai는 202로 즉시 끊고, 끝나면 X-Internal-Token을 달고 server의 내부 API로 callback 한다. 채팅은 반대로 SSE를 변환 없이 통과시킨다 — server가 이벤트를 재해석하지 않으므로 web 구간과 ai 구간의 포맷이 같고, 이벤트 정의가 한 곳에만 산다.

스키마는 contracts/가 정본이다.

설계 전제

  • server가 유일한 public edge다. 그래서 ai는 인증도 CORS도 구현하지 않는다. ai를 외부에 노출하는 순간 이 전제가 깨지고, ai에 인증 계층을 먼저 만들어야 한다.
  • 브로커를 도입하지 않는다. 비동기는 DB row와 HTTP callback으로 충분하다. Kafka·SQS는 병목이 실측될 때 꺼낸다.
  • DB를 둘로 가른다. 파생 데이터가 원본과 같은 database에 있으면 "지워도 되는 것"을 구분할 수 없다. cross-database 쿼리는 금지다.

미확인

무엇지금 아는 것
server → ai 구간의 인증계약이 미결로 등재했다. 네트워크로 막을지 토큰을 붙일지 정하지 않았다
운영 배포 형상어디에 어떻게 띄울지 아직 아무것도 없다
분석 완료를 web이 아는 경로설계 스펙은 STOMP push를 적었다. 구현이 그렇게 될지는 모른다