# HMM AI 업무 에이전트 유지보수성 모듈화 설계서 (#701)

## 프로젝트 개요

`poc4_active_source_20260714`는 레거시 스냅샷 경로이며, 정식 서비스명은 HMM AI 업무 에이전트다. HMM MCP를 통해 HR 데이터, 표준 용어, 규정 문서를 조회하고 대화 이력과 보안 관리 화면을 제공한다.

## 목표

기능을 바꾸지 않고 대형 화면 파일의 책임을 분리한다. 설정 해석과 MCP Streamable HTTP 통신은 Streamlit 화면 코드에서 제거해 독립적으로 검증할 수 있게 한다.

## 현재 문제

- `apps/poc4/mcp_discovery_ui.py`가 화면, 설정, 인증, SQLite 대화 이력, MCP JSON-RPC, Agent 실행을 함께 관리한다.
- MCP 설정과 인증 토큰 규칙을 수정할 때 화면 코드까지 함께 읽어야 한다.
- MCP 프로토콜 처리의 단위 검증 지점이 없다.

## 모듈 경계

| 모듈 | 책임 | Streamlit 의존 |
| --- | --- | --- |
| `src/poc4/runtime_config.py` | `.env`, MCP 서버 JSON, VPD preset 로드와 검증 | 없음 |
| `src/poc4/mcp_client.py` | endpoint 검증, JSON-RPC, 세션 fallback, tool discovery/call | 없음 |
| `src/poc4/chat_store.py` | SQLite 대화 이력 CRUD | 없음 |
| `apps/poc4/mcp_discovery_ui.py` | 사용자 입력, 상태, 화면 렌더링, 업무 Agent orchestration | 있음 |

### 재사용 UI Shell과 제품 프로필

공통 화면 shell은 `src/agent_console/`에서 제공하고, 특정 고객·PoC의 표현은
`config/app_profile.json`에 둔다. 다른 프로젝트는 앱 코드를 복사·수정하지 않고 profile JSON을
교체할 수 있다. 실제 배포에서는 `AGENT_CONSOLE_NAME`, `AGENT_CONSOLE_HEADER_DESCRIPTION`,
`AGENT_CONSOLE_PRIMARY_COLOR` 등 `AGENT_CONSOLE_*` 환경변수가 JSON 기본값보다 우선한다.
따라서 고객별 제품명·설명·색상은 같은 컨테이너 이미지와 코드로 운영할 수 있다.

| 구분 | 공통화 대상 | 제품별 설정 |
| --- | --- | --- |
| 화면 shell | light theme, sidebar, 입력/버튼, 로그인/헤더 renderer | 제품명, 문구, 아이콘, 색상 |
| 데모 질문 | JSON loader와 중복·형식 검증 | `config/hmm_demo_scenarios.json`의 질문 목록 |
| MCP 연결 | JSON registry와 server token env 참조 | endpoint, allowlist, token env 이름 |

`poc4` 접두어가 있는 app path, session key, DB 파일명은 배포 호환성을 위한 레거시 경계다.
새 코드에는 서비스/모듈 이름으로 사용하지 않으며, 별도 migration 작업에서만 제거한다.

## 추적 및 현행화 규칙

이 설계서는 HMM AI 업무 에이전트의 UI shell·제품 profile·데모 시나리오 구조에 대한 기준 문서다.

1. 구조나 JSON schema를 변경하면 이 문서의 모듈 경계와 호환성 원칙을 먼저 갱신한다.
2. 변경은 Redmine 이슈에 설계·검증 결과와 Git commit SHA를 함께 기록한다.
3. Git commit message에는 Redmine 번호를 `refs #<번호>:` 형식으로 포함한다.
4. 환경별 값과 비밀값은 profile JSON에 넣지 않고 `.env` 또는 secret store에만 둔다.
5. UI CSS는 `src/agent_console/presentation.py` 한 곳에서 관리한다. 제품별 색상과 문구는 Python/CSS를 수정하지 않고 `app_profile.json`으로 조정한다.

도메인 로직의 공개 오류는 `PublicMcpError`로 통일한다. UI는 이 오류를 사람이 이해할 수 있는 메시지로 표시하되 토큰과 HTTP 원문을 출력하지 않는다.

## 호환성 원칙

1. 기존 환경변수, JSON 키, SQLite 테이블과 세션 키를 유지한다.
2. HMM MCP의 서버 전용 `HMM_MCP_BEARER_TOKEN` 규칙을 유지한다.
3. HTTP 400이 발생하는 MCP에 대해 기존 initialize/session fallback을 유지한다.
4. 외부 호출은 read-only tool만 사용하며 UI의 요청·응답 형식을 변경하지 않는다.

## 검증 기준

- `py_compile` 및 모듈 import가 성공한다.
- 설정 JSON을 읽어 HMM MCP 한 개와 allowlist 세 개가 확인된다.
- HTTP mocking으로 일반 JSON-RPC와 session fallback을 검증한다.
- 운영 서버에서 `tools/list`로 HMM MCP 세 도구가 발견되고 Streamlit health/UI가 정상 응답한다.

## 단계

1. 설정·MCP transport·대화 저장소를 순수 Python 모듈로 추출한다.
2. 화면 파일은 새 공개 API만 사용하도록 교체한다.
3. 단위 검증과 운영 smoke test 후 Git/Gitea에 반영한다.
