Files
web-page-backend/CLAUDE.md

26 KiB
Raw Blame History

CLAUDE.md — web-backend 프로젝트 가이드

Claude Code가 이 프로젝트를 작업할 때 참조하는 설정 및 구조 문서.


1. 프로젝트 개요

Synology NAS 기반의 개인 웹 플랫폼 백엔드 모노레포.

  • 서비스: lotto-lab, stock-lab, travel-album, music-lab, blog-lab, realestate-lab, deployer
  • 프론트엔드: 별도 레포 (React + Vite SPA), 빌드 산출물만 NAS에 배포
  • 인프라: Docker Compose + 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:8000) — NVIDIA 3070 Ti + Ollama

3. NAS 디렉토리 구조

/volume1
├── docker/webpage/          # 운영 런타임 (Docker Compose 실행 위치)
│   ├── backend/             # lotto-backend 소스 (rsync 동기화)
│   ├── stock-lab/           # stock-lab 소스 (rsync 동기화)
│   ├── travel-proxy/        # travel-proxy 소스 (rsync 동기화)
│   ├── deployer/            # deployer 소스 (rsync 동기화)
│   ├── nginx/default.conf   # Nginx 설정
│   ├── scripts/deploy.sh    # Webhook 트리거 배포 스크립트
│   ├── docker-compose.yml
│   ├── .env                 # 운영 환경변수
│   ├── data/lotto.db        # SQLite DB
│   └── data/music/          # 생성된 오디오 파일 (music-lab)
│
├── workspace/web-page-backend/  # Git 레포 클론 위치 (REPO_PATH)
│
└── web/images/webPage/travel/   # 원본 여행 사진 (RO 마운트)

4. Docker 서비스 & 포트

컨테이너 포트 역할
lotto-backend 18000 로또 데이터 수집·분석·추천 API
stock-lab 18500 주식 뉴스·AI 분석·KIS API 연동
music-lab 18600 AI 음악 생성·라이브러리 관리 API
blog-lab 18700 블로그 마케팅 수익화 API
realestate-lab 18800 부동산 청약 자동 수집·매칭 API
agent-office 18900 AI 에이전트 오피스 (실시간 WebSocket + 텔레그램 연동)
travel-proxy 19000 여행 사진 API + 썸네일 생성
lotto-frontend (nginx) 8080 정적 SPA 서빙 + API 리버스 프록시
webpage-deployer 19010 Gitea Webhook 수신 → 자동 배포

5. Nginx 라우팅 규칙

경로 프록시 대상 비고
/api/ lotto-backend:8000 lotto API (기본)
/api/travel/ travel-proxy:8000 travel API
/api/stock/ stock-lab:8000 stock API
/api/trade/ stock-lab:8000 KIS 실계좌 API
/api/portfolio stock-lab:8000 trailing slash 유무 모두 매칭
/api/music/ music-lab:8000 AI 음악 생성·라이브러리 API
/api/blog-marketing/ blog-lab:8000 블로그 마케팅 수익화 API
/api/realestate/ realestate-lab:8000 부동산 청약 API
/api/agent-office/ agent-office:8000 AI 에이전트 오피스 API + WebSocket
/webhook, /webhook/ deployer:9000 Gitea Webhook
/media/music/ /data/music/ (파일 직접 서빙) 생성된 오디오 파일
/media/travel/.thumb/ /data/thumbs/ (파일 직접 서빙) 썸네일 캐시
/media/travel/ /data/travel/ (파일 직접 서빙) 원본 사진
/assets/ 정적 파일 (장기 캐시) Vite 해시 파일
/ SPA fallback (try_files → index.html)

6. 기술 스택

