Update architecture principles and plans

This commit is contained in:
Claude-51124 2026-01-04 14:28:10 +09:00
parent b167aae81c
commit 46229bf87a
25 changed files with 449 additions and 556 deletions

View File

@ -365,14 +365,7 @@ utils
- **실제 테스트 필수**: 코드 수정 후 추측하지 말고 실제로 테스트 (curl, Slack 직접 사용, DB 조회)
- **Git 커밋 확인**: 각 프로젝트 폴더에서 개별 확인 (루트에서 확인 금지)
## 19. 스케줄러 모듈 import 오류 체크 원칙
- **문법 오류로 인한 조용한 실패**: 스케줄러 시작 시 모듈 import 과정에서 문법 오류가 있으면 작업이 등록되지 않음
- **try-except 블록 구조 확인**: `try` 없이 `except`/`finally`만 있으면 문법 오류 발생
- **로그 확인 필수**: 스케줄러 시작 로그에서 "Failed to register job" 에러 확인 (`docker logs [컨테이너] | grep -i "failed to register"`)
- **교훈**: 문법 오류로 인해 스케줄러 작업이 조용히 실패할 수 있음. 모듈 import 단계에서 오류 발생 시 전체 작업이 실행되지 않음
## 20. 모범 사례 참고
## 19. 모범 사례 참고
본 문서는 FastAPI 커뮤니티의 다음 모범 사례를 반영하였습니다:

View File

@ -45,16 +45,23 @@
**파일명**: `yymmdd_주제.md`
**용도**: 미래 계획, 아이디어만 (아직 구현 안 됨)
**규칙**:
- **구현 완료 시 `journey/plans/archive/`로 이동** (필수)
- **모든 구현 완료 섹션은 즉시 삭제** - "→ 상세: troubleshooting/yymmdd_*.md" 링크로만 대체
**규칙** (⚠️ **핵심 원칙 - 절대 위반 금지**):
- **구현 완료 시 `journey/plans/archive/`로 이동** (필수) - `plans/`에는 미구현 계획만 남김
- **모든 구현 완료 섹션은 즉시 삭제** - "→ 상세: troubleshooting/yymmdd_*.md" 링크로만 대체 (상세 완료 사항 나열 금지)
- **명확한 행동강령만 기록** - 불확실한 표현("예상", "가능", "고려", "검토", "추후", "나중", "필요시", "선택", "옵션", "또는", "아마", "것 같", "추정") 금지
- **여지가 있는 내용은 아이디어 폴더로 이동** - 불확실한 아이디어는 `journey/ideas/`에 기록
- **아키텍처/Phase/필요작업만** - 장황한 구현 코드 예시 최소화
- **Phase별 분리 가능**: 복잡한 계획은 Phase 1/2/3으로 분리 가능
- 크기 제한 및 초과 시 처리: 섹션 4 참조
**구분**:
- `plans/`: 미구현 계획만 (will do)
- `plans/archive/`: 구현 완료된 계획 (참고용 보관)
**부분 완료 문서 처리** (⚠️ **핵심 원칙**):
- **부분 완료 문서는 `plans/`에 유지** - 전체 완료 시에만 archive로 이동
- **완료된 섹션은 삭제하고 troubleshooting 링크로만 대체** - "→ 상세: troubleshooting/yymmdd_*.md" 형식 (상세 완료 사항 나열 금지)
- **미구현 항목만 "남은 작업" 섹션에 남기기** - 아키텍처/Phase/필요작업만 기록
**구분** (⚠️ **명확히 구분 필수**):
- `plans/`: 미구현 계획만 (will do) - 부분 완료 포함, **구현 완료 섹션 절대 금지**
- `plans/archive/`: 전체 구현 완료된 계획 (참고용 보관)
- `troubleshooting/`: 구현 완료 + 문제 해결 (did + learned)
### 인덱스 README.md

View File

@ -211,14 +211,6 @@ The answer is:
- 감정 기반 동적 프롬프트 조합 시 퓨샷 예시 활용
- 사용자별 개인화 프롬프트 오버라이드 시 컨텍스트 구조화
## 11. LLM 생성 콘텐츠 이모지 제거 원칙
- **이모지 사용 금지**: LLM이 생성하는 모든 콘텐츠(일기, 응답, 요약 등)에서 이모지 사용 금지
- **이중 방어 전략**: 프롬프트에 명시 + 후처리 함수로 제거 (프롬프트만으로는 LLM이 이모지를 사용할 수 있음)
- **후처리 함수 필수**: LLM 생성 결과에 이모지 제거 함수 적용 (`_remove_emojis` 등)
- **이모지 패턴**: `\U0001F300-\U0001F9FF`, `\U00002600-\U000027BF` 등 주요 이모지 범위 포함
- **검증 방법**: 생성된 콘텐츠에서 이모지 패턴 정규식으로 확인
---
## 참고 자료

View File

@ -1,35 +0,0 @@
# 미해결 항목 매트릭스 (중요도 × 구현 난이도)
## 🔴 Quick Wins (높은 중요도 + 쉬운 구현) → 즉시 실행
(현재 없음)
## 🟠 Major Projects (높은 중요도 + 어려운 구현) → 계획 수립 후 진행
1. **하드코딩 URL 제거** - 15개+ 서비스 광범위 미해결, 특히 rb8001의 auth-server URL (3-4주) [→250915](../troubleshooting/250915_hardcoded_url_removal.md)
2. **Gateway 스케일링** - 재시도/백오프 미구현 (Rate limiting 완료, `/healthz` 제공) (1주) [→250811](../troubleshooting/250811_happybell80_Gateway필드변환문제.md) [→250915_rate](../troubleshooting/250915_rate_limiting_미구현.md)
3. **RAG 파이프라인 웹검색 통합** - 아이디어 단계, 미구현 (3주) [→250909](../ideas/250909_RAG_file_processing_architecture.md)
4. **rb8001 리팩토링** - 계획 단계, 미구현 (3주) [→250914](../ideas/250914_rb8001_리팩토링_계획.md)
5. **네이버웍스 캘린더 연동** - 가이드만 존재, 미구현 (2주) [→250917](../troubleshooting/250917_네이버웍스_캘린더_API_연동_가이드.md)
6. **Slack 캔버스 통합** - 아이디어 단계, 미구현 (2주) [→250916](../ideas/250916_슬랙_캔버스_API_활용_방안.md)
7. **news 엔드포인트 리팩토링** - DB 영속화 완료(250920), 서비스 레이어 리팩토링 미완 (1주) [→250920_db](../troubleshooting/250920_news_db_persistence_implementation.md)
## 🟡 Fill-ins (낮은 중요도 + 쉬운 구현) → 시간 날 때
1. **scheduled_tasks 테이블** - 미구현 (스키마만 존재) (3시간) [→250827](../troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md)
2. **캘린더 API** - /api/calendar 미구현 (4시간) [→250830](../troubleshooting/250830_skill_level_system_restructure.md)
3. **문서 API** - /api/docs 미구현 (4시간) [→250830](../troubleshooting/250830_skill_level_system_restructure.md)
4. **불용 환경변수 정리** - 전역 감사 미완 (2시간)
5. **임베딩 서비스 오류 처리** - 폴백(더미 벡터)만 구현, 재시도 미구현 (3시간)
## ⚪ Consider Later (낮은 중요도 + 어려운 구현) → 재검토 필요
1. **실시간 동기화** - WebSocket/폴링 미구현 (영향도 재평가 필요) (2주) [→250827](../troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md)
2. **PKCE 적용** - OAuth 보안 강화 미구현 (1주) [→380](../300_architecture/380_authentication_system.md)
4. **DB 스키마 통일** - company→workspaces 미구현 (2주) [→250831](250831_todo_and_tech_debt.md)
5. **스킬 라우팅 고도화** - Decision Engine 미구현 (3주) [→250811](../ideas/250811_claude_rb10408_vs_rb10508_비교분석.md)
6. **IntentAnalyzer 활성화** - 현재 미사용, LLM 기반 의도분석기 미연동 (1주) [→250914](../troubleshooting/250914_happybell80_IntentAnalyzer_미사용_문제.md)
7. **전역 ENV 감사** - 레포 전반 미사용/중복 ENV 정리 미구현 (2주)
8. **Slack Canvas 고급 시나리오** - DM/MPDM 공유 제약 대응 미구현 (2주) [→250916](../ideas/250916_슬랙_캔버스_API_활용_방안.md)
---
*평가 기준: 중요도(시스템 안정성/사용자 영향), 난이도(구현 시간/복잡도)*
---
*최종 업데이트: 2025-10-10*

