feat(REQ-005): implement TrEx Basic V1 API contract with auth, assets, ledger, and user endpoints

- Add V1 API routes for assets, ledger, and user info with complete CRUD operations
- Implement authentication scopes and request validation via auth_routes.py
- Extend schemas with V1-specific models for accounts, holdings, and positions
- Add database queries and aggregations for P&L, performance, and account data
- Include comprehensive test coverage for all V1 endpoints and integration flows
- Update batch and release documentation with implementation and verification evidence
- Sync project structure and runtime flows per V1 API contract requirements

Closes implementation phase of BAT-001 (TrEx Basic V1 API Contract)
This commit is contained in:
2026-05-02 11:37:42 +00:00
parent ce63c75c9c
commit 3509606c7e
17 changed files with 1159 additions and 124 deletions
@@ -59,16 +59,52 @@ design.md에서 확정된 결정 사항을 기반으로 아래 범위를 구현
11. [x] app/api/v1_ledger.py 구현 (idempotent)
12. [x] app/repositories/postgres.py 쿼리 추가
13. [x] app/main.py /v1 라우터 등록
14. [x] 테스트 작성 및 전체 테스트 스위트 통과 (88 passed)
14. [x] 테스트 작성 및 전체 테스트 스위트 통과 (98 passed, 2026-05-01 blocker 수정 후)
## Validation
- [x] pytest 88개 전체 통과 (2026-05-02)
- [x] pytest 98개 전체 통과 (2026-05-01, blocker B-1~B-12 수정 후)
- [ ] alembic upgrade head 성공 (로컬 Docker Compose 환경 — DB 없이 코드 검증만 완료)
- [x] GET /health 응답에 service/version/checked_at(+09:00 KST) 포함 확인 (테스트)
- [x] GET /v1/assets 200 응답 확인 (테스트)
- [x] GET /v1/assets 200 응답, 필드명 확인 (cash/quantity/broker_type/strategy_params)
- [x] GET /v1/assets ?status 필터 확인 (테스트)
- [x] GET /v1/user_info runtime_id 없는 토큰 → 404 확인 (테스트)
- [x] POST /v1/assets/{asset_id}/ledger/trades 중복 → created=false 확인 (테스트)
- [x] GET /v1/user_info trading_enabled, brokers[] 확인 (테스트)
- [x] GET /v1/user_info Fernet 복호화 → credential_payload 반환 확인 (테스트)
- [x] POST /v1/assets/{asset_id}/ledger/trades: new → 201, duplicate same payload → 200, different payload → 409, unknown asset → 404 (테스트)
- [x] POST /auth/service-tokens → 201 + runtime_id 확인 (테스트)
- [x] startup: CREDENTIAL_ENCRYPTION_KEY 없으면 RuntimeError (테스트)
- [x] Fernet encrypt/decrypt roundtrip 확인 (테스트)
## Blocker Fixes (2026-05-01)
- B-1: POST /auth/service-tokens 엔드포인트 추가 (app/api/auth_routes.py, app/schemas/auth.py)
- B-2: GET /v1/assets ?status 필터 추가 (app/api/v1_assets.py)
- B-3: 응답 필드명 수정 (cash/quantity/broker_type/strategy_id → 계약 정의명)
- B-4: strategy_params {} 폴백 구현
- B-5: UserInfoResponse trading_enabled 필드 추가
- B-6: brokers[] 배열 구현 + Fernet 복호화
- B-7: 중복 수신 → HTTP 200 + status="duplicate" (was created: bool)
- B-8: 다른 payload → HTTP 409
- B-9: 없는 asset_id → HTTP 404
- B-10: lifespan startup validation (CREDENTIAL_ENCRYPTION_KEY 없으면 RuntimeError)
- B-11: list_broker_credentials postgres 구현
- B-12: docs/project-structure.md, docs/runtime-flows.md에 신규 모듈 및 v1 흐름 반영
## Changed Files (Blocker Fixes)
- app/api/auth_routes.py (수정: POST /auth/service-tokens 엔드포인트 추가)
- app/schemas/auth.py (수정: IssueServiceTokenRequest, IssueServiceTokenApiResponse 추가)
- app/schemas/v1.py (수정: 필드명 전면 수정, BrokerItem, trading_enabled, status)
- app/api/v1_assets.py (수정: status 필터, strategy_params, 새 필드명)
- app/api/v1_user_info.py (수정: trading_enabled, brokers[], Fernet 복호화, Depends(get_settings))
- app/api/v1_ledger.py (수정: 200/201/404/409 분기, _payloads_match 비교)
- app/repositories/postgres.py (수정: list_broker_credentials 추가)
- app/main.py (수정: startup validation 추가)
- tests/test_v1.py (전면 재작성: 19개 테스트로 확장)
- tests/test_app.py (수정: db_enabled=True 테스트에 credential_encryption_key 추가)
- docs/project-structure.md (수정: v1 모듈, encryption.py 반영)
- docs/runtime-flows.md (수정: v1 API 흐름, startup 검증 흐름 추가)
## Design Decisions (confirmed during implementation)