feat: /api/reports POST/GET/PATCH + 종목별 이력 + 테스트 (#2) #25
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!25
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-2-reports-api"
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?
요약
통합 로드맵 Phase 2 의 핵심 — Share Note 대신 DB 에 리포트를 저장/조회.
엔드포인트
DELETE 는 두지 않음 (감사 기록 보존).
Pydantic v2.13 해결
type필드명이 내장type과 shadow 되어 에러.Annotated[Literal[...], Field()]로 감싸 해결.테스트 (11 case)
TDD 관례대로
test_post_then_get_persists를 첫 번째로 배치. Summary vs Detail 구분, stock 타입 422 검증, 필터 4종, PATCH persist 포함.로컬
uv run pytest→ 24 passed (smoke 3 + watchlist 10 + reports 11).Closes #2
통합 로드맵 Phase 2 의 핵심 — Share Note 대신 이 플랫폼 DB 에 리포트를 저장하고 조회. 스킬이 write 스코프로 POST, 뷰어/운영자가 read 스코프로 조회. ## 엔드포인트 (5개) - GET /api/reports — 목록 (type/ticker/published_only/include_backtest/limit 필터) - GET /api/reports/ticker/{ticker} — 종목별 이력 (stock 리포트) - GET /api/reports/{id} — 단건 상세 (본문 포함) - POST /api/reports — 저장 (write) - PATCH /api/reports/{id} — 수정 (write) — published 토글, verdict 보정, token_cost 후기록 삭제 엔드포인트는 두지 않음. 리포트는 감사 기록으로 보존. ## 스키마 설계 - ReportCreate: POST 바디. type 필수, stock 타입은 ticker 없으면 422. - ReportUpdate: 전 필드 선택. 식별 필드(type/date/ticker) 는 수정 불가. - ReportSummary: 목록/이력용 — content_md/html 제외로 페이로드 경량화 - ReportDetail: 상세용 — 본문 포함 (ReportSummary 상속) ## Pydantic v2.13 workaround `type` 이라는 필드명이 Python 내장 `type` 과 shadow 되어 "field name clashing with type annotation" 에러 발생. `Annotated[Literal[...], Field()]` 로 감싸 해결. `date` 도 같은 이유로 `from datetime import date as Date`. ## 테스트 (11 case, TDD 관례) tests/api/test_reports.py: - test_post_then_get_persists: deps.get_session 회귀 테스트 (첫 번째 배치) - test_list_omits_content_body / test_detail_includes_content: Summary vs Detail 구분 - test_stock_requires_ticker: 422 검증 - test_ticker_history_filters_by_ticker - test_type_filter / test_backtest_excluded_by_default / test_published_only_filter - test_patch_updates_verdict_and_published - test_missing_id_returns_404 로컬 uv run pytest -> 24 passed (smoke 3 + watchlist 10 + reports 11). Closes #2 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>