# REL-001: trex-basic v1 API contract - Status: draft - Profile: app-service - Included Batch: BAT-001 ## Scope - Included: - BAT-001 (REQ-004, REQ-005, REQ-006, REQ-007, REQ-008, REQ-009, REQ-010) - GET /health 응답 스키마 확장 (service/version/checked_at 필드) - POST /auth/service-tokens — service-token 발급 + runtime_id 반환 API - GET /v1/assets — service-token 소유자 범위의 포트폴리오 목록 조회 (status 필터, strategy_params, owner scope 재확인 반영) - GET /v1/user_info — 사용자 정보 + broker credentials 복호화 반환 - POST /v1/assets/{asset_id}/ledger/trades — 체결 기록 (idempotent: 201/200/409/404) - Fernet 암호화 유틸리티 (app/core/encryption.py) - startup validation: CREDENTIAL_ENCRYPTION_KEY 없으면 RuntimeError - DB 스키마 migration: portfolios.market, auth_tokens.runtime_id, broker_credentials, ledger_trades - Excluded: - GET /health status degraded/failed 경로 (이번 반복 OOS) - broker credential 저장 HTTP API (CLI 전용) - DB 환경(Docker Compose) 직접 실행 검증 ## Rollout Plan 1. 배포 전 `CREDENTIAL_ENCRYPTION_KEY` 환경 변수 설정 확인 (`python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"` 로 생성) 2. `alembic upgrade head` 실행 — migration 0014 적용 (portfolios.market, auth_tokens.runtime_id, broker_credentials, ledger_trades) 3. 서비스 재시작 (`uvicorn app.main:app`) 4. GET /health 호출로 기동 확인 5. v1 smoke 테스트: GET /v1/assets, GET /v1/user_info (service-token 사용) 6. GET /v1/assets smoke 검증 시 service-token 소유자의 portfolio만 반환되고 다른 사용자 소유 portfolio는 포함되지 않는지 확인 ## Rollback Plan - 조건: startup 실패 또는 GET /health 비정상 응답 시 - 절차: 1. 이전 버전 코드로 롤백 (`git revert` 또는 이전 컨테이너 이미지 재기동) 2. `alembic downgrade -1` — migration 0014 롤백 (신규 테이블/컬럼 DROP) 3. `CREDENTIAL_ENCRYPTION_KEY` 미설정 상태로도 DB disabled 모드에서는 기동 가능하므로, 긴급 시 `PORTFOLIOHUB_DB_ENABLED=false`로 임시 운영 가능 ## Verification Checklist ### 배포 전 - [ ] `CREDENTIAL_ENCRYPTION_KEY` 환경 변수 설정 완료 - [ ] `alembic upgrade head` 성공 (migration 0014) - [ ] pytest 98개 로컬 PASS 확인 (2026-05-01 완료) ### 배포 후 - [ ] GET /health → 200, body에 `status`, `service`, `version`, `checked_at` 포함 확인 - [ ] GET /health → `checked_at`에 `+09:00` 포함 확인 - [ ] POST /auth/service-tokens (admin 토큰) → 201, `runtime_id` 포함 확인 - [ ] GET /v1/assets (service-token) → 200, `assets[]` 반환 확인 - [ ] GET /v1/assets (service-token) → service-token 소유자의 portfolio만 반환되고 다른 사용자 portfolio가 비노출인지 확인 (REQ-006 owner scope 재확인) - [ ] GET /v1/user_info (service-token) → 200, `trading_enabled`/`brokers[]` 포함 확인 - [ ] POST /v1/assets/{asset_id}/ledger/trades → 201 (신규), 200 (중복 동일 payload) 확인 - [ ] 서비스 startup 로그에 RuntimeError 없음 확인 ## Release Execution Evidence - Release Status Transition Target: released ### Deployment Facts - Executed At: - (미기록 — 배포 미수행) - Completed At: - (미기록) - Environment: - (미기록) - Operator: - (미기록) - Revision or Artifact: - (미기록 — 커밋 SHA 배포 후 기록) - Commands or Procedure: - (미기록) ### Profile-Specific Checks - app-service: - Health Endpoint: - (미수행 — 배포 후 확인 필요) - Startup Log Fields: - (미수행 — 배포 후 확인 필요) - Request Log Fields: - (미수행 — 배포 후 확인 필요) - Smoke or Manual Verification: - (미수행 — Verification Checklist 참조) ### Rollback Outcome - Rollback Required: - (미기록) - Rollback Trigger: - none - Rollback Action: - none ### Release Decision Evidence - Released Decision: - (미기록) - Rationale: - (미기록) - Recorded By: - (미기록) - Recorded At: - (미기록) ## Feedback Handoff - Observation Summary: - (배포 후 기록) - Discovery Input: - (배포 후 기록) - REQ Input: - (배포 후 기록) - Change Request Input: - (배포 후 기록)