docs: update ROADMAP to reflect P0/P1 completion and services/ package structure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sal
2026-06-01 17:46:53 +09:00
parent 79f2abe7cf
commit 511c87b290
+22 -17
View File
@@ -4,16 +4,16 @@
| 항목 | 현재 상태 | 심각도 | | 항목 | 현재 상태 | 심각도 |
|------|---------|--------| |------|---------|--------|
| 아키텍처 모듈화 | UI·비즈니스 로직 혼재 (2파일) | 🔴 높음 | | 아키텍처 모듈화 | ~~2파일 혼재~~ → config / api_client / services/ / container / app 5모듈 분리 | ✅ 완료 |
| Windows 호환성 | ~~TTS `say` 명령어 — macOS 전용~~ → 크로스플랫폼 구현 완료 | ✅ 완료 | | Windows 호환성 | ~~TTS `say` 명령어 — macOS 전용~~ → 크로스플랫폼 구현 완료 | ✅ 완료 |
| Gradio Chatbot 타입 | ~~`type="messages"` 누락~~ → Gradio 6.x 기본 포맷 사용 | ✅ 완료 | | Gradio Chatbot 타입 | ~~`type="messages"` 누락~~ → Gradio 6.x 기본 포맷 사용 | ✅ 완료 |
| JSON yield 타입 불일치 | ~~`JSONDecodeError` 시 타입 혼용~~`str()` 변환 적용 | ✅ 완료 | | JSON yield 타입 불일치 | ~~`JSONDecodeError` 시 타입 혼용~~`str()` 변환 적용 | ✅ 완료 |
| run_id 인덱싱 버그 | ~~`history` / `run_ids` 동기화 취약~~ → 방어 로직 추가 | ✅ 완료 | | run_id 인덱싱 버그 | ~~`history` / `run_ids` 동기화 취약~~ → 방어 로직 추가 | ✅ 완료 |
| RAG 출처 표시 | ~~thinking 박스에 혼재~~ → 답변 하단 `📄 출처` 전용 박스로 분리 | ✅ 완료 | | RAG 출처 표시 | ~~thinking 박스에 혼재~~ → 답변 하단 `📄 출처` 전용 박스로 분리 | ✅ 완료 |
| async/sync 혼용 | 동기 콜백에서 `asyncio.run()` 사용 (5곳) | 🟡 중간 | | async/sync 혼용 | ~~`asyncio.run()` 5곳~~ → 모든 콜백 async 전환 완료 | ✅ 완료 |
| 코드 중복 | `asyncio.run()` 패턴 5회 반복 | 🟡 중간 | | 코드 중복 | ~~`asyncio.run()` 5회 반복~~ → container 위임으로 제거 | ✅ 완료 |
| 결합도 | `api_client` 직접 임포트·전역 상태 | 🔴 높음 | | 결합도 | ~~`api_client` 직접 임포트~~ → DI container + Protocol 추상화 | ✅ 완료 |
| 테스트 가능성 | ~20% (모킹 가능) | 🔴 낮음 | | 테스트 가능성 | Protocol 도입으로 모킹 가능 — 테스트 미작성 | 🟡 중간 |
| 로깅 | `print()` 만 사용 | 🟢 낮음 | | 로깅 | `print()` 만 사용 | 🟢 낮음 |
--- ---
@@ -43,8 +43,8 @@
└──────────────┬───────────────────────────┘ └──────────────┬───────────────────────────┘
│ 생성 │ 생성
┌──────────────▼───────────────────────────┐ ┌──────────────▼───────────────────────────┐
│ services.py │ services/
ChatService / DocumentService / TTSService chat.py / document.py / tts.py
└──────────────┬───────────────────────────┘ └──────────────┬───────────────────────────┘
│ 사용 │ 사용
┌──────────────▼───────────────────────────┐ ┌──────────────▼───────────────────────────┐
@@ -194,13 +194,14 @@ class HTTPAPIClient:
# 기존 함수들을 메서드로 이전 # 기존 함수들을 메서드로 이전
``` ```
### 3. 서비스 레이어 분리 → `services.py` 신규 생성 ### 3. 서비스 레이어 분리 → `services/` 패키지 신규 생성
``` ```
services.py services/
├── ChatService(api_client)chat, reset, save_feedback ├── __init__.py ChatService, DocumentService, TTSService 재익스포트
├── DocumentService(api_client) — ingest, list_documents, delete_document ├── chat.py — ChatService: chat, reset, save_feedback
── TTSService() — tts_speak (플랫폼 분기) ── document.py — DocumentService: ingest, list_documents, delete_document
└── tts.py — TTSService: speak (플랫폼 분기)
``` ```
### 4. 수동 DI 컨테이너 → `container.py` 신규 생성 ### 4. 수동 DI 컨테이너 → `container.py` 신규 생성
@@ -259,10 +260,14 @@ class Container:
``` ```
youlbot-webui/ youlbot-webui/
├── app.py # Gradio UI 전용 — 콜백만 존재, 비즈니스 로직 없음 ├── app.py # Gradio UI 전용 — 콜백만 존재, 비즈니스 로직 없음
├── container.py # 수동 DI 컨테이너 (신규) ├── container.py # 수동 DI 컨테이너
├── services.py # ChatService, DocumentService, TTSService (신규) ├── services/
├── api_client.py # APIClientProtocol + HTTPAPIClient (리팩터링) │ ├── __init__.py # 재익스포트
├── config.py # AppConfig, APIConfig dataclass (신규) ├── chat.py # ChatService
│ ├── document.py # DocumentService
│ └── tts.py # TTSService
├── api_client.py # APIClientProtocol + HTTPAPIClient
├── config.py # AppConfig, APIConfig dataclass
├── tests/ ├── tests/
│ ├── test_chat_service.py │ ├── test_chat_service.py
│ └── test_document_service.py │ └── test_document_service.py
@@ -287,7 +292,7 @@ youlbot-webui/
### P1 ### P1
- [x] `config.py` 작성 (APIConfig, AppConfig) - [x] `config.py` 작성 (APIConfig, AppConfig)
- [x] `api_client.py` — `APIClientProtocol` + `HTTPAPIClient` 분리 - [x] `api_client.py` — `APIClientProtocol` + `HTTPAPIClient` 분리
- [x] `services.py` 작성 (ChatService, DocumentService, TTSService) - [x] `services/` 패키지 작성 (chat.py, document.py, tts.py + __init__.py 재익스포트)
- [x] `container.py` 작성 (lazy singleton 프로퍼티) - [x] `container.py` 작성 (lazy singleton 프로퍼티)
- [x] `app.py` — 모든 콜백 async 전환 및 container 사용 (`asyncio.run()` 완전 제거) - [x] `app.py` — 모든 콜백 async 전환 및 container 사용 (`asyncio.run()` 완전 제거)