View File

@ -1,69 +0,0 @@
# 서비스 재구조화 계획
**날짜**: 2025-08-07
**상태**: 계획 단계
---
## 현재 문제
1. frontend-customer와 로빙 직접 연결 부재
2. 인증 흐름 불완전 (OAuth → frontend 토큰 전달 없음)
3. DB 분산 (PostgreSQL, ChromaDB, SQLite) - user_id 동기화 문제
4. 서비스 역할 혼재 (frontend-base가 admin UI + 백엔드)
---
## 제안 구조
### robeing-gateway (51123:8100)
**역할**:
- API 게이트웨이 (사용자 → 로빙 라우팅)
- JWT 인증 체크
- 사용자-로빙 매핑 (메모리 캐시)
### robeing-control (51123:9023)
**역할**:
- 시스템 모니터링 통합
- Admin 대시보드 UI
- 51123/51124 서버 상태 조회
### robeing-monitor (51124:9024)
**역할**:
- 로빙 컨테이너 health 체크
- Stats 수집 (메모리, CPU, 응답 시간)
- 로그 수집
---
## 구현 Phase
### Phase 1: robeing-gateway 분리 (미착수)
- frontend-base에서 라우팅 로직 분리
- JWT 인증 미들웨어
- 사용자-로빙 매핑 테이블/캐시
### Phase 2: robeing-control 분리 (미착수)
- Admin UI 분리
- 모니터링 통합 대시보드
- 51123 서버 프로세스 직접 체크
### Phase 3: robeing-monitor 구현 (미착수)
- 51124 서버에 배포
- Docker stats API
- Health check 엔드포인트
---
## 기대 효과
- 관심사 분리 (라우팅 vs 모니터링)
- 확장성 향상 (로빙 추가 시 gateway만 수정)
- 장애 격리 (모니터링 장애가 라우팅에 영향 X)
---
## 참고
- `troubleshooting/250827_frontend_backend_preferences_API_연동_완료.md`
- `311_FastAPI_구조_원칙.md`

View File

@ -1,86 +0,0 @@
# UUID 통합 시스템 구현 로드맵
**날짜**: 2025-08-31
**목표**: 모든 서비스에서 UUID를 Primary Key로 사용
---
## 현재 문제
- rb8001: UUID 매핑 제공하나 내부 혼용
- skill-email: slack_id 직접 사용 (UUID 미지원)
- Gateway: JWT에서 UUID 추출
- ChromaDB: 일관성 없는 collection 명명
**영향**: 서비스 간 통신 오류, 데이터 불일치
---
## Phase 1: DB 스키마 통일 (미착수)
### 필요 작업
**1. 외래 키 제약 추가**
```sql
ALTER TABLE gmail_token ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES user(id);
ALTER TABLE workspace_member ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES user(id);
```
**2. 인덱스 생성**
```sql
CREATE INDEX idx_conversation_log_user_id ON conversation_log(user_id);
CREATE INDEX idx_gmail_token_user_id ON gmail_token(user_id);
```
**3. 데이터 검증**
- orphaned UUID 확인
- NULL UUID 처리
---
## Phase 2: 서비스 수정 (미착수)
### skill-email
- 파일: `services/db_credentials_provider.py`
- 변경: slack_id → user_id (UUID)
### rb8001
- 파일: `app/skills/email_skill.py`
- 변경: UUID 우선 사용
### ChromaDB
- Collection 명명: `{service}_{uuid}` 통일
- 예: `rb8001_53529291-5050-4daa-89fb-008b546feb63`
---
## Phase 3: Gateway 통합 (미착수)
### JWT 표준화
```python
{
"sub": "uuid", # user.id
"username": "happybell80",
"email": "user@example.com"
}
```
### 헤더 표준화
- `X-User-Id`: UUID (모든 내부 API)
- Slack ID는 oauth_providers JSONB에만 저장
---
## 검증
**테스트 시나리오**:
1. Gmail 재인증 → JWT 발급 → UUID 확인
2. skill-email 호출 → UUID로 토큰 조회
3. ChromaDB 저장 → collection 명명 확인
---
## 참고
- `troubleshooting/250911_PostgreSQL_테이블명_단수형_통일.md`
- `troubleshooting/250924_UUID_체계_전환_및_대화저장_오류.md`

View File

@ -1,59 +0,0 @@
# Workspace 테이블 통합 계획
**날짜**: 2025-08-31
**목표**: company + workspaces → workspaces로 통합
---
## 현재 문제
### 중복 데이터
- Company-X가 양쪽 테이블에 존재
- 컬럼명 불일치 (`container_port` vs `robeing_port`)
- FK 관계 불일치 (slack_workspaces → company, workspace_member → workspaces)
### 코드 오류
- `workspace.workspace` (잘못된 참조)
- `workspace.robeing_port` (컬럼명 불일치)
---
## 마이그레이션 계획
### Phase 1: DB 백업
```bash
sudo -u postgres pg_dump -t company -t workspaces main_db > /backup/workspace.sql
```
### Phase 2: 데이터 통합
```sql
-- 1. company → workspaces 이동
INSERT INTO workspaces (id, name, subdomain, robeing_port)
SELECT id, name, subdomain, container_port FROM company;
-- 2. slack_workspaces FK 수정
ALTER TABLE slack_workspace
ADD COLUMN workspace_id UUID,
DROP COLUMN company_id;
-- 3. company 테이블 삭제
DROP TABLE company CASCADE;
```
### Phase 3: 코드 수정
- `auth-server/app/models/workspace.py`: company_id → workspace_id
- `auth-server/app/api/slack_router.py`: workspace.workspace 제거
---
## 검증
1. 모든 workspace 조회 성공
2. slack_workspaces FK 정상
3. 기존 기능 정상 작동
---
## 참고
- `troubleshooting/250911_PostgreSQL_테이블명_단수형_통일.md`

