merge: co-gahusb FE 클라이언트 배선 (.mcp.json + 역할 블록)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-12 07:51:34 +09:00
2 changed files with 144 additions and 1 deletions

9
.mcp.json Normal file
View File

@@ -0,0 +1,9 @@
{
"mcpServers": {
"co-gahusb": {
"type": "http",
"url": "https://gahusb.synology.me/api/co/mcp",
"headers": { "Authorization": "Bearer ${CO_BUS_KEY}" }
}
}
}

136
CLAUDE.md
View File

@@ -27,8 +27,18 @@
| `/lab/music` | `MusicStudio` | AI 음악 생성 스튜디오 (Sonic Forge) | | `/lab/music` | `MusicStudio` | AI 음악 생성 스튜디오 (Sonic Forge) |
| `/todo` | `Todo` | 태스크 보드 | | `/todo` | `Todo` | 태스크 보드 |
| `/insta` | `InstaCards` | 뉴스 키워드 발굴 → AI 카드 10장 자동 생성 → 인스타 업로드 | | `/insta` | `InstaCards` | 뉴스 키워드 발굴 → AI 카드 10장 자동 생성 → 인스타 업로드 |
| `/agent-office` | `AgentOffice` | AI 에이전트 가상 오피스 (WebSocket + 채팅) | | `/agent-office` | `AgentOffice` | AI 에이전트 가상 오피스 (WebSocket + 채팅 + LogTab 5초 폴링 source 뱃지) |
| `/portfolio` | `Portfolio` | 개인 포트폴리오 (프로필·경력·프로젝트·자기소개) | | `/portfolio` | `Portfolio` | 개인 포트폴리오 (프로필·경력·프로젝트·자기소개) |
| `/saju` | `Saju` | 호령 사주 v2 — 메인/입력 (mobile night-bg + desktop mt-wash 산수화, useViewportMode 1024px 분기) |
| `/saju/result?rid=N` | `SajuResult` | 사주 풀이 결과 (4탭: Basic/Chart/Flow/Traits) |
| `/saju/today?rid=N` | `Today` | 오늘의 운세 (FortuneRing + 4 ScoreCard + LuckyBox + good_signs/warnings) |
| `/saju/compatibility` | `Compatibility` | 궁합 입력 (두 사람 폼) |
| `/saju/compatibility/result?cid=N` | `CompatibilityResult` | 궁합 점수 + 요약 + strengths/challenges |
| `/saju/me` | `SajuMe` | 마이페이지 placeholder ("곧 만나요" + 4 비활성 카드) |
| `/tarot` | `Tarot` | 타로 메인 (agent-office에서 분리, tarot-lab API) |
| `/tarot/today` | `TarotTodayCard` | 오늘의 카드 (one_card spread) |
| `/tarot/reading` | `TarotReading` | 멀티 카드 스프레드 리딩 (three_card 등) |
| `/tarot/history` | `TarotHistory` | 리딩 이력 조회 |
라우트 정의: `src/routes.jsx` / 라우터 설정: `src/Router.jsx` 라우트 정의: `src/routes.jsx` / 라우터 설정: `src/Router.jsx`
@@ -128,6 +138,23 @@ proxy: {
| 포트폴리오 | GET | `/api/profile/public` — personal 서비스 | | 포트폴리오 | GET | `/api/profile/public` — personal 서비스 |
| 포트폴리오 | POST | `/api/profile/auth` — personal 서비스 | | 포트폴리오 | POST | `/api/profile/auth` — personal 서비스 |
| 포트폴리오 | CRUD | `/api/profile/careers`, `/api/profile/projects`, `/api/profile/skills`, `/api/profile/introductions` — personal 서비스 | | 포트폴리오 | CRUD | `/api/profile/careers`, `/api/profile/projects`, `/api/profile/skills`, `/api/profile/introductions` — personal 서비스 |
| 사주 | POST | `/api/saju/interpret` — body: `{ year, month, day, hour, gender, calendar_type, is_leap_month? }` → reading_id + saju_data + analysis + fortune_scores + lucky + monthly_flow |
| 사주 | GET | `/api/saju/readings/:id` — 저장된 사주 조회 (`useSajuReading` hook 사용) |
| 사주 | GET | `/api/saju/current-fortune?reading_id=N` — 현재 연도 세운 |
| 사주 | PATCH/DELETE | `/api/saju/readings/:id` — 즐겨찾기·메모 / 삭제 |
| 사주 | GET | `/api/saju/readings?page=1&size=20&favorite=bool` — 목록 |
| 궁합 | POST | `/api/saju/compat/interpret` — body: `{ person_a, person_b }` → compat_id + score + interpretation |
| 궁합 | GET | `/api/saju/compat/readings/:id` — 궁합 결과 |
| 궁합 | PATCH/DELETE | `/api/saju/compat/readings/:id` |
| 타로 | POST | `/api/tarot/interpret` — body: `{ spread_type, category, question, cards }` → interpretation_json (DB 저장 X) |
| 타로 | POST | `/api/tarot/readings` — 확정 후 저장 |
| 타로 | GET | `/api/tarot/readings?page=1&spread_type=X&category=Y` — 목록 |
| 타로 | GET/PATCH/DELETE | `/api/tarot/readings/:id` |
| 영상 생성 | POST | `/api/video/generate` — body: `{ provider, prompt, params }` → task_id (sora/veo/kling/seedance) |
| 영상 생성 | GET | `/api/video/tasks/:id`, `/api/video/providers` |
| 이미지 생성 | POST | `/api/image/generate` — body: `{ provider, prompt, params }` → task_id (gpt_image/nano_banana/flux) |
| 이미지 생성 | GET | `/api/image/tasks/:id`, `/api/image/providers` |
| 에이전트 로그 | GET | `/api/agent-office/agents/:id/logs?limit=50` — DB agent_logs + 컨테이너 `/logs/recent` 병합 |
--- ---
@@ -332,6 +359,102 @@ handleGenerate()
--- ---
## 호령 사주 v2 — `/saju` 라우트 트리
2026-05-27 풀 리디자인 (Phase 1-6, 30 commits). v1 `components/` + `Saju.css` 일괄 삭제 후 신규 디자인 시스템 도입.
### 디자인 컨셉
한국 전통 명리학 미학 + 호령 캐릭터. Inter/Roboto 같은 generic AI sans 회피.
- **타이포**: Nanum Myeongjo (display, weight 800) + Nanum Gothic (body) + Gowun Batang (fallback serif). `index.html` head에서 preconnect + link 일괄 로드 (기존 Noto Serif KR도 v1 호환 유지)
- **컬러**: navy `#1F2A44` dominant + gold `#D4AF37` accent + ivory `#F7F2E8` paper. 화면별 단일 accent (홈=navy, 오늘=gold, 궁합=green, 사주풀이=purple, 마이=gray)
- **차별화 요소**: `OrnateFrame` (4 코너 꺽쇠 + double border), `MascotBubble` (paw-bob 2.4s 애니메이션), `OrnamentBloom` (꽃봉오리 SVG), `mt-wash` (산수화 SVG 데스크탑 배경)
### 디렉토리 구조
```
src/pages/saju/
├── _shell/ # 디자인 시스템 + 네비
│ ├── tokens.css # CSS 변수 (.saju-v2 scope)
│ ├── shell.css # paper-bg/night-bg/mt-wash/screenIn/paw-bob
│ ├── useViewportMode.js # 1024px breakpoint hook
│ ├── BottomNav.jsx # 모바일 5항목
│ ├── DesktopHeader.jsx # 데스크탑 헤더 nav
│ ├── Mascot.jsx # 7 variant 매핑 (full/head/upper/greeting/thinking/pointing/happy)
│ ├── MascotBubble.jsx # 4 tone (ivory/navy/green/purple)
│ ├── OrnateFrame.jsx
│ ├── OrnamentBloom.jsx
│ ├── TopRibbon.jsx
│ ├── TitleBlock.jsx
│ ├── PrimaryButton.jsx
│ ├── GhostButton.jsx
│ ├── InputRow.jsx
│ ├── Icons.jsx # 5 nav + IconPaw/Chevron/Sparkle
│ └── helpers/
│ ├── hexA.js # hex + alpha → rgba
│ ├── daeunLabel.js # 나이 → 8 인생 단계 label
│ ├── deriveTraits.js # element_scores → 6 성향
│ └── colorMap.js # 오행 한자 → CSS var + 한글/한자
├── views/ # mobile/desktop 컴포넌트 분리
│ ├── home.{mobile,desktop}.jsx
│ ├── saju.{mobile,desktop}.jsx # 4탭 (Basic/Chart/Flow/Traits)
│ ├── today.{mobile,desktop}.jsx
│ └── match.{mobile,desktop}.jsx
├── hooks/
│ ├── useSajuForm.js # 폼 상태 (year/month/day/hour/gender/calendar_type, handleChange(field,value) 콜백)
│ └── useSajuReading.js # rid 기반 { data, loading, error }
├── Saju.jsx # /saju 진입 router
├── SajuResult.jsx # /saju/result 진입 (Empty/Loading/Error state)
├── Today.jsx
├── Compatibility.jsx
├── CompatibilityResult.jsx
└── Me.jsx # placeholder
```
### 응답 schema 매핑 (saju-lab → view)
`useSajuReading(rid).data` 구조:
- `saju_data.{year,month,day,hour}``{stem, stem_kr, branch, branch_kr, ten_god, fortune}` (4기둥)
- `analysis_data.element_scores` (한자 키 `木/火/土/金/水`) — view에서 `wood/fire/earth/metal/water`로 매핑 (`HANJA_TO_ID`)
- `analysis_data.day_master_strength.{result, score, reasons}` (신강신약)
- `daeun_data` (8개): `{age, start_year, end_year, stem, branch, stem_kr, branch_kr}` — 현재 판정 `start_year ≤ currentYear ≤ end_year`
- `interpretation_json.{summary, items: [{key,title,content,evidence}], advice}`
- `fortune_scores.{wealth, romance, social, career, overall}` (0-100)
- `lucky.{color: string[], number, direction, good_signs: string[], warnings: string[]}`
### 반응형 전략
1024px breakpoint로 모바일/데스크탑 컴포넌트 트리 완전 분리:
- 모바일 (< 1024): `night-bg` 또는 `paper-bg`, BottomNav 하단 fixed + safe-area
- 데스크탑 (≥ 1024): `mt-wash` 산수화 배경, DesktopHeader sticky top, content max-width 1200px
### 호령 자산
`public/images/saju/horyung/` 7 PNG (horyung-main/bust/front/greeting/thinking/pointing/happy). Mascot variant API가 매핑:
- `full` → horyung-main, `head` → horyung-bust, `upper` → horyung-front, 나머지는 1:1
---
## 타로 — `/tarot` 라우트 트리
agent-office에서 독립 라우트로 분리 (백엔드는 `tarot-lab` 컨테이너).
| 경로 | 컴포넌트 | 백엔드 |
|------|----------|--------|
| `/tarot` | `Tarot` | tarot-lab `/api/tarot/interpret` |
| `/tarot/today` | `TarotTodayCard` | one_card spread |
| `/tarot/reading` | `TarotReading` | three_card spread + 멀티 |
| `/tarot/history` | `TarotHistory` | `/api/tarot/readings` 목록 |
해석 흐름 (interpret ↔ save 분리):
1. 사용자가 카드 배치 → `POST /api/tarot/interpret` → Claude 응답 (DB 저장 X)
2. 사용자 확정 또는 reroll 결정
3. 확정 후 `POST /api/tarot/readings` → DB 저장 + reading_id 반환
`useTarotReading(id)` + `useTarotShuffle()` hook (`src/pages/tarot/hooks/`).
---
## Windows AI 서버 (`C:\Users\jaeoh\Desktop\workspace\music_ai`) ## Windows AI 서버 (`C:\Users\jaeoh\Desktop\workspace\music_ai`)
NAS의 music-lab 컨테이너 대신 Windows PC(RTX 5070 Ti)에서 MusicGen을 로컬 추론하는 별도 서버. NAS의 music-lab 컨테이너 대신 Windows PC(RTX 5070 Ti)에서 MusicGen을 로컬 추론하는 별도 서버.
@@ -372,3 +495,14 @@ web-ui → POST /api/music/generate (NAS music-lab)
``` ```
Windows 방화벽에서 포트 8765 인바운드 허용 필요. Windows 방화벽에서 포트 8765 인바운드 허용 필요.
---
## 협업 팀 버스 (co-gahusb) — 이 세션의 역할: **FE**
이 세션은 프론트엔드(FE) 역할이다. co-gahusb MCP 툴로 다른 세션(BE/AI/Producer)과 협업한다.
- **소유권**: 이 세션은 `web-ui` repo만 쓴다(BE=web-backend, AI=web-ai).
- **공유 리소스 변경 전 반드시 `acquire_lock(resource, "FE")`**: 대상 = `nas-deploy`, `stock-db-schema`, `lotto-db-schema`, `memory-mirror`, `nginx-conf`, `compose`. 점유 중이면 대기, 긴 작업은 `heartbeat_lock`, 끝나면 `release_lock`.
- **모든 툴 호출에 `role="FE"`** (또는 `from_role`/`created_by`에 FE).
- **수신**: `/loop`로 주기적으로 `read_inbox("FE", after_id=<last>)` + `list_tasks(assignee_role="FE")` 확인.
-`CO_BUS_KEY`는 환경변수로 주입(커밋 금지).