31 KiB
CLAUDE.md — web-backend 프로젝트 가이드
Claude Code가 이 프로젝트를 작업할 때 참조하는 안정적 카탈로그. 포트·nginx 라우팅·서비스별 API 엔드포인트 목록·공통 규칙만 담는다. DB 스키마 세부·스케줄러 잡·환경변수 세부·최근 기능 히스토리는 서비스별 메모리(
service_<name>.md)가 authoritative — 9번 섹션 각 서비스 끝의 메모리 포인터 참조.
0. 메모리 구조 규칙 (하네스 엔지니어링)
이 모노레포는 서비스당 1개 메모리 파일(memory/service_<name>.md)로 운영 상태를 관리한다.
- CLAUDE.md (이 파일, 항상 로딩) = 변하지 않는 지도: 포트, nginx 라우팅, 서비스 한 줄 역할, API 엔드포인트 목록, cross-cutting 규칙.
service_<name>.md(관련 시 recall) = 휘발성 상세: DB 테이블+컬럼, 스케줄러 cron, 환경변수, provider/큐 흐름, 비자명한 함정, 최근 기능 작업 히스토리.
작업 시작 전: 해당 서비스의 service_<name>.md를 먼저 읽어 최신 운영 상태·함정을 확인할 것. 14개 서비스 전부 메모리 파일이 있다(MEMORY.md 인덱스 참조).
변경 후: DB 스키마/스케줄러/운영 흐름이 바뀌면 CLAUDE.md가 아니라 해당 서비스 메모리를 갱신할 것.
1. 프로젝트 개요
Synology NAS 기반의 개인 웹 플랫폼 백엔드 모노레포.
- 서비스 14개: lotto, stock, music-lab, video-lab, image-lab, insta-lab, realestate-lab, agent-office, tarot-lab, saju-lab, personal, packs-lab, travel-proxy, deployer
- 공유 인프라:
_shared/access_log모듈 (5개 서비스 공유),redis(music/video/image/insta-lab 큐 공유) - 렌더/생성 위임: music/video/image/insta의 무거운 생성·렌더는 Windows AI 워커(
web-ai별도 레포)가 담당. NAS 서비스는 Redis 큐 push + 결과 webhook 수신만 한다. - 프론트엔드: 별도 레포 (React + Vite SPA), 빌드 산출물만 NAS에 배포
- 인프라: Docker Compose (16+ 컨테이너) + Nginx(리버스 프록시) + Gitea Webhook 자동 배포
2. NAS 환경
| 항목 | 값 |
|---|---|
| 장비 | Synology NAS |
| CPU | Intel Celeron J4025 (2 Core, 2.0 GHz) |
| 메모리 | 18 GB |
| Docker | Synology Container Manager |
| Git 서버 | Gitea (self-hosted, NAS 내부) |
| AI 서버 | Windows PC (192.168.45.59) — NVIDIA RTX 5070 Ti (16GB VRAM) + Ollama. 상세 → infra_windows_ai.md 메모리 |
3. NAS 디렉토리 구조
/volume1
├── docker/webpage/ # 운영 런타임 (Docker Compose 실행 위치)
│ ├── <service>/ # 각 서비스 소스 (rsync 동기화)
│ ├── nginx/default.conf # Nginx 설정
│ ├── scripts/deploy.sh # Webhook 트리거 배포 스크립트
│ ├── docker-compose.yml
│ ├── .env # 운영 환경변수
│ └── data/ # SQLite DB + 생성 미디어 (*.db, music/, video/, image/, insta_cards/ 등)
│
├── workspace/web-page-backend/ # Git 레포 클론 위치 (REPO_PATH)
│
└── web/images/webPage/travel/ # 원본 여행 사진 (RO 마운트)
배포 흐름·런타임 함정 상세 → service_deployer.md, feedback_nas_deploy_runtime.md 메모리.
4. Docker 서비스 & 포트
| 컨테이너 | 포트 | 역할 |
|---|---|---|
lotto |
18000 | 로또 데이터 수집·분석·추천 API |
stock |
18500 | 주식 뉴스·AI 분석·KIS API 연동 + 보유종목 인텔리전스 |
music-lab |
18600 | AI 음악 생성 게이트웨이 (Suno/MusicGen 호출은 Windows 워커, NAS는 Redis push) |
video-lab |
18801 | 동영상 생성 게이트웨이 (sora/veo/kling/seedance, Redis 큐) |
image-lab |
18802 | 이미지 생성 게이트웨이 (gpt_image/nano_banana/flux, Redis 큐) |
insta-lab |
18700 | 인스타 카드 피드 자동 생성 (렌더는 Windows insta-render 워커) |
realestate-lab |
18800 | 부동산 청약 자동 수집·매칭 API |
agent-office |
18900 | AI 에이전트 오피스 (실시간 WebSocket + 텔레그램 연동) |
tarot-lab |
18250 | 타로 카드 해석 (Claude Sonnet 3-card, agent-office에서 분리) |
saju-lab |
18300 | 사주 분석 + 궁합 (Claude Sonnet, TS→Python 포팅, lunar↔solar 내장) |
packs-lab |
18950 | NAS 자료 다운로드 자동화 (DSM 공유 링크 + 5GB 업로드, Vercel SaaS와 HMAC 통신) |
personal |
18850 | 개인 서비스 (포트폴리오·블로그·투두 통합) |
travel-proxy |
19000 | 여행 사진 API + 썸네일 생성 |
redis |
6379 | 비동기 큐 (music/video/image/insta-lab 공유) |
frontend (nginx) |
8080 | 정적 SPA 서빙 + API 리버스 프록시 |
webpage-deployer |
19010 | Gitea Webhook 수신 → 자동 배포 |
5. Nginx 라우팅 규칙
| 경로 | 프록시 대상 | 비고 |
|---|---|---|
/api/ |
lotto:8000 |
lotto API (catch-all fallback) |
/api/travel/ |
travel-proxy:8000 |
travel API (proxy_read_timeout 600s) |
/api/stock/ |
stock:8000 |
stock API |
/api/trade/ |
stock:8000 |
KIS 실계좌 API |
/api/portfolio |
stock:8000 |
trailing slash 유무 모두 매칭 |
/api/music/ |
music-lab:8000 |
AI 음악 생성·라이브러리 API (660s) |
/api/video/ |
video-lab:8000 |
동영상 생성 게이트웨이 (120s) |
/api/image/ |
image-lab:8000 |
이미지 생성 게이트웨이 (120s) |
/api/insta/ |
insta-lab:8000 |
인스타 카드 자동 생성 API (300s) |
/api/realestate/ |
realestate-lab:8000 |
부동산 청약 API |
/api/tarot/ |
tarot-lab:8000 |
타로 해석 (proxy_read/send_timeout 600s, Claude 3-card 응답) |
/api/saju/ |
saju-lab:8000 |
사주 분석 (300s) |
/api/todos |
personal:8000 |
투두 API |
/api/blog/ |
personal:8000 |
블로그 API |
/api/profile/ |
personal:8000 |
포트폴리오 API |
/api/agent-office/ |
agent-office:8000 |
AI 에이전트 오피스 API + WebSocket (86400s) |
/api/packs/upload |
packs-lab:8000 |
5GB multipart 업로드 (client_max_body_size 5G, proxy_request_buffering off, 1800s timeout) |
/api/packs/ |
packs-lab:8000 |
다운로드/list |
/api/internal/insta/ |
insta-lab:8000 |
Windows 워커 webhook (nginx IP 화이트리스트 + 앱 X-Internal-Key) |
/api/internal/music/ |
music-lab:8000 |
Windows 워커 webhook (IP 화이트리스트 + X-Internal-Key) |
/api/internal/video/ |
video-lab:8000 |
Windows 워커 webhook (IP 화이트리스트 + X-Internal-Key) |
/api/internal/image/ |
image-lab:8000 |
Windows 워커 webhook (IP 화이트리스트 + X-Internal-Key) |
/api/webai/ |
stock:8000 |
Windows AI 서버 프록시 (rate-limited 60r/m) |
/webhook, /webhook/ |
deployer:9000 |
Gitea Webhook |
/ext/feargreed |
CNN API | 공포탐욕지수 외부 프록시 |
/ext/vix, /ext/treasury, /ext/wti, /ext/brent |
Yahoo Finance | 시장 지표 외부 프록시 |
/media/music/ |
/data/music/ (파일 직접 서빙) |
생성된 오디오 파일 (30d cache) |
/media/video/ |
/data/video/ (파일 직접 서빙) |
video-lab 생성 영상 (1d cache). 단수 video |
/media/videos/ |
/data/videos/ (파일 직접 서빙) |
music-lab 뮤직비디오 (1d). 복수 videos |
/media/image/ |
/data/image/ (파일 직접 서빙) |
image-lab 생성 이미지 (1d cache) |
/media/insta/ |
/data/insta_cards/ (파일 직접 서빙) |
카드 PNG (1h cache) |
/media/travel/.thumb/ |
/data/thumbs/ (파일 직접 서빙) |
썸네일 캐시 (30d). nginx miss 시 앱 라우트 폴백 생성 |
/media/travel/ |
/data/travel/ (파일 직접 서빙) |
원본 사진 (7d) |
/assets/ |
정적 파일 (장기 캐시) | Vite 해시 파일 (1y immutable) |
/ |
SPA fallback (try_files → index.html) |
index.html no-cache |
6. 기술 스택
| 레이어 | 기술 |
|---|---|
| Backend 언어 | Python 3.12 |
| API 프레임워크 | FastAPI |
| DB | SQLite (/app/data/*.db) |
| 스케줄러 | APScheduler |
| 컨테이너 | Docker (python:3.12-slim 기반) |
| AI 연동 | Claude API (Anthropic) + Ollama (Llama 3.1, Windows PC 192.168.45.59) |
| 주식 API | KIS (한국투자증권) Open API |
| 생성 워커 | Windows web-ai 레포 (music/video/image/insta 렌더·생성) |
7. 자동 배포 흐름
개발자 git push → Gitea → Webhook (HMAC SHA256 검증)
→ deployer 컨테이너 → scripts/deploy.sh (오케스트레이터)
→ deploy-nas.sh (rsync REPO→RUNTIME) → docker compose up -d --build
- 배포 스크립트 동기화 함정(6개 hardcoded 위치) →
feedback_deploy_script_sync.md메모리 - Webhook 검증·동시배포 락·헬스체크 게이트·
.releases백업 상세 →service_deployer.md메모리 - 머지 후 첫 webhook이 깨지는 패턴 →
feedback_nas_deploy_runtime.md메모리 - 프론트엔드는 자동 배포 안 됨: 로컬 Vite 빌드 후 NAS에 수동 업로드
8. 로컬 개발 환경
# .env 기본값으로 즉시 실행 가능 (RUNTIME_PATH=., PHOTO_PATH=./mock_data/photos)
docker compose up -d
⚠️ Docker는 NAS에서만 구동 — 로컬에서 docker 명령어 실행 금지 (feedback_docker_nas.md).
| 서비스 | 로컬 URL | 서비스 | 로컬 URL | |
|---|---|---|---|---|
| Frontend + API | http://localhost:8080 | Tarot Lab | http://localhost:18250 | |
| Lotto | http://localhost:18000 | Saju Lab | http://localhost:18300 | |
| Stock | http://localhost:18500 | Video Lab | http://localhost:18801 | |
| Music Lab | http://localhost:18600 | Image Lab | http://localhost:18802 | |
| Insta Lab | http://localhost:18700 | Personal | http://localhost:18850 | |
| Realestate Lab | http://localhost:18800 | Agent Office | http://localhost:18900 | |
| Packs Lab | http://localhost:18950 | Travel API | http://localhost:19000 | |
| Redis | redis://localhost:6379 |
9. 서비스별 API 엔드포인트
각 서비스의 DB 스키마·스케줄러·환경변수·운영 함정·최근 작업은 해당 메모리 파일을 읽을 것.
lotto (lotto/)
로또 데이터 수집·분석·추천 + 자율 학습(능동 시그널·가중치 진화·자가학습 백테스트).
- 핵심 파일:
main.py,db.py,recommender.py,collector.py,checker.py,generator.py,analyzer.py,purchase_manager.py,strategy_evolver.py,backtest.py,routers/(curator/briefing/review/backtest) - 📌 상세(DB 15테이블·스케줄러·v1~v3 자율학습):
service_lotto.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/lotto/latest |
최신 당첨번호 |
| GET | /api/lotto/{drw_no} |
특정 회차 |
| GET | /api/lotto/stats |
번호 빈도 통계 |
| GET | /api/lotto/analysis |
5가지 통계 분석 리포트 |
| GET | /api/lotto/best |
시뮬레이션 최적 번호 (기본 20쌍) |
| GET | /api/lotto/simulation |
시뮬레이션 상세 결과 |
| GET | /api/lotto/recommend |
통계 기반 추천 |
| GET | /api/lotto/recommend/heatmap |
히트맵 기반 추천 |
| GET/POST | /api/lotto/recommend/batch |
배치 추천 (조회/저장) |
| GET | /api/lotto/recommend/smart |
전략 진화 기반 메타 추천 |
| GET/POST | /api/lotto/purchase |
구매 이력 조회/등록 |
| PUT/DELETE | /api/lotto/purchase/{id} |
구매 이력 수정/삭제 |
| GET | /api/lotto/purchase/stats |
구매 통계 (전체/실제/가상 + 전략별) |
| GET | /api/lotto/strategy/weights |
전략별 가중치 + 성과 + trend |
| GET | /api/lotto/strategy/performance |
전략별 회차 성과 이력 (차트용) |
| POST | /api/lotto/strategy/evolve |
수동 가중치 재계산 |
| POST | /api/admin/simulate, /api/admin/sync_latest |
시뮬레이션·동기화 수동 실행 |
| GET | /api/history |
추천 이력 (limit, offset, favorite, tag, sort) |
| PATCH/DELETE | /api/history/{id} |
즐겨찾기·메모·태그 수정 / 삭제 |
| GET | /api/lotto/curator/candidates, /curator/context, /curator/usage |
큐레이터 후보·맥락·토큰비용 |
| POST | /api/lotto/briefing |
AI 브리핑 저장 |
| GET | /api/lotto/briefing/latest, /briefing/{draw_no}, /briefing |
브리핑 조회/이력 |
| GET | /api/lotto/evolver/status, /evolver/history, /evolver/trials/{week_start} |
가중치 진화 상태/이력/주별 trial |
| POST | /api/lotto/evolver/generate-now, /evolver/evaluate-now |
진화 수동 트리거 |
| GET | /api/lotto/backtest/track-record |
forward 가상구매 성적 |
| GET | /api/lotto/backtest/calibration |
winner 캘리브레이션 percentile |
| GET | /api/lotto/backtest/review/{draw_no} |
특정 회차 백테스트 리뷰 |
| POST | /api/lotto/backtest/run-forward |
forward 가상구매 수동 실행 |
| POST | /api/lotto/backtest/backfill |
역대 캘리브레이션 백필 (batch, sample_m) |
stock (stock/)
주식 뉴스·AI 분석·KIS 연동 + 보유종목 인텔리전스(advisory 브리핑) + 스크리너.
- 핵심 파일:
main.py,db.py,scraper.py,price_fetcher.py,holdings_intel.py,screener/,holidays.json - Windows AI 서버 연동:
WINDOWS_AI_SERVER_URL=http://192.168.45.59:8000 - 📌 상세(DB 테이블·스케줄러·보유종목 인텔 아키텍처):
service_stock.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/stock/news |
뉴스 조회 (limit, category) |
| GET | /api/stock/indices |
주요 지표 실시간 조회 |
| GET | /api/stock/holidays |
KRX 공휴일 목록 |
| POST | /api/stock/scrap |
수동 뉴스 스크랩 트리거 |
| GET | /api/stock/holdings/intel |
보유종목 advisory (+ /history, /run) |
| GET | /api/trade/balance |
실계좌 잔고 (Windows AI 프록시) |
| POST | /api/trade/order |
주식 주문 (Windows AI 프록시) |
| GET/POST | /api/portfolio |
포트폴리오 조회/추가 |
| PUT/DELETE | /api/portfolio/{id} |
종목 수정/삭제 |
| GET/PUT | /api/portfolio/cash |
예수금 조회/upsert |
| DELETE | /api/portfolio/cash/{broker} |
예수금 삭제 |
| POST | /api/portfolio/snapshot |
총 자산 스냅샷 수동 저장 |
| GET | /api/portfolio/snapshot/history |
스냅샷 이력 (days) |
| GET/POST | /api/portfolio/sell-history |
매도 내역 조회/저장 |
| PUT/DELETE | /api/portfolio/sell-history/{id} |
매도 기록 수정/삭제 |
music-lab (music-lab/)
듀얼 프로바이더 음악 생성(Suno + MusicGen) + YouTube 영상 자동화 파이프라인 + 시장 트렌드.
- ⚠️ NAS는 게이트웨이 — Suno/MusicGen 호출은 Windows
music-render워커가 담당. NAS는queue:music-renderRedis push +/api/internal/music/updatewebhook 수신.suno_provider.py/local_provider.py는 DEPRECATED stub. - 핵심 파일:
main.py,db.py,batch_generator.py,compiler.py,internal_router.py,market.py,pipeline/(orchestrator/cover/video/thumb/metadata/review/youtube/state_machine 등) - 📌 상세(DB 14테이블·env·pipeline state machine·YouTube OAuth):
service_music.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/music/providers, /models, /credits, /genres |
프로바이더·모델·크레딧·장르 |
| POST | /api/music/generate |
음악 생성 (provider/model/vocal 등) |
| GET | /api/music/status/{task_id} |
생성 상태 폴링 |
| POST | /api/music/lyrics, /style-boost |
가사·스타일 프롬프트 생성 |
| GET/POST/DELETE | /api/music/library |
라이브러리 조회/추가/삭제 |
| POST | /api/music/extend, /vocal-removal, /wav, /stem-split, /cover-image |
곡 후처리 |
| POST | /api/music/upload-cover, /upload-extend, /add-vocals, /add-instrumental |
외부 음원 가공 |
| GET | /api/music/timestamped-lyrics |
타임스탬프 가사 |
| GET/POST/PUT/DELETE | /api/music/lyrics/library |
가사 라이브러리 CRUD |
| POST/GET | /api/music/generate-batch |
배치 생성 |
| POST/GET | /api/music/compile (+ /compiles/{id}/export) |
컴파일 |
| POST/GET/DELETE | /api/music/video-project (+ /{id}/render, /export) |
영상 프로젝트 |
| ALL | /api/music/pipeline (생성/start/feedback/cancel/publish/telegram-msg/lookup) |
YouTube 자동화 파이프라인 |
| GET/PUT | /api/music/setup |
파이프라인 설정 |
| GET | /api/music/youtube/auth-url, /callback, /status; POST /disconnect |
YouTube OAuth |
| GET/POST/PUT/DELETE | /api/music/revenue (+ /dashboard) |
수익 기록 |
| POST | /api/music/market/ingest |
트렌드 수신 + 리포트 |
| GET | /api/music/market/trends, /report/latest, /report, /suggest |
트렌드 조회·추천 |
| POST | /api/internal/music/update |
Windows 워커 결과 webhook |
video-lab (video-lab/)
동영상 생성 게이트웨이 (Redis 비동기 큐 queue:video-render). provider: sora/veo/kling/seedance.
- 핵심 파일:
main.py,db.py,internal_router.py,auth.py - 흐름: POST generate → task_id + Redis push → Windows 워커 pop →
/api/internal/video/updatewebhook → DB 업데이트. 출력 mp4/data/video/→ nginx/media/video/(1d) - 📌 상세(
video_tasks스키마·큐 payload·X-Internal-Key):service_video.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/video/generate |
영상 생성 → task_id + Redis push |
| GET | /api/video/tasks/{id} |
생성 상태 폴링 |
| GET | /api/video/providers |
지원 provider 목록 |
| POST | /api/internal/video/update |
Windows 워커 결과 webhook |
image-lab (image-lab/)
이미지 생성 게이트웨이 (Redis 비동기 큐 queue:image-render). provider: gpt_image/nano_banana/flux.
- 핵심 파일:
main.py,db.py,internal_router.py,auth.py - 흐름: video-lab과 동형. 출력 png/jpg
/data/image/→ nginx/media/image/(1d) - 📌 상세(
image_tasks스키마·provider 모델 메타·X-Internal-Key):service_image.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/image/generate |
이미지 생성 → task_id + Redis push |
| GET | /api/image/tasks/{id} |
생성 상태 폴링 |
| GET | /api/image/providers |
지원 provider 목록 |
| POST | /api/internal/image/update |
Windows 워커 결과 webhook |
insta-lab (insta-lab/)
인스타그램 카드 피드 자동 생성 — 뉴스→키워드→10페이지 카드 카피 → 텔레그램 푸시 → 사용자 수동 업로드.
- ⚠️ 렌더는 NAS가 안 함 —
card_renderer.py는 DEPRECATED stub. NAS는queue:insta-renderRedis push만, 실제 Jinja→Playwright 렌더는 Windowsinsta-render워커(web-ai). 워커가GET /slates/{id}fetch → 렌더 →/api/internal/insta/updatewebhook. - 핵심 파일:
app/main.py,config.py,db.py,news_collector.py,keyword_extractor.py,card_writer.py,internal_router.py,trend_collector.py,design_importer.py,templates/<theme>/card.html.j2 - 카드 사이즈 1080×1350 (4:5). 디자인 import는 로컬 Python 실행 필수(NAS docker exec 시 소실 →
feedback_container_ephemeral_artifacts.md) - 📌 상세(DB 스키마·디자인 import·v2 카드뉴스·렌더 아키텍처·미해결 갭):
service_insta.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/insta/status |
서비스 상태 (NAVER/ANTHROPIC 키 여부) |
| POST | /api/insta/news/collect |
뉴스 수집 트리거 |
| GET | /api/insta/news/articles |
수집 기사 목록 |
| POST | /api/insta/keywords/extract |
키워드 추출 트리거 |
| GET | /api/insta/keywords |
트렌딩 키워드 목록 |
| GET/POST | /api/insta/slates |
슬레이트 목록/생성 |
| GET/DELETE | /api/insta/slates/{id} |
슬레이트 상세/삭제 |
| POST | /api/insta/slates/{id}/render |
카드 렌더 재시도 |
| GET | /api/insta/slates/{id}/assets/{page} |
카드 PNG 다운로드 (1~10) |
| GET | /api/insta/slates/{id}/package |
zip 패키지 (10 PNG + caption.txt) |
| GET | /api/insta/keywords/ranked |
4신호 선별 점수 + eligible (자율 발급용) |
| POST | /api/insta/slates/{id}/decision |
승인/반려 (approved→published) |
| GET | /api/insta/tasks/{task_id} |
BackgroundTask 상태 폴링 |
| GET/PUT | /api/insta/templates/prompts/{name} |
프롬프트 템플릿 CRUD |
| POST | /api/internal/insta/update |
Windows 워커 결과 webhook |
realestate-lab (realestate-lab/)
공공데이터포털 청약 분양정보 수집 + 자치구 5티어 매칭 + agent-office push 알림.
- 핵심 파일:
main.py,db.py,collector.py,matcher.py,notifier.py,models.py - 매칭 100점: 지역35 / 주택유형10 / 면적15 / 가격15 / 자격25
- 📌 상세(DB 스키마·스케줄러 4단계·매칭 모델·notifier 멱등 흐름·env):
service_realestate.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET/POST | /api/realestate/announcements |
공고 목록(district/match_score 포함)/수동 등록 |
| GET/PUT/DELETE | /api/realestate/announcements/{id} |
공고 상세/수정/삭제 |
| PATCH | /api/realestate/announcements/{id}/bookmark |
북마크 토글 (텔레그램 콜백 대상) |
| DELETE | /api/realestate/announcements/closed |
완료 공고 일괄 삭제 |
| POST/GET | /api/realestate/collect (+ /collect/status) |
수동 수집(collect→cleanup→match→notify)/상태 |
| GET/PUT | /api/realestate/profile |
프로필 조회/수정 (preferred_districts, min_match_score, notify_enabled) |
| GET | /api/realestate/matches |
매칭 결과 (district/status 포함) |
| POST | /api/realestate/matches/refresh |
매칭 재계산 |
| PATCH | /api/realestate/matches/{id}/read |
신규 알림 읽음 |
| GET | /api/realestate/dashboard |
요약 (진행중·신규매칭·일정) |
agent-office (agent-office/)
AI 에이전트 가상 오피스 — 기존 서비스 API를 프록시로 호출, 실시간 WebSocket + 텔레그램 봇.
- 핵심 파일:
main.py,db.py,config.py,websocket_manager.py,service_proxy.py,telegram_bot.py,scheduler.py,agents/(stock/music/realestate/youtube/youtube_publisher/lotto/base) - 에이전트 7종 레지스트리. 명령 API body 필드명 →
reference_agent_office_command_api.md - 📌 상세(DB 9테이블·FSM·전체 cron 목록·AGENT_CONTAINER_MAP·텔레그램 캐싱·env):
service_agent_office.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| WS | /api/agent-office/ws |
WebSocket (init/agent_state/task_complete/command_result) |
| GET | /api/agent-office/agents (+ /{id}, /{id}/tasks, /{id}/logs) |
에이전트 목록·상세·이력·로그 |
| PUT | /api/agent-office/agents/{id} |
에이전트 설정 수정 |
| GET | /api/agent-office/tasks/pending (+ /{id}) |
승인 대기·작업 상세 |
| POST | /api/agent-office/command |
에이전트 명령 전송 |
| POST | /api/agent-office/approve |
작업 승인/거부 |
| POST | /api/agent-office/telegram/webhook |
텔레그램 Webhook (realestate_bookmark_* 콜백 포함) |
| POST | /api/agent-office/realestate/notify |
realestate-lab 전용 push 수신 → 텔레그램 |
| GET | /api/agent-office/states |
전체 에이전트 상태 |
| GET | /api/agent-office/conversation/stats |
텔레그램 대화 토큰·캐시 통계 (days) |
| POST/GET | /api/agent-office/youtube/research (+ /status) |
YouTube 트렌드 수집 트리거/상태 |
| GET | /api/agent-office/lotto/signals, /lotto/baselines |
로또 시그널 이력·baseline |
| POST | /api/agent-office/lotto/signal-check |
로또 시그널 평가 트리거 (light/sim/deep) |
tarot-lab (tarot-lab/)
타로 카드 해석 (Claude Sonnet, agent-office에서 2026-05-25 독립).
- 핵심 파일:
app/main.py,pipeline.py,prompt.py,schema.py,models.py,config.py,db.py - interpret(해석만, DB 저장 X) ↔ readings(저장) 2단계 분리. nginx 600s
- 📌 상세(
tarot_readings스키마·max_tokens/truncation/reroll·env):service_tarot.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/tarot/interpret |
카드 배치 → AI 해석 (저장 X) |
| POST/GET | /api/tarot/readings |
해석 결과 저장 / 기록 목록 (page, favorite, spread_type, category) |
| GET/PATCH/DELETE | /api/tarot/readings/{id} |
기록 상세 / 즐겨찾기·note 수정 / 삭제 |
saju-lab (saju-lab/)
사주 분석 + 궁합 (Claude Sonnet 4.6 + prompt caching, saju-web TS→Python 포팅).
- 핵심 파일:
main.py,routers/(saju+compat),interpret/(pipeline+prompt+schema),calculator/(core/analysis/daeun/lunar/shinsal/compatibility/fortune_scores/lucky/monthly_flow/solar_terms) - TS 원본 버그도 동등 재현(
feedback_ts_python_reference_fixture.md). DSM timeout 300s+ - 📌 상세(DB 스키마·계산엔진·TS 버그·UI v2 schema 매핑):
service_saju.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/saju/interpret |
사주 계산 + AI 해석 + DB 저장 (fortune_scores/lucky/monthly_flow 포함) |
| GET | /api/saju/readings (+ /{id}) |
사주 기록 목록/상세 |
| PATCH/DELETE | /api/saju/readings/{id} |
즐겨찾기·메모 수정 / 삭제 |
| GET | /api/saju/current-fortune |
저장된 사주의 현재 연도 세운 (실시간 계산) |
| POST | /api/saju/compat/interpret |
두 사람 궁합 계산 + AI 해석 |
| GET | /api/saju/compat/readings (+ /{id}) |
궁합 기록 목록/상세 |
| PATCH/DELETE | /api/saju/compat/readings/{id} |
궁합 즐겨찾기·메모 수정 / 삭제 |
packs-lab (packs-lab/)
NAS 자료 다운로드 자동화 — DSM 공유링크 발급 + 5GB chunked 업로드. Vercel SaaS와 HMAC 통신.
- 핵심 파일:
app/main.py,auth.py,dsm_client.py,routes.py,models.py - 외부 DB: Supabase
pack_files. 경로 3분리(PACK_DATA_PATH→PACK_BASE_DIR→PACK_HOST_DIR) - 📌 상세(HMAC 패턴·chunked contract·운영검증 DSM env·backlog):
service_packs.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/packs/sign-link |
HMAC → DSM 4시간 다운로드 URL 발급 |
| POST | /api/packs/admin/mint-token |
HMAC → 일회성 upload 토큰 (30분 TTL) |
| POST | /api/packs/upload |
Bearer → single-shot 5GB 저장 + Supabase INSERT |
| POST | /api/packs/upload/init |
Bearer → chunked 세션 초기화 (jti consume) |
| PUT | /api/packs/upload/{session_id}/chunk |
부분파일 append (offset 불일치 시 409 + X-Current-Offset) |
| GET | /api/packs/upload/{session_id}/status |
{written, expected_size} (재개용) |
| POST | /api/packs/upload/{session_id}/complete |
rename + Supabase INSERT |
| DELETE | /api/packs/upload/{session_id} |
세션 중단 + 부분파일 정리 |
| GET | /api/packs/list |
HMAC → 활성 pack_files |
| DELETE | /api/packs/{file_id} |
HMAC → soft delete |
personal (personal/)
포트폴리오 + 블로그 + 투두 통합. 편집 인증 Bearer 24h TTL (인메모리).
- 핵심 파일:
main.py,db.py,models.py,auth.py - ⚠️
DELETE /api/todos/done은DELETE /api/todos/{id}보다 반드시 먼저 등록 (FastAPI prefix 매칭) - 📌 상세(DB 7테이블·인증 흐름·라우트 함정):
service_personal.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/profile/public |
공개 데이터 일괄 조회 |
| POST | /api/profile/auth |
비밀번호 인증 → 토큰 |
| GET/PUT | /api/profile/profile |
프로필 조회/수정 (인증) |
| GET/POST/PUT/DELETE | /api/profile/careers, /projects, /skills, /introductions |
각 섹션 CRUD (인증) |
| PATCH | /api/profile/introductions/{id}/main |
메인 자기소개 지정 (인증) |
| GET/POST | /api/todos |
투두 목록/생성 |
| PUT/DELETE | /api/todos/{id} |
투두 수정/삭제 |
| DELETE | /api/todos/done |
완료 항목 일괄 삭제 (라우트 순서 주의) |
| GET/POST/PUT/DELETE | /api/blog/posts (+ /{id}) |
블로그 글 CRUD |
travel-proxy (travel-proxy/)
여행 사진 API + 썸네일(480×480 Pillow) + 지역 관리.
- 핵심 파일:
main.py,db.py,indexer.py. DB/data/thumbs/travel.db - 지역 3중 파일:
region_map.json(RO 원본) +region_map_extra.json(RW 오버라이드:_regions_meta/_removes/미분류) +regions.geojson. PUID/PGID 권한 주입 - 📌 상세(DB 스키마·지역 병합·sync 동작·썸네일 폴백):
service_travel.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/travel/regions |
지역 GeoJSON (커스텀 지역 동적 추가) |
| GET | /api/travel/photos |
사진 목록 (region, page, size) |
| POST | /api/travel/sync |
폴더 스캔 → DB 동기화 + 썸네일 생성 |
| GET | /api/travel/albums |
앨범 목록 + 사진 수 + 커버 + region |
| PUT | /api/travel/albums/{album}/cover |
앨범 커버 지정 |
| PUT | /api/travel/albums/{album}/region |
앨범 지역 변경 |
| PUT | /api/travel/regions/{region_id} |
커스텀 지역 이름/좌표 수정 |
deployer (deployer/)
Gitea Webhook 수신 → 자동 배포. HMAC SHA256 검증(X-Gitea-Signature 또는 X-Hub-Signature-256).
- 즉시
{"ok": true}응답 후 BackgroundTask 배포. 동시 배포 락(threading.Lock + flock). 10분 타임아웃 - 📌 상세(검증 흐름·배포 스크립트 2단 구조·
.releases백업·헬스체크 게이트):service_deployer.md
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /webhook |
Gitea Webhook 수신 → HMAC 검증 → 배포 |
10. 공유 인프라
_shared/access_log.py 공용 모듈
5개 서비스(lotto, stock, music-lab, insta-lab, realestate-lab)가 공유. agent-office의 /agents/{id}/logs가 이를 통해 각 서비스 /logs/recent를 수집·병합.
install(app)단일 진입점 → middleware(요청 계측 + ring buffer maxlen=500) +BufferLogHandler+GET /logs/recent?limit&since&path_prefix- docker-compose:
${RUNTIME_PATH}/_shared:/shared/_shared:ro+PYTHONPATH=/app:/shared - 제외:
/health/docs/logs/recent등 +OPTIONS/HEAD
redis 컨테이너 (6379)
4개 서비스 비동기 큐 공유. 각 서비스가 queue:<svc>-render push → Windows AI 워커 pop → 완료 후 /api/internal/<svc>/update webhook → DB 업데이트.
queue:music-render,queue:video-render,queue:image-render,queue:insta-render
11. 주의사항 (cross-cutting)
.env절대 커밋 금지 (.env.example만 레포 포함)- 커밋 경로: web-ui / web-backend 별도 Git — 각 경로에서만 커밋 (
feedback_commit_repo.md) - Docker는 NAS에서만 구동 (
feedback_docker_nas.md) - Nginx trailing slash:
/api/portfolio는 두 location 블록으로 slash 유무 모두 매칭 - 라우트 순서: personal
DELETE /api/todos/done을/{id}보다 먼저 등록 - DB 마이그레이션: 스키마 변경 시 ALTER TABLE 멱등 패턴 (각 서비스 메모리 참조)
- 공휴일 목록:
stock/app/holidays.json매년 수동 갱신 (KRX 기준) - Windows AI 서버 IP:
192.168.45.59(DHCP 고정 예약). Tailscale은 Synology userspace 모드라 TCP 불가 → 로컬 IP 사용 - 렌더/생성 워커 분리: music/video/image/insta 무거운 작업은 Windows
web-ai워커. NAS 코드의*_provider.py/card_renderer.py가 DEPRECATED stub면 실 로직은 web-ai 쪽이 authoritative - Playwright Dockerfile: bookworm 고정 + 수동 chromium deps,
--with-deps금지 (feedback_playwright_dockerfile.md) - lab 네이밍:
-lab은 개발/연구 단계에만, 정식 서비스엔 미사용 (feedback_lab_naming.md)