No reviewers
Labels
No labels
api
bug
chore
collector
decision-needed
docs
enhancement
feature
feedback-loop
frontend
infra
skill
test
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
xhh/financial-data-platform!64
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-54-streamlit-api-migration"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #54, Closes #55.
요약
Streamlit 레거시 프로토타입 페이지를 API 기반으로 전환하면서 운영 대시보드에 DB 용량 메트릭도 추가. 두 이슈가 자연스럽게 묶임 —
/api/meta/coverage가 양쪽의 데이터 소스.커밋
feat: /api/meta/coverage 응답에 db_size_bytes + 운영 페이지 표시 (#55)CoverageResponse.db_size_bytes(nullable int) 추가meta_coverage가Depends(get_database)로 주입받아 SQLite 파일 용량 계산. in-memory 또는 파일 부재 시 None5_Data_Coverage페이지 상단 메트릭 카드에 'DB 파일 용량' 표시 (KB/MB/GB 자동 단위)refactor: Streamlit 레거시 페이지 API 기반 마이그레이션 (#54)frontend/streamlit/utils/data_loader.py: 함수 시그니처 유지, 내부만 API 호출로 교체. 페이지 본문 코드는 손대지 않음 (위험 최소화)sys.path해킹 제거,ensure_sidebar_controls()호출 추가docker-compose.yml: streamlit 의./data:/app/data:ro볼륨 마운트 제거API 매핑
get_database_stats/get_latest_update_time/api/meta/coverage의 테이블 + 심볼 max_date 집계get_fred_indicators/api/meta/coverage심볼 상세 +/api/indicators/latest최신값get_equity_symbols/api/meta/coverage심볼 상세 +/api/prices/{symbol}1건get_time_series/api/indicators/{symbol}(FRED 우선) →/api/prices/{symbol}get_sector_etfs/get_market_indices/api/meta/coverage의 max_date +/api/prices/{symbol}정밀 1건/api/prices는 asc 정렬만 지원해 "최신 1건"을 직접 못 받기 때문에, coverage 의max_date로 좌표를 잡고start_date=end_date=max_date로 정밀 조회하는 패턴 사용.효과
ssh + ls -lh data/안 해도 DB 용량을 대시보드에서 즉시 확인테스트
uv run pytest: 113 passed (기존 111 + 신규 2)uv run ruff check: cleanTest plan
5_Data_Coverage상단 'DB 파일 용량' 표시 확인./data:볼륨 없이 정상 렌더링 확인app.py사이드바의 통계 (전체 심볼/레코드/기간) 가 prod DB 와 일치하는지 확인알려진 한계
get_market_indices/get_sector_etfs가 심볼당 2회 호출 (coverage 1회는 모듈 내 캐싱 없음, 가격 1회). Streamlit 캐싱 도입은 후속 이슈로 분리./api/prices의 desc 정렬 지원이 있으면 일부 패턴이 더 깔끔해질 것 — 별도 이슈 검토.- CoverageResponse 에 db_size_bytes (nullable int) 필드 추가 - meta_coverage 라우터가 Database dependency 를 주입받아 SQLite 파일 용량을 계산. in-memory(":memory:") 또는 파일 부재 시 None - 5_Data_Coverage 페이지 상단 메트릭 카드에 'DB 파일 용량' 표시 (humanize 보조 함수: KB/MB/GB 자동 단위) 회귀 테스트 2건: - in-memory 엔진 → db_size_bytes None - 파일 기반 엔진 → 양의 정수 이전엔 컨테이너 ssh 들어가 'ls -lh data/' 해야 알 수 있던 정보를 운영 대시보드에서 한눈에 확인 가능. Closes #55 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>레거시 프로토타입 페이지 (Market_Coverage / Sector_Flows / Indicator_Detail) 와 app.py 사이드바가 SQLite 파일을 직접 읽어 컨테이너에 read-only 볼륨을 공유하던 구조를 제거. 변경: - frontend/streamlit/utils/data_loader.py: 모든 함수의 시그니처는 유지하되 내부를 utils.api.get 호출로 교체. 페이지 본문 코드는 손대지 않음 (위험 최소화). * get_database_stats / get_latest_update_time → /api/meta/coverage * get_fred_indicators → /api/meta/coverage + /api/indicators/latest * get_equity_symbols → /api/meta/coverage + /api/prices/{symbol} * get_time_series → /api/indicators/{symbol} 또는 /api/prices/{symbol} * get_sector_etfs / get_market_indices → /api/meta/coverage 의 max_date + /api/prices/{symbol} 정밀 조회 - frontend/streamlit/app.py + 1/2/3 페이지: sys.path 해킹 제거, ensure_sidebar_controls 호출 추가 (API URL/Key 입력 일관성) - docker-compose.yml: streamlit 서비스의 './data:/app/data:ro' 마운트 제거. 데이터 접근은 전부 API_URL 의 FastAPI 경유. 이점: - Streamlit 컨테이너에 SQLite 파일이 없어도 정상 동작 — 공격면 하나 줄어듦 (외부 노출 시 DB 파일 직접 접근 불가) - 스키마 변경 시 API/프론트 두 쪽을 동시에 고칠 필요 없음 - 새 운영 페이지(#22, #46) 와 같은 패턴으로 수렴 Closes #54 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>