레이어 기술
Backend 언어 Python 3.12
API 프레임워크 FastAPI
DB SQLite (/app/data/*.db)
스케줄러 APScheduler
컨테이너 Docker (python:3.12-slim 기반)
AI 연동 Ollama (Llama 3.1) — Windows PC (192.168.45.59)
주식 API KIS (한국투자증권) Open API

7. 자동 배포 흐름

개발자 git push → Gitea → Webhook (HMAC SHA256 검증)
  → deployer 컨테이너 → /scripts/deploy.sh
  → rsync(REPO→RUNTIME) → docker compose up -d --build
  • 배포 스크립트 위치: scripts/deploy-nas.sh (레포) / scripts/deploy.sh (런타임)
  • 환경변수 파일: .env (RUNTIME_PATH, REPO_PATH, PHOTO_PATH, PUID, PGID 등)
  • 백업: .releases/ 디렉토리에 자동 백업

8. 로컬 개발 환경

# .env 기본값으로 즉시 실행 가능 (RUNTIME_PATH=., PHOTO_PATH=./mock_data/photos)
docker compose up -d
서비스 로컬 URL
Frontend + API http://localhost:8080
Lotto Backend http://localhost:18000
Travel API http://localhost:19000
Stock Lab http://localhost:18500
Blog Lab http://localhost:18700
Realestate Lab http://localhost:18800

9. 서비스별 핵심 정보

lotto-lab (backend/)

  • DB: /app/data/lotto.db
  • 데이터 소스: smok95.github.io/lotto/results/
  • 파일 구조: main.py, db.py, recommender.py, collector.py, checker.py, generator.py, analyzer.py, utils.py, purchase_manager.py, strategy_evolver.py

lotto.db 테이블

테이블 설명
draws 로또 당첨번호
recommendations 추천 이력 (즐겨찾기·태그·채점 포함)
simulation_runs 시뮬레이션 실행 기록
simulation_candidates 시뮬레이션 후보 (점수 5종)
best_picks 현재 활성 최적 번호 20개 (is_active 플래그로 교체)
purchase_history 구매 이력 (실제/가상, 번호, 전략 출처, 결과)
strategy_performance 전략별 회차 성과 (EMA 입력 데이터)
strategy_weights 메타 전략 가중치 (EMA + Softmax)
weekly_reports 주간 공략 리포트 캐시
lotto_briefings AI 큐레이터 주간 브리핑 (5세트 + 내러티브 + 토큰·비용 집계)
todos 투두리스트 (UUID PK)
blog_posts 블로그 글 (tags: JSON 배열)

스케줄러 job

  • 09:10 / 21:10 매일 — 당첨번호 동기화 + 채점 (sync_latestcheck_results_for_draw)
  • 00:05, 04:05, 08:05, 12:05, 16:05, 20:05 — 몬테카를로 시뮬레이션 (20,000후보 → 상위100 → best_picks 20개 교체)

lotto-lab API 목록

메서드 경로 설명
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 /api/lotto/recommend/batch 배치 추천
POST /api/lotto/recommend/batch 배치 추천 저장
GET /api/lotto/recommend/smart 전략 진화 기반 메타 추천
GET /api/lotto/purchase 구매 이력 조회 (is_real, strategy, draw_no, days 필터)
POST /api/lotto/purchase 구매 등록 (실제/가상, 번호, 전략 출처 포함)
PUT /api/lotto/purchase/{id} 구매 이력 수정
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 시뮬레이션 수동 실행
POST /api/admin/sync_latest 당첨번호 수동 동기화
GET /api/history 추천 이력 (limit, offset, favorite, tag, sort)
PATCH /api/history/{id} 즐겨찾기·메모·태그 수정
DELETE /api/history/{id} 삭제
GET /api/todos 투두 전체 목록
POST /api/todos 투두 생성 (status: todo|in_progress|done)
PUT /api/todos/{id} 투두 수정
DELETE /api/todos/done 완료 항목 일괄 삭제
DELETE /api/todos/{id} 투두 개별 삭제
GET /api/blog/posts 블로그 글 목록 ({"posts": [...]}, date DESC)
POST /api/blog/posts 블로그 글 생성 (date 미입력 시 오늘)
PUT /api/blog/posts/{id} 블로그 글 수정
DELETE /api/blog/posts/{id} 블로그 글 삭제
GET /api/lotto/curator/candidates 큐레이터용 후보 N세트 + 피처
GET /api/lotto/curator/context 주간 맥락(핫/콜드·직전 회차)
GET /api/lotto/curator/usage 큐레이터 토큰·비용 집계
POST /api/lotto/briefing AI 브리핑 저장
GET /api/lotto/briefing/latest 최신 브리핑
GET /api/lotto/briefing/{draw_no} 특정 회차 브리핑
GET /api/lotto/briefing 브리핑 이력

stock-lab (stock-lab/)

  • Windows AI 서버 연동: WINDOWS_AI_SERVER_URL=http://192.168.45.59:8000
  • KIS API 연동으로 실계좌 잔고·거래 조회
  • 뉴스 스크래핑: 네이버 증권 + 해외 사이트
  • DB: /app/data/stock.db (articles, portfolio, broker_cash, asset_snapshots, sell_history 테이블)
  • 파일 구조: main.py, db.py, scraper.py, price_fetcher.py, holidays.json

stock-lab API 목록

메서드 경로 설명
GET /api/stock/news 뉴스 조회 (limit, category 파라미터)
GET /api/stock/indices 주요 지표 실시간 조회
POST /api/stock/scrap 수동 뉴스 스크랩 트리거
GET /api/trade/balance 실계좌 잔고 조회 (Windows AI 서버 프록시)
POST /api/trade/order 주식 주문 (Windows AI 서버 프록시)
GET /api/portfolio 포트폴리오 전체 조회 (현재가·손익·예수금 포함)
POST /api/portfolio 종목 추가
PUT /api/portfolio/{id} 종목 수정
DELETE /api/portfolio/{id} 종목 삭제
GET /api/portfolio/cash 예수금 전체 조회
PUT /api/portfolio/cash 예수금 등록·수정 (upsert)
DELETE /api/portfolio/cash/{broker} 예수금 삭제
POST /api/portfolio/snapshot 총 자산 스냅샷 수동 저장
GET /api/portfolio/snapshot/history 스냅샷 이력 조회 (days=0: 전체, days=N: 최근 N건)
GET /api/portfolio/sell-history 매도 내역 조회 (broker, days 필터 선택)
POST /api/portfolio/sell-history 매도 기록 저장 (id 포함 레코드 반환)
PUT /api/portfolio/sell-history/{id} 매도 기록 수정 (수정된 레코드 반환)
DELETE /api/portfolio/sell-history/{id} 매도 기록 삭제

매도 히스토리 (sell_history)

  • 독립 테이블 — portfolio 테이블과 별개로 관리
  • sold_at: UTC ISO8601 형식 (new Date().toISOString())
  • realized_profit / realized_rate: 프론트 계산값 저장 (백엔드 재계산 무방)
  • 응답 정렬: sold_at DESC (최신순)

총 자산 스냅샷 (asset_snapshots)

  • 평일 15:40 APScheduler 자동 실행 (save_daily_snapshot)
  • 공휴일 판별: holidays.json (매년 수동 갱신, KRX 기준) → is_market_open() 함수
  • 같은 날 중복 저장 시 upsert (date UNIQUE 제약)
  • 수동 저장: POST /api/portfolio/snapshot
  • 이력 조회: GET /api/portfolio/snapshot/history?days=30 (ASC 정렬, 차트용)

스케줄러 job

  • 08:00 매일 — 뉴스 스크랩 (run_scraping_job)
  • 15:40 평일 — 총 자산 스냅샷 저장 (save_daily_snapshot)

music-lab (music-lab/)

  • 듀얼 프로바이더 음악 생성 서비스 (Suno API + 로컬 MusicGen)
  • 생성된 오디오 파일: /app/data/music/ (Nginx가 /media/music/로 직접 서빙)
  • DB: /app/data/music.db (music_tasks, music_library 테이블)
  • 파일 구조: main.py, db.py, suno_provider.py, local_provider.py
  • 생성 흐름: POST generate (provider 지정) → task_id 반환 → BackgroundTask → 파일 저장 → 라이브러리 자동 등록

Provider 구조

  • suno: Suno REST API (apicast.suno.ai/v1) — 보컬·가사·인스트루멘탈 지원
  • local: Windows AI 서버 (MusicGen) — 인스트루멘탈 전용

music-lab API 목록

메서드 경로 설명
GET /api/music/providers 사용 가능한 프로바이더 목록
GET /api/music/models Suno 모델 목록 (V4~V5.5)
GET /api/music/credits Suno 크레딧 조회
POST /api/music/generate 음악 생성 (provider, model, vocal_gender, negative_tags, style_weight, audio_weight)
GET /api/music/status/{task_id} 생성 상태 폴링
POST /api/music/lyrics Suno AI 가사 생성
GET /api/music/library 라이브러리 전체 조회
POST /api/music/library 트랙 수동 추가
DELETE /api/music/library/{id} 트랙 삭제
POST /api/music/extend 곡 연장
POST /api/music/vocal-removal 보컬/인스트 분리 (2트랙)
POST /api/music/cover-image 커버 이미지 2장 생성
POST /api/music/wav WAV 고음질 변환
POST /api/music/stem-split 12스템 분리 (50cr)
GET /api/music/timestamped-lyrics 타임스탬프 가사 (가라오케)
POST /api/music/style-boost AI 스타일 프롬프트 생성
POST /api/music/upload-cover 외부 음원 AI Cover
POST /api/music/upload-extend 외부 음원 확장
POST /api/music/add-vocals 인스트에 AI 보컬 추가
POST /api/music/add-instrumental 보컬에 AI 반주 추가
POST /api/music/video 뮤직비디오 MP4 생성
GET /api/music/lyrics/library 저장된 가사 목록
POST /api/music/lyrics/library 가사 저장
PUT /api/music/lyrics/library/{id} 가사 수정
DELETE /api/music/lyrics/library/{id} 가사 삭제

환경변수

  • SUNO_API_KEY: Suno API 키 (미설정 시 Suno provider 비활성화)
  • MUSIC_AI_SERVER_URL: 로컬 MusicGen 서버 URL (미설정 시 local provider 비활성화)
  • MUSIC_MEDIA_BASE: 오디오 파일 공개 URL prefix (기본 /media/music)
  • MUSIC_DATA_PATH: NAS 오디오 파일 저장 경로 (기본 ./data/music)

music_library 테이블 (확장 컬럼)

  • provider: suno | local — 생성에 사용된 프로바이더
  • lyrics: Suno 생성 가사 텍스트
  • image_url: Suno 생성 커버 이미지 URL
  • suno_id: Suno 곡 ID (CDN 참조용)
  • file_hash: MD5 해시 (rename 감지용)
  • cover_images: JSON 배열 — 커버 이미지 URL 목록
  • wav_url: WAV 변환 URL
  • video_url: 뮤직비디오 URL
  • stem_urls: JSON 객체 — 12스템 URL 맵

Suno 생성 특이사항

  • 1회 생성 시 2개 변형(variation) 반환 → 둘 다 라이브러리에 저장
  • CDN URL(cdn1.suno.ai)은 임시 → 반드시 로컬 다운로드 필요
  • 가사 섹션 태그: [Verse], [Chorus], [Bridge], [Instrumental]

realestate-lab (realestate-lab/)

  • 공공데이터포털 API 연동: 한국부동산원 청약홈 분양정보 조회 서비스
  • DB: /app/data/realestate.db (announcements, announcement_models, user_profile, match_results, collect_log 테이블)
  • 파일 구조: main.py, db.py, collector.py, matcher.py, models.py

환경변수

  • DATA_GO_KR_API_KEY: 공공데이터포털 API 키 (미설정 시 수동 등록만 가능)

스케줄러 job

  • 09:00 매일 — 청약 공고 수집 + 매칭 (scheduled_collect)
  • 00:00 매일 — 상태 갱신 + 재매칭 (scheduled_status_update)

realestate-lab API 목록

메서드 경로 설명
GET /api/realestate/announcements 공고 목록 (region, status, house_type, matched_only, sort, page, size)
GET /api/realestate/announcements/{id} 공고 상세 (주택형별 포함)
POST /api/realestate/announcements 수동 공고 등록
PUT /api/realestate/announcements/{id} 공고 수정
DELETE /api/realestate/announcements/{id} 공고 삭제
POST /api/realestate/collect 수동 수집 트리거
GET /api/realestate/collect/status 마지막 수집 결과
GET /api/realestate/profile 내 프로필 조회
PUT /api/realestate/profile 프로필 수정 (upsert)
GET /api/realestate/matches 매칭 결과 목록
POST /api/realestate/matches/refresh 매칭 재계산
PATCH /api/realestate/matches/{id}/read 신규 알림 읽음 처리
GET /api/realestate/dashboard 요약 (진행중 공고수, 신규 매칭수, 다가오는 일정)

travel-proxy (travel-proxy/)

  • 원본 사진: /data/travel/ (RO)
  • 썸네일 캐시: /data/thumbs/ (RW)
  • DB: /data/thumbs/travel.db (photos, album_covers 테이블)
  • 메타: /data/travel/_meta/region_map.json, regions.geojson
  • 파일 구조: main.py, db.py, indexer.py
  • 썸네일: 480×480 리사이징 (Pillow), 동기화 시 사전 생성 + 온디맨드 폴백
  • 데이터 흐름: 수동 sync → 폴더 스캔 → SQLite 인덱싱 + 썸네일 일괄 생성

travel.db 테이블

테이블 설명
photos 사진 인덱스 (album, filename, mtime, has_thumb)
album_covers 앨범별 커버 사진 지정

travel-proxy API 목록

메서드 경로 설명
GET /api/travel/regions 지역 GeoJSON
GET /api/travel/photos 사진 목록 (region, page=1, size=20)
POST /api/travel/sync 폴더 스캔 → DB 동기화 + 썸네일 생성
GET /api/travel/albums 앨범 목록 + 사진 수 + 커버 정보
PUT /api/travel/albums/{album}/cover 앨범 커버 지정

blog-lab (blog-lab/)

  • 블로그 마케팅 수익화 서비스 (키워드 분석 → AI 글 생성 → 마케팅 강화 → 품질 리뷰 → 포스팅 → 수익 추적)
  • AI 엔진: Claude API (Anthropic, claude-sonnet-4-20250514)
  • 웹 검색: Naver Search API (블로그 + 쇼핑) + 상위 블로그 본문 크롤링
  • DB: /app/data/blog_marketing.db
  • 파일 구조: main.py, db.py, config.py, naver_search.py, content_generator.py, marketer.py, quality_reviewer.py, web_crawler.py

파이프라인: 리서치(+크롤링) → 작가(초안) → 마케터(링크 삽입) → 평가자(6기준 60점) 상태 흐름: draftmarketedreviewedpublished

blog_marketing.db 테이블

테이블 설명
keyword_analyses 키워드 분석 결과 (네이버 검색 데이터 + 경쟁도/기회 점수 + 크롤링 본문)
blog_posts 블로그 글 (draft → marketed → reviewed → published)
brand_links 브랜드커넥트 제휴 링크 (post_id/keyword_id FK)
commissions 포스트별 월간 클릭/구매/수익
generation_tasks 비동기 작업 상태 (research/generate/market/review)
prompt_templates AI 프롬프트 템플릿 (DB 저장, 코드 배포 없이 수정 가능)

blog-lab API 목록

메서드 경로 설명
GET /api/blog-marketing/status 서비스 상태 (API 키 설정 현황)
POST /api/blog-marketing/research 키워드 분석 시작 (+ 상위 블로그 크롤링)
GET /api/blog-marketing/research/history 분석 이력 조회
GET /api/blog-marketing/research/{id} 분석 상세 조회
DELETE /api/blog-marketing/research/{id} 분석 삭제
GET /api/blog-marketing/task/{task_id} 작업 상태 폴링
POST /api/blog-marketing/generate 작가 단계: AI 글 생성 (크롤링 참고 + 링크 반영)
POST /api/blog-marketing/market/{post_id} 마케터 단계: 전환율 강화 + 링크 삽입
POST /api/blog-marketing/review/{post_id} 평가자 단계: 품질 리뷰 (6기준 × 10점, 42/60 통과)
POST /api/blog-marketing/regenerate/{post_id} 피드백 기반 재생성
POST /api/blog-marketing/links 브랜드커넥트 링크 등록
GET /api/blog-marketing/links 링크 조회 (post_id, keyword_id 필터)
PUT /api/blog-marketing/links/{id} 링크 수정
DELETE /api/blog-marketing/links/{id} 링크 삭제
GET /api/blog-marketing/posts 포스트 목록 (status 필터)
GET /api/blog-marketing/posts/{id} 포스트 상세
PUT /api/blog-marketing/posts/{id} 포스트 수정
DELETE /api/blog-marketing/posts/{id} 포스트 삭제
POST /api/blog-marketing/posts/{id}/publish 발행 (네이버 URL 등록)
GET /api/blog-marketing/commissions 수익 내역 조회
POST /api/blog-marketing/commissions 수익 기록 추가
PUT /api/blog-marketing/commissions/{id} 수익 기록 수정
DELETE /api/blog-marketing/commissions/{id} 수익 기록 삭제
GET /api/blog-marketing/dashboard 대시보드 집계

환경변수

  • ANTHROPIC_API_KEY: Claude API 키 (미설정 시 AI 생성 비활성화)
  • NAVER_CLIENT_ID: 네이버 검색 API 클라이언트 ID
  • NAVER_CLIENT_SECRET: 네이버 검색 API 시크릿
  • BLOG_DATA_PATH: SQLite DB 저장 경로 (기본 ./data/blog)

agent-office (agent-office/)

  • AI 에이전트 가상 오피스 — 2D 픽셀아트 사무실에서 에이전트가 실제 작업 수행
  • stock-lab/music-lab 기존 API를 서비스 프록시로 호출 (직접 DB 접근 없음)
  • 실시간 상태 동기화: WebSocket (/api/agent-office/ws)
  • 텔레그램 봇: 양방향 알림 + 승인 (인라인 키보드)
  • DB: /app/data/agent_office.db (agent_config, agent_tasks, agent_logs, telegram_state 테이블)
  • 파일 구조: main.py, db.py, config.py, models.py, websocket_manager.py, service_proxy.py, telegram_bot.py, scheduler.py, agents/base.py, agents/stock.py, agents/music.py

에이전트 FSM 상태: idle → working → waiting (승인 대기) → reporting → break (휴식)

환경변수

  • STOCK_LAB_URL: stock-lab 내부 URL (기본 http://stock-lab:8000)
  • MUSIC_LAB_URL: music-lab 내부 URL (기본 http://music-lab:8000)
  • TELEGRAM_BOT_TOKEN: 텔레그램 봇 토큰 (미설정 시 알림 비활성화)
  • TELEGRAM_CHAT_ID: 텔레그램 채팅 ID
  • TELEGRAM_WEBHOOK_URL: 텔레그램 Webhook URL
  • TELEGRAM_WIFE_CHAT_ID: 아내 chat.id (브리핑 공유 + 대화 허용)
  • ANTHROPIC_API_KEY: 자연어 대화용 Claude API 키 (미설정 시 대화 비활성)
  • CONVERSATION_MODEL: 대화 모델 (기본 claude-haiku-4-5-20251001)
  • CONVERSATION_HISTORY_LIMIT: 이력 주입 수 (기본 20)
  • CONVERSATION_RATE_PER_MIN: 채팅당 분당 최대 메시지 (기본 6)
  • LOTTO_BACKEND_URL: 기본 http://lotto-backend:8000
  • LOTTO_CURATOR_MODEL: 기본 claude-sonnet-4-5

텔레그램 자연어 대화 (옵션 B)

  • 슬래시 명령이 아닌 일반 문장을 보내면 Claude Haiku 4.5가 응답
  • 프롬프트 캐싱: system 블록 + 히스토리 마지막 블록에 cache_control: ephemeral → 5분 TTL
  • 허용 chat_id 화이트리스트: TELEGRAM_CHAT_ID, TELEGRAM_WIFE_CHAT_ID
  • 평가 지표: conversation_messages 테이블에 tokens / cache_read / cache_write / latency 기록
  • 조회: GET /api/agent-office/conversation/stats?days=7

스케줄러 job

  • 07:30 매일 — 주식 뉴스 요약 (stock_news_job)
  • 매주 월요일 07:00 — 로또 큐레이터 브리핑 (lotto_curate)
  • 60초 간격 — 유휴 에이전트 휴식 체크 (idle_check_job)

agent-office API 목록

메서드 경로 설명
WS /api/agent-office/ws WebSocket (init, agent_state, task_complete, command_result)
GET /api/agent-office/agents 에이전트 목록
GET /api/agent-office/agents/{id} 에이전트 상세 (설정 + 상태)
PUT /api/agent-office/agents/{id} 에이전트 설정 수정
GET /api/agent-office/agents/{id}/tasks 에이전트 작업 이력
GET /api/agent-office/agents/{id}/logs 에이전트 로그
GET /api/agent-office/tasks/pending 승인 대기 작업 목록
GET /api/agent-office/tasks/{id} 작업 상세
POST /api/agent-office/command 에이전트에 명령 전송
POST /api/agent-office/approve 작업 승인/거부
POST /api/agent-office/telegram/webhook 텔레그램 Webhook 수신
GET /api/agent-office/states 전체 에이전트 상태 조회
GET /api/agent-office/conversation/stats 텔레그램 자연어 대화 토큰·캐시 통계 (days 필터)

deployer (deployer/)

  • Webhook 검증: X-Gitea-Signature (HMAC SHA256, compare_digest 사용)
  • WEBHOOK_SECRET 환경변수로 시크릿 관리
  • Webhook 수신 즉시 {"ok": True} 응답 후 BackgroundTask로 배포 실행
  • 배포 타임아웃: 10분 (scripts/deploy.sh)

10. 주의사항

  • Nginx trailing slash: /api/portfolio는 trailing slash 없이도 매칭되도록 두 location 블록으로 처리
  • 라우트 순서: DELETE /api/todos/doneDELETE /api/todos/{id} 보다 반드시 먼저 등록 (FastAPI prefix 매칭 순서)
  • PUID/PGID: travel-proxy는 NAS 파일 권한을 위해 PUID/PGID를 환경변수로 주입
  • 캐시 전략: index.htmlno-store, assets/는 1년 장기 캐시(immutable)
  • Frontend 배포: git push로 자동 배포되지 않음. 로컬 빌드 후 NAS에 수동 업로드
  • .env 파일: 절대 커밋 금지. .env.example만 레포에 포함
  • 공휴일 목록: stock-lab/app/holidays.json 매년 수동 갱신 필요 (KRX 기준)
  • Windows AI 서버 IP: 192.168.45.59 — 공유기 DHCP 고정 예약으로 고정. Tailscale은 Synology에서 TCP 불가(userspace 모드)라 로컬 IP 사용
  • 현재가 조회: 네이버 모바일 API → HTML 파싱 폴백, 3분 TTL 캐시 (price_fetcher.py)
  • 시뮬레이션 교체 방식: best_picks는 교체형 — 새 시뮬레이션 실행 시 is_active=0으로 비활성화 후 신규 입력