View File

@ -20,15 +20,13 @@ skill-publish (8511)
---
## 2. 구현 상태
## 2. 구현 완료
### ✅ 완료
- skill-news: 포트 8505 운영 중
- skill-publish: 포트 8511 구현 완료
→ 상세: `troubleshooting/250906_skill_publish_implementation.md`
**상세**: `troubleshooting/250906_skill_publish_implementation.md`
---
### ⏳ 미구현
## 3. 남은 작업
**Phase 3: skill-news 스크래핑/요약 기능 강화**
- 현재: 제목/URL만 제공
@ -41,7 +39,7 @@ skill-publish (8511)
---
## 3. 필수 변수 (Squarespace 게시용)
## 4. 필수 변수 (Squarespace 게시용)
```json
{
@ -59,7 +57,7 @@ skill-publish (8511)
---
## 4. 참고
## 5. 참고
- `troubleshooting/250906_skill_publish_implementation.md`
- `troubleshooting/250908_skill_news_companyx_data_integration.md`

View File

@ -24,24 +24,15 @@ APScheduler → skill-news:8505 → rb8001 → Slack 채널
---
## 2. 구현 상태
## 2. 구현 완료
### ✅ 완료
- skill-news 운영 중 (포트 8505)
- skill-publish 구현 완료 (포트 8511)
- APScheduler 평일 10:00 자동 실행
- Slack Block Kit 버튼 전송
**상세**: `troubleshooting/250907_company_x_news_zero_articles.md` 외 다수
### ⏳ 미구현
- **PostgreSQL rb_news 테이블**: 현재 JSON 파일 기반
- **실시간 게시 상태 추적**: skill-publish API 확장 필요
- **게시 이력 조회**: 프론트엔드 UI 미구현
→ 상세: `troubleshooting/250907_company_x_news_zero_articles.md` 외 다수
---
## 3. 미구현 Phase 3: DB 영구 저장
## 3. 남은 작업
### Phase 3: DB 영구 저장
### 현재 제약
- JSON 파일 (`/app/data/news_state.json`) 사용

View File

@ -5,7 +5,13 @@
---
## Phase 1: Coldmail 온톨로지 (미착수)
## Phase 1: Coldmail 온톨로지 (✅ 완료)
→ 상세: `troubleshooting/251014_claude_coldmail_filter_tokenization_issue.md`
---
## Phase 2: Neo4j 기억 시스템 (⏳ 미착수)
### 개념 계층
```
@ -76,13 +82,11 @@ RETURN e.subject, e.sender, e.timestamp
## Phase 3: 감정-기억-윤리 삼각형 (미착수)
### 통합 설계
**파일**: `rb8001/app/services/memory/neo4j_client.py`
- 감정 분석 → 기억 검색 → 윤리 제약 → 응답 생성
- Neo4j에 감정 이력 저장
- 패턴 분석 (우울증 조기 감지)
**예상 기간**: 3-4개월
---
## 참고

View File

@ -18,43 +18,20 @@
---
## 개선 방향 (3단계 구조)
## 구현 완료 (3단계 구조)
**구현 완료**: `troubleshooting/251126_happybell80_rb8001_의도_3단계_아키텍처_도입_및_배포.md`
**완료일**: 2025-11-26
**커밋**: `a4738b9` (rb8001)
### 완료 사항
- ✅ 3단계 스키마 정의: `intent/schemas.py` (IntentCategory, IntentGoal, ActionPlan, SkillSequence)
- ✅ IntentAnalyzer 구현: LLM 기반 제로샷 의도 분석
- ✅ ActionPlanner 구현: IntentGoal → ActionPlan 변환
- ✅ SkillSelector 구현: ActionPlan → SkillSequence 변환
- ✅ DecisionEngine 통합: `_build_intent_pipeline()` 메서드 추가, execution_plan에 intent_pipeline 메타데이터 포함
- ✅ TDD 테스트: `tests/test_intent_3step_architecture.py` 통과
```
1. 의도 파악 → 추상적 목표 (일정 관리, 정보 검색 등)
2. 행동 계획 → 구체적 행동 (등록, 조회, 삭제 등)
3. 스킬 선택 → 적절한 도구 (calendar_skill 등)
```
→ 상세: `troubleshooting/251126_happybell80_rb8001_의도_3단계_아키텍처_도입_및_배포.md`
---
## 미구현: 하이브리드 시스템
## ⏳ 미구현: 하이브리드 시스템
### 제안 구조
```
사용자 메시지
1단계: 정규식 FastPath (명확한 패턴)
↓ 실패
2단계: 임베딩 후보 축소 (Top-3)
↓ 확신도 < 0.7
3단계: LLM 제로샷 분류
```
**구조**:
1. 정규식 FastPath (명확한 패턴) → conf ≥ 0.9 즉시 결정
2. 임베딩 후보 축소 (Top-3) → 확신도 < 0.7
3. LLM 제로샷 분류 → conf < 0.5 CLARIFY
### 필요 작업
**필요 작업**:
**1. SemanticIntentClassifier 구현**
- 파일: `app/services/brain/semantic_classifier.py`
@ -65,11 +42,6 @@
- Top-3 후보를 LLM에 전달
- 확신도 < 0.5 CLARIFY
**3. 성능 최적화**
- 정규식: 80% 케이스 (< 10ms)
- 임베딩: 15% 케이스 (< 200ms)
- LLM: 5% 케이스 (1-2s)
---
## 참고

View File

