feat: v1 portfolio mutation, sub-resources, ledger path migration (BAT-008~011)

dcy-003/004 기반 v1 API surface 완성 및 BAT-008~011 구현·검증 완료:

- BAT-008 (REQ-019~021,024): 토큰 surface baseline 문서 갱신
- BAT-009 (REQ-025~028): POST/PATCH/DELETE/GET /v1/portfolios CRUD 신설
  - _require_write_token, _get_portfolio_or_404, soft delete, daemon-scoped list
- BAT-010 (REQ-030~032): portfolio tag/comment 서브 라우트 신설 + baseline 갱신
  - GET/POST/DELETE /v1/portfolios/{id}/tags
  - POST/GET/PATCH/DELETE /v1/portfolios/{id}/comments
- BAT-011 (REQ-029): ledger path migration
  - POST /v1/assets/{asset_id}/ledger/trades → /v1/portfolios/{portfolio_id}/ledger/trades
  - v1_ledger.py 제거, disabled 차단(409) 추가
  - test_v1.py / test_daemon_assignment.py 구 path 갱신
- 신규 tests: test_v1_portfolios_crud.py, test_v1_portfolios_list.py,
  test_v1_portfolios_tags_comments.py, test_v1_portfolios_ledger.py
- 전체 suite: 340 passed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 07:25:39 +00:00
co-authored by Claude Sonnet 4.6
parent c815ce39b6
commit 4bf6b554a7
50 changed files with 3989 additions and 249 deletions
@@ -0,0 +1,61 @@
# BAT-008 Verification
- Status: release-candidate
- Batch: BAT-008
## Acceptance Mapping
- REQ-019:
- AC-1: `grep -n "service-token rebind" docs/interface-contract.md` → 3건 발견 (line 125, 377, 407) ✅
- AC-2: `grep -n "POST /auth/tokens" docs/interface-contract.md` → "Removed" 섹션 헤더 및 설명으로만 잔존 (신규 발급 명세 없음) ✅
- AC-3: `grep -n "AuthContext.*daemon_id" docs/runtime-flows.md` → line 148 ("AuthContext is populated with ... and daemon_id") ✅
- AC-4: `grep -n "revoked_at IS NULL" docs/data-model.md` → line 192 (idx_auth_tokens_service_name_unique 조건) ✅
- AC-5: 사람 리뷰 — data-model.md, interface-contract.md, runtime-flows.md, project-structure.md 전체에서 client token 발급 경로 잔재 없음; "client" 언급은 모두 "Removed/Deprecated" 맥락. ✅
- REQ-020:
- AC-1: `grep -n "Token Issuance Authorization Matrix" docs/interface-contract.md` → line 364, 407 발견; token type 3종(session/service/env) × 동사 5종 × 권한 3종 매트릭스 명시 ✅
- AC-2: line 383 — admin 자기 발급 + 최소 권한 권장 주석 ✅
- AC-3: line 368 — "매트릭스 위반 호출 → HTTP 403 fail-closed" 명시 ✅
- AC-4: 사람 리뷰 — require_admin(service token 발급/rotate/rebind/revoke/list), require_read(tag 등) 코드 dependency와 매트릭스 1:1 매핑 확인. 불일치 항목 없음. ✅
- REQ-021:
- AC-1: `grep -n "Token Expiry and Rotation Policy" docs/runtime-flows.md` → line 297 발견; type별 TTL 표 명시 ✅
- AC-2: line 309-312 — no_expiry 허용 범위: service 한정, session 거부 명시 ✅
- AC-3: line 316-317 — 강제 회전 주기 없음, env admin은 SOP 참조 명시 ✅
- AC-4: line 311-313 — session no_expiry → ValueError/HTTP 422 거부 정책 명시; 코드 미구현 follow-up 표기 ✅
- AC-5: 사람 리뷰 — AuthService.login(session 만료), AuthService.issue_service_token(service 만료·no_expiry) 로직과 정책 일치 확인. session no_expiry 코드 미구현 항목 follow-up으로 기록됨. ✅
- REQ-024:
- AC-1: `grep -n "env admin token 운영 SOP" docs/runtime-flows.md` → line 326 발견; 분기 권장 회전 주기 + 강제 없음 명시 ✅
- AC-2: `grep -n "다단계 회전 절차" docs/runtime-flows.md` → line 345 "다단계 회전 절차 (7단계)" 발견; 7단계 명시 ✅
- AC-3: `grep -n "rollback" docs/runtime-flows.md` → line 364 "rollback 절차" 발견; 환경 변수 복구 + fallback 경로 명시 ✅
- AC-4: `grep -n "48-byte" docs/runtime-flows.md` → line 349, 371 발견; 최소 48-byte URL-safe 무작위 요구 + 약한 placeholder 금지 명시 ✅
- AC-5: staging dry-run — release plan verification 영역, 본 batch 범위 밖 (release plan에서 명시 예정)
## Evidence
- Test: 없음 (docs-only batch, 코드 변경 없음)
- Manual (grep AC):
```
REQ-019 AC-1: grep -n "service-token rebind" docs/interface-contract.md → 3건 ✅
REQ-019 AC-2: grep -n "POST /auth/tokens" docs/interface-contract.md → Removed 섹션만 잔존 ✅
REQ-019 AC-3: grep -n "AuthContext.*daemon_id" docs/runtime-flows.md → line 148 ✅
REQ-019 AC-4: grep -n "revoked_at IS NULL" docs/data-model.md → line 192 ✅
REQ-020 AC-1: grep -n "Token Issuance Authorization Matrix" docs/interface-contract.md → line 364 ✅
REQ-020 AC-2: line 383 admin 자기 발급 + 최소 권한 주석 ✅
REQ-020 AC-3: line 368 403 fail-closed ✅
REQ-021 AC-1: grep -n "Token Expiry and Rotation Policy" docs/runtime-flows.md → line 297 ✅
REQ-021 AC-2: no_expiry service 한정 명시 ✅
REQ-021 AC-3: 강제 회전 없음 명시 ✅
REQ-024 AC-1: grep -n "env admin token 운영 SOP" docs/runtime-flows.md → line 326 ✅
REQ-024 AC-2: grep -n "다단계 회전 절차" docs/runtime-flows.md → line 345 ✅
REQ-024 AC-3: grep -n "rollback" docs/runtime-flows.md → line 364 ✅
REQ-024 AC-4: grep -n "48-byte" docs/runtime-flows.md → line 349, 371 ✅
```
- Logs: 없음 (docs-only)
## Result
- Ready for Release: true
- Blocking Issues: 없음
- 미완료 AC: REQ-024 AC-5 (staging dry-run) — release plan verification 영역, release plan에 포함 예정