From c024087c942b69719714d1b0dfbda3944301ccb4 Mon Sep 17 00:00:00 2001 From: gahusb Date: Fri, 12 Jun 2026 07:34:31 +0900 Subject: [PATCH] =?UTF-8?q?feat(co-gahusb):=20FE=20=ED=81=B4=EB=9D=BC?= =?UTF-8?q?=EC=9D=B4=EC=96=B8=ED=8A=B8=20=EB=B0=B0=EC=84=A0=20(.mcp.json?= =?UTF-8?q?=20+=20=EC=97=AD=ED=95=A0=20=EB=B8=94=EB=A1=9D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .mcp.json | 9 ++++ CLAUDE.md | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 .mcp.json diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..7da5f7f --- /dev/null +++ b/.mcp.json @@ -0,0 +1,9 @@ +{ + "mcpServers": { + "co-gahusb": { + "type": "http", + "url": "https://gahusb.synology.me/api/co/mcp", + "headers": { "Authorization": "Bearer ${CO_BUS_KEY}" } + } + } +} diff --git a/CLAUDE.md b/CLAUDE.md index 2ec8822..dd35849 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,8 +27,18 @@ | `/lab/music` | `MusicStudio` | AI 음악 생성 스튜디오 (Sonic Forge) | | `/todo` | `Todo` | 태스크 보드 | | `/insta` | `InstaCards` | 뉴스 키워드 발굴 → AI 카드 10장 자동 생성 → 인스타 업로드 | -| `/agent-office` | `AgentOffice` | AI 에이전트 가상 오피스 (WebSocket + 채팅) | +| `/agent-office` | `AgentOffice` | AI 에이전트 가상 오피스 (WebSocket + 채팅 + LogTab 5초 폴링 source 뱃지) | | `/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` @@ -128,6 +138,23 @@ proxy: { | 포트폴리오 | GET | `/api/profile/public` — personal 서비스 | | 포트폴리오 | POST | `/api/profile/auth` — 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`) NAS의 music-lab 컨테이너 대신 Windows PC(RTX 5070 Ti)에서 MusicGen을 로컬 추론하는 별도 서버. @@ -372,3 +495,14 @@ web-ui → POST /api/music/generate (NAS music-lab) ``` 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=)` + `list_tasks(assignee_role="FE")` 확인. +- 키 `CO_BUS_KEY`는 환경변수로 주입(커밋 금지).