@ -5,62 +5,41 @@
---
## 개요
## 목표
**목표**: 룰 중심 의도 파악 → 의미 기반 + 불확실성 관리 + 지속 학습
**접근**: FastPath + 임베딩 Top-K + LLM 재분석 + Beta(α,β) 동적 임계치
**기대**:
- Unknown↓
- 잘못된 실행 <1%
- LLM 호출 ≤30%
- 지연 중앙값 <800ms
FastPath + 임베딩 Top-K + LLM 재분석 + Beta(α,β) 동적 임계치 하이브리드 시스템
---
## 아키텍처 (Phase 1)
## Phase 1: 하이브리드 파이프라인
### 1. FastPath
- 정규식 + Naive Bayes
- conf ≥ 0.9 즉시 결정
**파일**: `rb8001/app/services/brain/intent_graph.py` (신규)
- FastPath: 정규식 + Naive Bayes, conf ≥ 0.9 즉시 결정
- SemanticIntentClassifier: intent 설명/예시 벡터와 코사인 유사도, Top-K 후보 선택
- LLM 재분석: Top-K만 JSON 스키마로 결정, conf < τ는 clarify
### 2. 임베딩 후보 축소
- intent 설명/예시 벡터와 코사인 유사도
- Top-K + 마진 기반 신뢰도
**파일**: `rb8001/app/services/brain/semantic_classifier.py` (신규)
- intent_prototypes 테이블 활용
- 임베딩 유사도로 Top-3 후보 선택
### 3. LLM 재분석
- Top-K만 JSON 스키마로 결정
- conf < τ는 clarify
**파일**: `rb8001/app/services/llm/intent_parser.py` (신규)
- LLM JSON 파서
### 4. 캘리브레이션
- 유사도·마진 기반 conf → 온도/Isotonic 보정
## Phase 2: 베이지안 동적 학습
---
## 구현 파일 (스캐폴드)
- `rb8001/app/brain/intent_graph.py`: FastPath→Semantic→LLM 파이프
- `rb8001/app/brain/semantic_classifier.py`: 제로샷 후보 축소
- `rb8001/app/llm/intent_parser.py`: LLM JSON 파서
- `rb8001/app/brain/intent_registry.yaml`: intent 설명/슬롯
---
## 베이지안 동적 학습
### Beta(α,β) 추적
- 의도/경로별 성공률 추적
- 성공 α+=1, 실패 β+=1
**파일**: `rb8001/app/state/repositories/intent_decision_repository.py` (신규)
- `intent_decision_log` 테이블 생성
- 의도/경로별 성공률 추적 (Beta(α,β))
- Thompson Sampling으로 임계치 τ 동적 최적화
### 로그 스키마
**DB 스키마**:
```sql
CREATE TABLE intent_decision_log (
user_id UUID,
message TEXT,
candidates JSONB,
chosen TEXT,
path TEXT, -- fastpath/semantic/llm
path TEXT,
success BOOLEAN,
latency_ms INT,
timestamp TIMESTAMPTZ
@ -69,26 +48,6 @@ CREATE TABLE intent_decision_log (
---
## Chain-of-Thought (CoT) 적용
### 목적
- 복잡한 질문 정확도 향상
- 확신도 낮은 경우 단계별 추론
### 조건부 활성화
- conf < 0.7: CoT 사용
- conf ≥ 0.9: CoT 생략 (비용 절감)
- 컨텍스트 의존 질문: CoT 우선
---
## 배포 전략
- A/B → 밴딧: 10%→30%→50% 점진 롤아웃
- 지표: Unknown/Clarify/오실행/지연/비용 모니터링
---
## 참고
- `troubleshooting/251126_intent_3step_db_bayesian_integration.md`

View File

@ -19,67 +19,33 @@
3. **휴먼 인 더 루프 (HITL) 패턴**: 실행 일시 중지 후 인간 승인 API 제공
4. **그래프 기반 실행 모델 개선**: 결정론적/에이전트 컴포넌트 혼합 제어 강화
## 업그레이드 활용 방안
## Phase 1: 콜드메일 워크플로우 HITL 패턴 적용
### Phase 1: 콜드메일 워크플로우 개선
- **현재**: "이 기업을 분석해 드릴까요?" 버튼이 Slack 인터랙션으로 별도 처리 (워크플로우 외부)
- **개선**: `process_node`에서 HITL 패턴으로 일시 중지 → 사용자 승인 대기 → 재개
- **효과**: 워크플로우 내부에서 상태 관리, 중단/재개 자동화
**파일**: `rb8001/app/services/workflows/coldmail_workflow.py`
- `process_node`에서 HITL 패턴으로 일시 중지 → 사용자 승인 대기 → 재개
- "이 기업을 분석해 드릴까요?" 버튼을 워크플로우 내부에서 처리
### Phase 2: 프론트엔드 IR 평가 통합
- **현재**: 프론트엔드 요청은 REST API로 직접 처리 (`IRDeckAnalyzer().analyze()`)
- **개선**: 프론트엔드 요청도 LangGraph 워크플로우로 처리
- **효과**: IR Deck 평가(수 분 소요) 중단/재개 지원, 상태 관리 일원화
## Phase 2: 프론트엔드 IR 평가 워크플로우화
### Phase 3: 자동 상태 복구
- **현재**: 체크포인터 수동 설정 (`AsyncSqliteSaver.from_conn_string()`)
- **개선**: 1.0의 자동 상태 관리 활용
- **효과**: 서버 재시작 시 콜드메일 처리 중단 지점부터 자동 재개
**파일**: `rb8001/app/router/ir_deck.py`
- 프론트엔드 요청을 LangGraph 워크플로우로 처리
- 신규 워크플로우 생성 (HITL 없음)
- 공통 함수: `extract_ir_metrics()`, `evaluate_ir_deck()`, `save_evaluation()`
## 워크플로우 통합 설계
## Phase 3: 자동 상태 복구
### 설계 고려사항
**문제**: 콜드메일과 프론트엔드 IR Deck 분석이 서로 다른 진입점을 가짐
- 콜드메일: 스케줄러 → `coldmail_workflow.py`
- 프론트엔드: REST API → `ir_deck.py` (직접 `IRDeckAnalyzer().analyze()` 호출)
**고려한 방법**:
1. **라우터 노드 통합**: 단일 워크플로우에서 라우터 노드로 분기
2. **서브그래프 통합**: 공통 분석 부분을 서브그래프로 만들어 재사용
3. **별도 워크플로우 + 공통 함수**: 각각 독립 워크플로우, 공통 로직은 함수로 재사용
### 최종 결정
**2개 워크플로우 + 공통 함수 재사용** 방식 채택
| 방식 | 장점 | 단점 | 결정 |
|------|------|------|------|
| 라우터 통합 | 단일 워크플로우 관리 | 진입점이 달라 복잡도 증가 | ❌ |
| 서브그래프 | 공통 부분 재사용 | 여전히 2개 워크플로우 필요 | ⚠️ |
| 별도 워크플로우 | 단순, 유지보수 용이 | 공통 로직 중복 가능 | ✅ |
**구조**:
- **워크플로우 1**: 콜드메일 처리 (기존 + HITL 패턴)
- **워크플로우 2**: 프론트엔드 IR Deck 분석 (신규, HITL 없음)
- **공통 함수**: `extract_ir_metrics()`, `evaluate_ir_deck()`, `save_evaluation()`
**이유**: 진입점이 다르면 별도 워크플로우로 관리하는 것이 단순하고 유지보수에 유리함
## 마이그레이션 전략
1. **의존성 업데이트**: `requirements.txt`에서 `langgraph==0.6.10``langgraph>=1.0.0`
2. **API 변경 확인**: `StateGraph`, `AsyncSqliteSaver` API 변경사항 확인
3. **체크포인터 마이그레이션**: 기존 SQLite 체크포인트 데이터 호환성 확인
4. **단계적 적용**: 콜드메일 워크플로우부터 적용 후 프론트엔드 IR 평가 확장
**파일**: `rb8001/app/services/workflows/coldmail_workflow.py`
- LangGraph 1.0 자동 상태 관리 활용
- 체크포인터 수동 설정 제거
## 필요 작업
- [ ] LangGraph 1.0 공식 마이그레이션 가이드 확인
- [ ] `coldmail_workflow.py` API 호환성 테스트
- [ ] HITL 패턴 적용 설계 (콜드메일 "분석할까요?" 버튼)
- [ ] 프론트엔드 IR 평가 워크플로우화 설계
- [ ] 체크포인트 데이터 마이그레이션 스크립트 작성
1. `requirements.txt`: `langgraph==0.6.10``langgraph>=1.0.0`
2. `coldmail_workflow.py` API 호환성 테스트
3. HITL 패턴 적용 (콜드메일 "분석할까요?" 버튼)
4. 프론트엔드 IR 평가 워크플로우화
5. 체크포인트 데이터 마이그레이션 스크립트 작성
## 참고

View File

@ -6,22 +6,9 @@
---
## 현재 상태
### Frontend 문제점
- `app.js`: 1132줄 (여전히 1000줄 이상)
- 일기 모듈만 분리됨 (`modules/diary.js`)
- 시스템, 컨테이너, 사용자, 로빙 모듈 미분리
### Backend 문제점
- `admin_routes.py`: 96줄 (인증만 남음) ✅
- 시스템 모듈 분리 완료 ✅
---
## 남은 작업
### Frontend 모듈 분리 (미완료)
### Frontend 모듈 분리 (⏳ 미완료)
**목표 구조**:
```
@ -54,17 +41,7 @@ frontend/
## 구현 완료
**완료일**: 2025-12-25
**커밋**: `ac96e2a` (admin-dashboard)
**상세**: `troubleshooting/251225_admin_dashboard_code_refactoring.md`
### 완료 사항
- ✅ Backend 모듈 분리: `admin_routes.py``routers/system.py`, `services/system_service.py`
- ✅ 정적 파일 서빙: `routers/admin_static.py` 생성
- ✅ Frontend 모듈화: `modules/diary.js` 분리, `app.js` 1360줄 → 1132줄
- ✅ 로그인 오류 수정: `app.js:938` 문자열 결합 문법 오류 수정
- ✅ 경로 매칭 문제 해결: `/diary/list``/diaries`로 변경
- ✅ Gateway 프록시 호환성: 이중 경로 지원
→ 상세: `troubleshooting/251225_admin_dashboard_code_refactoring.md`
---

