본문으로 건너뛰기

애플리케이션 아키텍처 (AA)

갱신: 2026-08-17

HeyMoa는 웹, 업무 서버, AI 서비스가 각자 다른 책임을 맡는다. 경계를 판단하는 기준은 배포 위치가 아니라 데이터와 업무 규칙의 소유권이다. 프로세스 사이의 실제 통신은 시스템 아키텍처, AWS 배치는 클라우드 아키텍처에서 다룬다.

전체 구성​

heymoa-web에서 시작한 요청은 기능에 따라 업무 서버의 모듈로 들어간다. 채팅과 회의 분석만 heymoa-ai로 이어지며, AI가 업무 맥락을 읽을 때는 agent-context를 통해 서버의 권한 검사를 거친다. 두 PostgreSQL database는 같은 종류의 저장소지만 소유자가 다르다. heymoa는 업무 서버가, heymoa_ai는 AI 서비스가 쓴다.

서버가 관리하는 PostgreSQL·Redis·S3·NEO와 AI가 소유하는 heymoa_ai는 데이터 소유권에 따라 경계를 나눴다. Redis는 연결 중 필요한 cache, S3는 오디오 object storage, NEO는 검색용 파생 색인이라 영속성과 용도는 서로 다르지만 모두 서버 모듈이 상태를 관리한다.

SQS는 데이터를 보관하는 저장소가 아니라 애플리케이션 사이에서 실행 책임을 넘기는 비동기 경계다. 그래서 데이터 영역에서 분리했다. analysis가 회의 분석 작업을 발행하면 Meeting analysis가 소비하며, 이 전달 덕분에 오래 걸리거나 실패율이 다른 AI 작업이 서버 요청 처리와 분리된다.

외부 제공자는 역할에 따라 인증·메시징, 음성 처리, AI model·도구, 관측으로 나눠 실제 소비자 가까이에 놓았다. OpenAI는 Agent와 회의 분석이, Soniox는 transcription이, pyannote는 analysis가 사용한다. Linear와 GitHub는 서버가 연결 정보를 관리하고 AI가 승인된 작업을 실행하므로 양쪽 연결을 모두 표시했다. 관측은 모든 모듈에서 반복되는 횡단 책임이므로 모듈마다 선을 긋지 않는다. Server telemetry와 AI telemetry가 각 애플리케이션의 신호 수집 책임을 대표해 Grafana Cloud와 Langfuse로 보낸다.

세 애플리케이션의 책임​

전체 구성 그림에서 heymoa-web 을 누르면 세 애플리케이션이 주고받는 것만 남는다.

heymoa-web은 화면과 브라우저 상호작용을 맡는다. 업무 규칙과 권한 판단은 heymoa-server에 있다. heymoa-ai는 Agent 실행과 회의 분석을 맡지만 업무 데이터를 따로 복제하지 않고 필요한 맥락을 서버에서 읽는다.

브라우저가 AI 서비스를 직접 호출하는 경로는 없다. 채팅 요청과 분석 요청은 서버가 접수하며, AI가 업무 맥락이나 권한을 확인할 때도 서버의 내부 API를 사용한다. 이 규칙 덕분에 인증과 업무 데이터의 소유권이 AI 서비스로 새지 않는다.

회의가 끝난 뒤 오래 걸리는 작업은 SQS로 요청 처리와 분리한다. 같은 서버 프로세스 안에서 끝나는 작업은 별도 큐를 만들지 않고 데이터베이스의 상태로 관리한다.

업무 서버의 모듈 경계​

전체 구성 그림의 heymoa-server 칸에 모듈 아홉 개가 그대로 들어 있다. 모듈 하나를 누르면 그 모듈이 닿는 저장소와 외부만 남는다.

모듈맡은 일실행 위치
auth, user로그인, 세션, 계정api
workspace, project조직, 멤버, 초대, 프로젝트api
note회의록, 참가자, 회의 상태api
transcription전사 세션, 세그먼트, 오디오 중계realtime
analysis회의 종료 뒤 작업, 화자 결과와 매핑api
agentchat채팅, 메시지, 도구 승인api, realtime
agentcontextAI에 회의 맥락 제공api
integration, notification외부 도구 연결, 알림api
common예외 처리, 보안 설정, 요청 기록공통

agentcontext는 사용자 화면을 위한 API가 아니다. AI가 서버 소유 데이터를 읽을 때만 사용한다. agentchat은 요청을 받는 API와 응답을 중계하는 realtime에 걸쳐 있으므로 한 모듈이 두 실행 단위를 사용한다. analysis는 비동기 작업을 발행하고 외부 처리 결과를 다시 받아 회의 상태를 이어 간다.

대부분의 모듈은 presentation, application, domain, infra로 나뉜다. 상태를 소유하지 않는 agentcontext에는 domain이 없고, 여러 모듈이 함께 쓰는 기술 설정을 모은 common에는 application이 없다. 모든 모듈을 같은 네 층으로 맞추지 않은 이유다.

오디오 조립 함수는 Spring 모듈에 포함되지 않는다. S3의 오디오 조각을 순서대로 이어 붙이고 완료 메시지를 보내는 독립 실행 단위다.

AI 서비스의 내부 책임​

전체 구성 그림의 heymoa-ai 칸을 보면 된다. Agent runtime·Meeting analysis·Tool execution 은 LangGraph workflows 안에 있다.

heymoa-ai는 채팅, 직접 들어온 분석 요청, 큐에서 받은 분석 요청을 처리한다. 채팅 상태와 분석 결과, 임베딩은 AI 서비스가 소유한 heymoa_ai 데이터베이스에 저장한다. 회의록과 사용자 권한 같은 업무 데이터는 heymoa 데이터베이스에 남는다.

현재 코드에서 확인한 외부 연동은 OpenAI, Linear, GitHub다. Redis, S3, SES는 AI 서비스가 직접 사용하지 않는다. Linear와 GitHub의 쓰기 작업은 사용자가 승인한 뒤 실행한다. Agent 내부 상태와 승인 재개 과정은 HeyMoa AI Agent에 코드 기준으로 정리했다.

데이터 소유권과 의존 방향​

전체 구성 그림에서 저장소(PostgreSQL · heymoa, PostgreSQL · heymoa_ai)를 누르면 누가 그 저장소를 만지는지 바로 보인다.

PostgreSQL 인스턴스는 하나지만 heymoa와 heymoa_ai는 소유자가 다르다. 서버는 heymoa만 직접 쓰고 AI는 heymoa_ai만 직접 쓴다. 두 데이터베이스를 한 쿼리에서 조인하지 않는다. 한쪽에 필요한 정보가 다른 쪽에 있다면 소유 애플리케이션의 API를 호출한다.

데이터소유자
전사 세션과 세그먼트transcription
회의 상태note
화자 결과와 전사 매핑analysis
오디오 조립 작업 상태analysis
분석 결과, 임베딩, 채팅 checkpointheymoa-ai
그 밖의 업무 데이터heymoa-server

조립 함수는 데이터베이스를 읽지 않는다. API가 작업에 필요한 오브젝트 키를 메시지에 담아 보내고, 함수는 합본 키와 길이를 돌려준다.