# 로빙 아키텍처 원칙 위반 현황 및 개선 계획

## 작성일: 2025-10-04 23:01:59
## 작성자: happybell80
## 위치: `/home/happybell80/ivada_project/DOCS/troubleshooting/20251004_happybell80_로빙_뇌_기관_원칙_위반_현황.md`
## 상태: 인지 완료, 점진적 개선 예정

---

## 문제 인식

skill-slack 리포지토리에 Slack Lists API 테스트 파일이 추가되면서, 현재 rb8001이 Slack API를 직접 호출하는 구조가 로빙 아키텍처 원칙에 위배됨을 재확인했다.

## 로빙 아키텍처 핵심 원칙

### 출처: `/DOCS/300_architecture/360_로빙_컨테이너_경량화_전략.md:7`
> "컨테이너는 몸, 기억은 영혼 - 100개 로빙이 하나의 스킬 서비스를 공유한다"

### 출처: `/DOCS/300_architecture/README.md:38`
> "Backend: FastAPI + Celery (로빙의 두뇌와 신경계)"

### 원칙 정리
- **로빙 컨테이너 (rb8001) = 두뇌(뇌)**: 판단과 라우팅만 수행
- **스킬 서비스 (skill-*) = 운동기관/감각기관**: 실제 실행 담당
- **DB (PostgreSQL/ChromaDB) = 기억/영혼**: 상태 저장

### 출처: `/DOCS/troubleshooting/250721_happybell80_이메일스킬HTTP분리및아키텍처전환.md:99-113`
> **교훈**
> 1. "빠른 개발"이 항상 빠르지 않음
> 2. 아키텍처 원칙을 지키는 것이 장기적으로 이득
> 3. 마이크로서비스는 처음부터 제대로 분리해야 함
>
> **CLAUDE.md 업데이트**
> - 스킬 포트 범위: 8501-8599
> - HTTP API 통신 원칙 명시
> - 직접 import 금지 규칙 추가

---

## 현재 원칙 위반 현황

### 1. Slack API 직접 호출 위반

#### 250915_happybell80_Slack_메시징_운영_런북.md
- **20-36줄**: `rb8001/app/router/slack_handler.py`가 WebClient로 직접 `chat_postMessage` 호출
- **38-45줄**: `rb8001/app/skills/dm_skill.py`가 직접 Slack SDK 사용
- **47-59줄**: `rb8001/app/skills/news_posting_skill.py`가 직접 Slack SDK 사용
- **176줄**: "이벤트/인터랙티브 응답: rb8001 slack_handler가 채널/스레드로 직접 전송"

#### 250930_naverworks_slack_03_cold_mail_list.md
- **36-40줄**: `rb8001/app/services/slack_lists_client.py` - 직접 Slack Lists API 호출 (aiohttp 사용)
- **문제**: rb8001(뇌)이 직접 손을 움직이는 격

### 2. 스킬 직접 Import 위반

#### 250819_rb8001_gmail_integration_completed.md
- Gmail 스킬을 직접 import하는 구조 (HTTP API 사용 안함)

#### 250914_happybell80_깡프로뉴스_용어추출_기능추가.md
- rb8001이 스킬 로직 직접 포함

#### 250909_ocr_skill_implementation_plan.md
- 스킬 직접 import 계획

### 3. 관련 위반 사례

#### 250903_slack_multi_workspace_token_issue.md
- rb8001이 여러 Slack 토큰 직접 관리

#### 250906_news_skill_publish_separation.md, 250907_company_x_news_implementation.md
- rb8001이 뉴스 게시 직접 수행

---

## 위반 패턴 분석

### 잘못된 흐름 (현재)
- rb8001(뇌) → 직접 Slack API 호출
- rb8001(뇌) → 직접 Lists API 호출
- rb8001(뇌) → 스킬 로직 import

### 올바른 흐름 (목표)
- rb8001(뇌) → skill-slack(손)에 HTTP 요청 → Slack API 호출
- rb8001(뇌) → skill-slack(손)에 HTTP 요청 → Lists API 호출
- rb8001(뇌) → skill-*(기관)에 HTTP 요청 → 스킬 실행

---

## 개선 계획

### Phase 1: skill-slack Lists API 엔드포인트 추가 (우선)
1. skill-slack에 `/api/v1/lists/items` 엔드포인트 구현
   - POST: 리스트 아이템 생성 (slackLists.items.create)
   - GET: 리스트 아이템 조회 (slackLists.items.list)
   - PUT: 리스트 아이템 수정 (slackLists.items.update)
2. `tests/test_slack_lists.py`의 헬퍼 함수를 서비스 모듈로 이동
3. rb8001의 `slack_lists_client.py` → skill-slack HTTP 호출로 변경

### Phase 2: rb8001 Slack 직접 호출 제거
1. rb8001/app/router/slack_handler.py → skill-slack /api/v1/send 사용
2. rb8001/app/skills/dm_skill.py → skill-slack HTTP 호출로 변경
3. rb8001/app/skills/news_posting_skill.py → skill-slack HTTP 호출로 변경
4. Slack SDK (slack_sdk) 의존성 제거

### Phase 3: 기타 스킬 분리
1. Gmail 스킬 HTTP API로 완전 분리
2. OCR 스킬 분리 시 HTTP API 기본 적용
3. 뉴스 스킬 로직 분리

### Phase 4: 문서 업데이트
1. 위반 사례 문서에 "개선 완료" 표시
2. 아키텍처 원칙 문서 강화
3. 신규 스킬 개발 시 체크리스트 추가

---

## 즉시 적용 가능한 원칙

### skill-slack 테스트 파일 활용
1. `/home/happybell80/ivada_project/skill-slack/tests/test_slack_lists.py`의 헬퍼 함수:
   - `list_all_items()` → GET 엔드포인트
   - `add_file_to_list()` → POST 엔드포인트
2. 실제 컬럼 구조 확인 후 구현 (추측 금지)
3. rb8001은 HTTP로만 호출

### 개발 체크리스트
1. 로빙이 외부 API를 직접 호출하는가? → 스킬로 분리
2. 로빙이 스킬 로직을 포함하는가? → HTTP API로 분리
3. 로빙이 스킬을 import하는가? → HTTP 클라이언트로 교체

---

## 교훈

1. **"빠른 개발"의 함정**: 직접 호출이 당장은 빠르지만, 나중에 더 큰 리팩토링 비용 발생
2. **아키텍처 일관성**: 원칙을 지키면 100개 로빙 운영 시 리소스 절감 (뇌 = 512MB, 스킬 = 공유)
3. **문서의 중요성**: 원칙 문서가 있었지만 실제 코드에 반영 안됨 → 주기적 점검 필요

---

## 참고 문서

- `/DOCS/300_architecture/360_로빙_컨테이너_경량화_전략.md` - 핵심 원칙
- `/DOCS/300_architecture/README.md` - 아키텍처 개요
- `/DOCS/troubleshooting/250721_happybell80_이메일스킬HTTP분리및아키텍처전환.md` - 성공 사례
- `/DOCS/troubleshooting/250915_happybell80_Slack_메시징_운영_런북.md` - 위반 현황
- `/DOCS/troubleshooting/250930_naverworks_slack_03_cold_mail_list.md` - Lists API 위반

---

*"컨테이너는 몸, 기억은 영혼 - 뇌는 판단만, 손발은 스킬이 담당한다"*
