Files
web-page-backend/CLAUDE.md
gahusb ce6c8d8f7d docs(CLAUDE): 카탈로그 슬림화(966→484) + 서비스별 메모리 분담 + stale 수정
포트/nginx/API 엔드포인트 목록·cross-cutting 규칙만 CLAUDE.md에 유지. DB 스키마 세부·스케줄러·env·운영 히스토리는 service_<name>.md 메모리로 이관(§0 규칙 명시).

코드 대조로 발견한 stale 수정: insta 렌더는 Windows 워커(card_renderer.py DEPRECATED), lotto v3 backtest API 추가, music-lab 워커 위임, internal webhook X-Internal-Key 2중, /media video↔videos 구분 등.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 01:48:15 +09:00

31 KiB
Raw Blame History

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-render Redis push + /api/internal/music/update webhook 수신. 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/update webhook → 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-render Redis push만, 실제 Jinja→Playwright 렌더는 Windows insta-render 워커(web-ai). 워커가 GET /slates/{id} fetch → 렌더 → /api/internal/insta/update webhook.
  • 핵심 파일: 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/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_PATHPACK_BASE_DIRPACK_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/doneDELETE /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)