View File

@ -7,15 +7,9 @@
---
## 개선 목표
## 목표
현재 프롬프트가 코드에 하드코딩되어 있어 변경 시 배포가 필요하고, 사용자별 개인화가 어려움. DB화를 통해 동적 변경 및 개인화 구현.
## 기대 UX 개선
1. **개인화**: 사용자별 선호사항(톤, 길이, 스타일) 즉시 반영 ("짧게 대답해" → 다음 대화부터 적용)
2. **빠른 반응성**: 프롬프트 수정 시 배포 없이 즉시 적용, A/B 테스트 가능
3. **일관성 향상**: 버전 관리 및 롤백으로 품질 지속 개선
프롬프트 DB화를 통한 동적 변경 및 개인화 구현
## DB 스키마 설계
@ -35,7 +29,6 @@ CREATE TABLE prompt_templates (
);
```
**참고**: `content` 필드는 XML 구조화된 프롬프트를 저장하며, 변수 플레이스홀더는 텍스트 내 포함. 예: `{"template": "<role>로빙 AI 어시스턴트</role>\n<constraints>사용자 감정: {emotion_labels}</constraints>", "variables": ["emotion_labels"]}` 형식으로 저장 가능.
## 프롬프트 분류 기준
@ -50,91 +43,41 @@ CREATE TABLE prompt_templates (
- **Task**: 작업 타입별 (chat, extract, calendar_confirm 등)
### 3. 병합 로직
Global → Robeing → User 순서로 조회, 상위에서 정의되면 하위가 상속, 하위에서 오버라이드 시 상위 우선순위 적용.
- 각 레벨별 개별 쿼리 후 애플리케이션에서 병합 (복잡한 JOIN 대신)
- Global scope는 scope_id=NULL로 조회 (PostgreSQL NULL은 UNIQUE 제약에서 제외)
- Global → Robeing → User 순서로 조회
- 각 레벨별 개별 쿼리 후 애플리케이션에서 병합
- Global scope는 scope_id=NULL로 조회
## 관리 포인트 (10가지)
1. 시스템 프롬프트 (기본 정체성/규칙)
2. 작업 타입별 (chat, summarize, extract_actions, calendar_confirm)
3. 의도 분석 (IntentAnalyzer, IntentParserLLM)
4. 스킬별 (naverworks_briefing, dm_skill, startup_news)
5. IR Deck 분석
6. 일기 생성
7. 콜드메일 처리
8. 감정 기반 동적 프롬프트
9. 맥락 기반 (직전 대화, 메모리 검색)
10. 변수 치환 ({current_time}, {user_name}, {emotion_labels})
## 핵심 설계 원칙 (기존 문서 참고)
- **프롬프트 구조화**: XML 태그 사용 (`<role>`, `<constraints>`, `<task>`, `<context>`, `<output_format>` 등) - [[book/300_architecture/313_Gemini_프롬프트_설계_원칙]] 필수 준수
- **퓨샷 예시 활용**: 긍정적 패턴 예시 제공으로 모델 성능 향상
- **rule_type 분류**: never/always/prefer/avoid + 감정 가중치 ([[ideas/250828_dynamic_system_prompt_memory]])
- **계층 구조**: Base Layer(기본 규칙) + Dynamic Layer(동적 변수) ([[troubleshooting/250806_happybell80_동적프롬프트구현]])
- **우선순위 병합**: Global → Robeing → User 순서, 하위가 상위 오버라이드
## 구현 Phase
### Phase 1: DB 스키마 및 기본 인프라
## Phase 1: DB 스키마 및 기본 인프라
**파일**: `rb8001/app/state/repositories/prompt_repository.py` (신규)
- `prompt_templates` 테이블 생성
- PromptService 클래스 (조회, 병합, 캐싱)
- 기본 프롬프트 마이그레이션 (하드코딩 → DB)
- **XML 구조화된 프롬프트 저장** (현재 모든 프롬프트가 XML 구조화 완료)
- 프롬프트 작성 시 [[book/300_architecture/313_Gemini_프롬프트_설계_원칙]] 원칙 준수 필수
### Phase 2: 핵심 프롬프트 DB화
- 시스템 프롬프트 (gemini_handler, openai_handler)
- 작업 타입별 프롬프트 (chat, extract, calendar_confirm)
- **XML 구조화된 프롬프트 마이그레이션** (2025-12-25 완료)
- 모든 프롬프트가 XML 태그(`<role>`, `<constraints>`, `<task>`, `<context>`, `<output_format>` 등) 구조로 변경됨
- DB 저장 시 XML 구조 유지 필수 ([[book/300_architecture/313_Gemini_프롬프트_설계_원칙]] 참고)
- 폴백 로직 (DB 조회 실패 시 하드코딩 사용) - 필수
- DB 조회 실패/타임아웃 시 기존 _get_system_prompt() 메서드 사용
- 점진적 마이그레이션 가능, 안전한 전환 보장
## Phase 2: 핵심 프롬프트 DB화
### Phase 3: 개인화 및 동적 프롬프트
**파일**: `rb8001/app/services/llm/gemini_handler.py`, `rb8001/app/services/llm/llm_service.py`
- 시스템 프롬프트 DB 조회로 변경
- 작업 타입별 프롬프트 (chat, extract, calendar_confirm) DB화
- 폴백 로직: DB 조회 실패 시 기존 `_get_system_prompt()` 메서드 사용
## Phase 3: 개인화 및 동적 프롬프트
**파일**: `rb8001/app/services/llm/prompt_service.py` (신규)
- 사용자별 프롬프트 오버라이드
- 감정 기반 동적 프롬프트 조합
- 변수 치환 시스템 ({current_time}, {emotion_labels} 등)
- DB 저장 시 변수 플레이스홀더 유지
- 조회 후 str.format() 또는 템플릿 엔진으로 런타임 치환
- 변수 치환 시스템 ({current_time}, {emotion_labels})
### Phase 4: A/B 테스트 및 모니터링
## Phase 4: A/B 테스트 및 모니터링
**파일**: `rb8001/app/services/llm/prompt_service.py`
- 프롬프트 버전 관리
- A/B 테스트 지원 (암묵적 피드백 + 명시적 피드백)
- A/B 테스트 지원
- 롤백 기능
## 캐싱 전략
- Redis/Memory 캐시 (키: `prompt:{scope}:{type}:{version}`)
- TTL 1시간, DB 변경 시 무효화 (웹훅/이벤트)
- 캐시 히트율 99%+ 목표 (테스트 결과 99.8% 달성)
- Redis는 선택 사항: 메모리 캐시(ThreadDocCache 패턴)로 시작, 필요 시 Redis 전환
- Redis 없이도 동작하도록 폴백 로직 구현
## 구현 시 주의사항
### DB 스키마
- scope_id NULL 처리: Global scope는 scope_id=NULL로 조회 (PostgreSQL NULL은 UNIQUE 제약에서 제외되어 문제 없음)
- 각 레벨별 개별 쿼리 후 애플리케이션에서 병합 권장 (복잡한 JOIN 대신)
### 캐싱
- Redis는 선택 사항, 메모리 캐시로 시작 가능
- Redis 없이도 동작하도록 폴백 로직 구현 필수
### 변수 치환
- 템플릿 변수({current_time}, {emotion_labels})는 DB 저장 시 플레이스홀더로 유지
- 조회 후 런타임에 str.format() 또는 템플릿 엔진으로 치환
- **XML 구조 내 변수 처리**: XML 태그 내부에 변수 플레이스홀더 포함 가능
- 예: `<constraints>사용자 감정: {emotion_labels}</constraints>`
- XML 구조를 유지한 채 변수만 치환
### 폴백 전략
- DB 조회 실패/타임아웃 시 하드코딩 프롬프트 사용 (기존 코드 유지)
- 점진적 마이그레이션으로 안전한 전환 보장
## 참고 문서
- **[[book/300_architecture/313_Gemini_프롬프트_설계_원칙]]** - Gemini 프롬프트 설계 원칙 (XML 구조화, 퓨샷 예시, 구조화 등) - **필수 참고**

View File

@ -0,0 +1,86 @@
# 실제 필요한 플랜 정리
**작성일**: 2026-01-02
**목적**: plans 디렉토리 문서 중 실제로 진행해야 할 항목만 정리
---
## ✅ 완료된 항목 (archive 이동 완료)
1. **admin_dashboard_business_integration (251204)** - 완료 → archive 이동
2. **gemini_file_search_콜드메일_tdd_테스트_계획 (251110)** - 완료 → archive 이동
3. **main_db3_migration_plan (250911)** - 완료 → archive 이동
---
## 🔴 실제로 필요한 플랜 (미구현)
### 1. 베이지안 스타트업 가치평가 (251016)
**상태**: 미구현
**목표**: Neo4j + 베이지안 MCMC 확률적 가치평가
**필요 작업**:
- Phase 1: Neo4j 유사 기업 탐색 (1주)
- Phase 2: 베이지안 MCMC 확률 분포 (2주)
- Phase 3: 동적 프리미엄 학습 (1개월)
**참고**: `plans/251016_bayesian_startup_valuation.md`
### 2. LangGraph 1.0 업그레이드 (251218)
**상태**: 미구현
**목표**: HITL 패턴, 자동 상태 복구
**필요 작업**:
- LangGraph 1.0 마이그레이션
- 콜드메일 워크플로우 HITL 패턴 적용
- 프론트엔드 IR 평가 워크플로우화
**참고**: `plans/251218_langgraph_1.0_upgrade_plan.md`
### 3. 프롬프트 동적 관리 (251225)
**상태**: 미구현
**목표**: 프롬프트 DB화, 개인화, A/B 테스트
**필요 작업**:
- Phase 1: DB 스키마 및 기본 인프라
- Phase 2: 핵심 프롬프트 DB화
- Phase 3: 개인화 및 동적 프롬프트
- Phase 4: A/B 테스트 및 모니터링
**참고**: `plans/251225_프롬프트_동적관리_계획.md`
### 4. 의도 런타임 하이브리드 (251023)
**상태**: 부분 완료 (3단계 아키텍처 완료)
**목표**: FastPath + 임베딩 + LLM 하이브리드 시스템
**필요 작업**:
- SemanticIntentClassifier 구현 (임베딩 후보 축소)
- LLM 폴백 (Top-K 후보 재분석)
- 베이지안 동적 학습 (Beta(α,β) 추적, Thompson Sampling)
**참고**: `plans/251023_happybell80_의도_런타임_하이브리드_임베딩_베이지안_동적학습.md`
---
## 🟡 부분 완료 항목 (남은 작업만)
### 1. Admin Dashboard 코드 리팩토링 (251225)
- **완료**: Backend 모듈 분리
- **남은 작업**: Frontend 모듈 분리 (app.js 1132줄 → modules/*.js)
- **참고**: `plans/251225_admin_dashboard_code_refactoring.md`
### 2. 뉴스 시스템 (250906)
- **완료**: skill-news, skill-publish 분리 및 통합
- **남은 작업**: 스크래핑/요약 기능 강화, PostgreSQL rb_news 테이블 영구 저장
- **참고**: `plans/250906_news_skill_publish_separation.md`, `plans/250906_news_system_integration.md`
### 3. 콜드메일 온톨로지 (251016)
- **완료**: Phase 1 온톨로지 필터
- **남은 작업**: Phase 2 (Neo4j 기억 시스템), Phase 3 (감정-기억-윤리 삼각형)
- **참고**: `plans/251016_ontology_coldmail_implementation.md`
### 4. 의도 분석 개선 (251017)
- **완료**: 3단계 아키텍처 (IntentAnalyzer, ActionPlanner, SkillSelector)
- **남은 작업**: 하이브리드 시스템 (FastPath + 임베딩 + LLM)
- **참고**: `plans/251017_intent_analysis_improvement_plan.md`
---
## 참고 문서
- `plans/archive/260102_9월이전_미해결_항목_통합.md` (감정 시스템, 기술 부채)
- `troubleshooting/251204_admin_dashboard_business_integration.md` (완료)
- `troubleshooting/251110_claude_gemini_file_search_coldmail_integration.md` (완료)

View File

@ -11,21 +11,20 @@
**현재**: Gmail/Slack → 임시 코드 → `/auth/verify` → JWT
**문제**: Redis 의존성, 60초 TTL 제한
**개선**: JWT 직접 전달 또는 Secure cookie
**상태**: 여전히 사용 중 (`frontend-customer/src/contexts/auth-context.tsx`)
### 2. DB 스키마 불일치
**문제**: company vs workspaces 테이블 공존
**해결**: `plans/250831_workspace_unification_plan.md` 참조
### 3. 하드코딩 URL 제거
### 2. 하드코딩 URL 제거
**위치**:
- `app/providers/slack.py`: login_callback_url
- `frontend-customer/src/contexts/auth-context.tsx`: auth.ro-being.com
**해결**: 환경변수로 추출 (dev/staging/prod)
**상태**: 부분 완료 (250915 문서 참조), 일부 남아있음
### 4. 사용자 매핑 로직 개선
### 3. 사용자 매핑 로직 개선
**문제**: email 변경 시 중복 계정, workspace 없이 매핑 불가
**해결**: UserIdentityService 통합 서비스
**상태**: 미구현
---
@ -34,6 +33,7 @@
- 2025-09-15: Rate Limiting 구현
- 2025-09-04: python-multipart, Docker 정리 (3.9GB 회수)
- 2025-08-31: Slack OAuth 로그인 구현
- 2025-09-11: DB 스키마 불일치 해결 (company → workspaces 통합, `troubleshooting/250911_PostgreSQL_테이블명_단수형_통일.md`)
---
@ -54,5 +54,5 @@
## 참고
- `troubleshooting/250831_slack_oauth_login_implementation.md`
- `plans/250831_workspace_unification_plan.md`
- `troubleshooting/250911_PostgreSQL_테이블명_단수형_통일.md` (workspace 통합 완료)
- `book/300_architecture/311_FastAPI_구조_원칙.md`

View File

@ -0,0 +1,86 @@
# UUID 통합 시스템 구현 로드맵
**날짜**: 2025-08-31
**목표**: 모든 서비스에서 UUID를 Primary Key로 사용
---
## 현재 문제
- rb8001: UUID 매핑 제공하나 내부 혼용
- skill-email: slack_id 직접 사용 (UUID 미지원)
- Gateway: JWT에서 UUID 추출
- ChromaDB: 일관성 없는 collection 명명
**영향**: 서비스 간 통신 오류, 데이터 불일치
---
## Phase 1: DB 스키마 통일 (✅ 완료)
### 완료된 작업
**1. 외래 키 제약** ✅
- `conversation_log.user_id``user.id` (main_db.py:146)
- `gmail_token.user_id``user.id` (이미 구현됨)
**2. 인덱스** ⚠️ 부분 완료
- 일부 테이블에 인덱스 존재 (ir_deck_evaluations, robeing_diary 등)
- `conversation_log.user_id`, `gmail_token.user_id` 인덱스는 확인 필요
**3. 데이터 검증** ⏳ 미착수
- orphaned UUID 확인
- NULL UUID 처리
---
## Phase 2: 서비스 수정 (✅ 완료)
### skill-email ✅
- 파일: `services/db_credentials_provider.py`
- 변경: UUID 지원 추가 완료 (250920)
- 추가 수정: UUID 강제 (250926, 2025-12-17)
### rb8001 ✅
- 파일: `app/skills/email_integration.py`
- 변경: UUID 우선 사용 완료 (250926)
### ChromaDB ✅
- Collection 명명: `{service}_{identifier}_{type}` 통일 완료 (250920)
- 예: `rb8001_53529291-5050-4daa-89fb-008b546feb63_memory`
- 참고: `troubleshooting/250920_chromadb_collection_naming_unification.md`
---
## Phase 3: Gateway 통합 (✅ 완료)
### JWT 표준화 ✅
```python
{
"sub": "uuid", # user.id
"username": "happybell80",
"email": "user@example.com"
}
```
- auth-server에서 UUID를 sub에 포함하여 발급 중
### 헤더 표준화 ✅
- `X-User-Id`: UUID (모든 내부 API)
- Slack ID는 oauth_providers JSONB에만 저장
- Gateway에서 UUID 변환 후 전달 중
---
## 검증
**테스트 시나리오**:
1. Gmail 재인증 → JWT 발급 → UUID 확인
2. skill-email 호출 → UUID로 토큰 조회
3. ChromaDB 저장 → collection 명명 확인
---
## 참고
- `troubleshooting/250911_PostgreSQL_테이블명_단수형_통일.md`
- `troubleshooting/250924_UUID_체계_전환_및_대화저장_오류.md`

View File

@ -0,0 +1,72 @@
# 9월 이전 계획 문서 미해결 항목 통합
**작성일**: 2026-01-02
**목적**: 9월 이전 계획 문서 중 미해결 항목 통합 정리
---
## 1. 감정 시스템 확장 (250808)
### Phase 4: 32개 세밀 감정 (미구현)
- **목표**: Plutchik 감정 휠 기반 32개 감정
- **필요 작업**: AI Hub 데이터 재라벨링 (7 → 32개), 모델 재학습, skill-embedding API 확장
- **예상 기간**: 2-3개월
- **참고**: `plans/archive/250808_감정시스템_현실적용_5단계_로드맵.md`
### Phase 5: 감정 기억 시스템 (부분 구현)
- **구현 완료**: Neo4j에 감정 노드 저장 (`rb8001/app/services/memory/neo4j_client.py`)
- **미구현**: 시간별 감정 변화 추적, 패턴 분석 (우울증 조기 감지 등)
- **예상 기간**: 1개월
- **참고**: `troubleshooting/251016_phase2_hybrid_memory_implementation.md`
### Phase 3 미구현 항목
- 감정 기반 응답 톤 조정 (현재 LLM에만 의존)
- 감정 기록 및 패턴 분석 DB
- **참고**: `troubleshooting/251002_emotion_system_todo.md`
---
## 2. 기술 부채 (250831)
### 임시 코드 방식 제거
- **현재**: Gmail/Slack → 임시 코드 → `/auth/verify` → JWT
- **문제**: Redis 의존성, 60초 TTL 제한
- **개선**: JWT 직접 전달 또는 Secure cookie
- **상태**: 여전히 사용 중
- **참고**: `frontend-customer/src/contexts/auth-context.tsx`, `plans/archive/250831_todo_and_tech_debt.md`
### 하드코딩 URL 제거
- **위치**: `app/providers/slack.py`, `frontend-customer/src/contexts/auth-context.tsx`
- **상태**: 부분 완료 (일부 남아있음)
- **참고**: `troubleshooting/250915_hardcoded_url_removal.md`
### 사용자 매핑 로직 개선
- **문제**: email 변경 시 중복 계정, workspace 없이 매핑 불가
- **해결**: UserIdentityService 통합 서비스
- **상태**: 미구현
- **참고**: `plans/archive/250831_todo_and_tech_debt.md`
### 보안 개선
- Refresh Token 구현
- PKCE 적용
- 토큰 암호화 저장
- **상태**: 미구현
---
## 완료된 항목 (삭제됨)
- ✅ **서비스 재구조화 (250807)**: robeing-control 분리 → admin-dashboard로 대체 완료 (251204)
- ✅ **Workspace 통합 (250831)**: company → workspaces 통합 완료 (250911)
- ✅ **UUID 통합 시스템 (250831)**: skill-email UUID 지원, ChromaDB 명명 규칙 통일, Gateway JWT 표준화 완료
---
## 참고 문서
- `plans/archive/250808_감정시스템_현실적용_5단계_로드맵.md`
- `plans/archive/250831_todo_and_tech_debt.md`
- `plans/archive/250831_unified_id_system_implementation_roadmap.md` (완료)
- `troubleshooting/251002_emotion_system_todo.md`
- `troubleshooting/250915_hardcoded_url_removal.md`

View File

@ -0,0 +1,96 @@
# rb8001 계층 분리 리팩토링 Phase 2 완료
**날짜**: 2026-01-02
**작성자**: happybell80
**관련 파일**:
- `rb8001/app/services/coldmail_filter.py`
- `rb8001/app/services/startup_valuation.py`
- `rb8001/app/services/intent_bayes.py`
- `rb8001/app/services/diary/aggregator.py`
- `rb8001/app/services/skills/dm_skill.py`
- `rb8001/app/services/naverworks_file_processor.py`
- `rb8001/app/state/repositories/`
---
## 문제 상황
계획 문서(`251123_rb8001_계층_분리_리팩토링_계획.md`)에서 Phase 2 미완료 위반 사항 6개:
1. router/feedback_handler.py:58 - SessionLocal() 직접 사용
2. router/intent_review_endpoint.py:21 - SessionLocal() 직접 사용
3. router/slack_handler.py:77,202,361 - SessionLocal() 직접 사용
4. services/startup_valuation.py:475 - asyncpg.connect() 직접 사용
5. services/intent_bayes.py:57,117,160 - psycopg2.connect() 직접 사용
6. services/coldmail_filter.py:182,208,255 - asyncpg.connect() 직접 사용
**원칙 위반**: `311_FastAPI_구조_원칙.md` 6장 - DB 접근은 state/repositories를 통해서만
---
## 해결 방안
### 1. state/repositories/ 폴더 생성
- `app/state/repositories/` 폴더 생성
- 기존 repository 파일들은 `state/`에 유지 (이미 올바른 위치)
### 2. Repository 패턴 구현 (TDD)
- **coldmail_classifier_repository.py**: coldmail_classifier 테이블 CRUD
- `get_word_counts()`, `get_all_coldmail_counts()`, `get_vocabulary_size()`, `update_word_count()`, `initialize_seed_data()`
- **startup_valuation_repository.py**: startup_valuation 테이블 저장
- `save_valuation()`
- **intent_classifier_repository.py**: intent_classifier 테이블 CRUD (동기)
- `ensure_setup()`, `get_totals()`, `get_counts()`, `update_counts()`
- **user_repository.py**: user, user_preference 테이블 조회
- `get_user_news_keywords()`, `get_user_uuid_by_slack_id()`, `get_user_team_id()`
### 3. Services 수정
- `coldmail_filter.py`: asyncpg.connect() 3곳 → repository 호출로 변경
- `startup_valuation.py`: asyncpg.connect() 1곳 → repository 호출로 변경
- `intent_bayes.py`: psycopg2.connect() 3곳 → repository 호출로 변경
- `diary/aggregator.py`: SessionLocal() 1곳 → conversation_repository 호출로 변경
- `skills/dm_skill.py`: SessionLocal() 1곳 → user_repository 호출로 변경
- `naverworks_file_processor.py`: SessionLocal() 2곳 → user_repository 호출로 변경
### 4. conversation_repository 확장
- `get_conversations_by_time_range()` 메서드 추가
---
## 구현 완료
**커밋**: 작업 완료
**수정 파일**:
- `app/state/repositories/coldmail_classifier_repository.py` (신규)
- `app/state/repositories/startup_valuation_repository.py` (신규)
- `app/state/repositories/intent_classifier_repository.py` (신규)
- `app/state/repositories/user_repository.py` (신규)
- `app/services/coldmail_filter.py`
- `app/services/startup_valuation.py`
- `app/services/intent_bayes.py`
- `app/services/diary/aggregator.py`
- `app/services/skills/dm_skill.py`
- `app/services/naverworks_file_processor.py`
- `app/state/conversation_repository.py`
---
## 교훈
### TDD 방식 적용
- 테스트 먼저 작성 (Red) → Repository 구현 (Green) → Services 수정 (Refactor)
- `test_coldmail_classifier_repository.py` 작성으로 기대 동작 명확화
### Repository 패턴 일관성
- asyncpg/psycopg2 직접 연결을 repository로 캡슐화
- 각 repository는 단일 테이블/도메인 전담
- 연결 관리(생성/종료)는 repository 내부에서 처리
### 계층 분리 원칙 준수
- services에서 DB 직접 연결 금지, state/repositories를 통해서만 접근
- router는 FastAPI 의존성 주입 패턴 사용 (`get_db()` 함수는 정상)
### 남은 작업
- `diary/aggregator.py`에 SessionLocal() 직접 사용 3곳 추가 수정 필요
- `router/slack_handler.py`의 SessionLocal() 사용 확인 필요 (의존성 주입 패턴일 수 있음)
- 나머지 asyncpg/psycopg2 직접 연결 10곳 추가 수정 필요