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:
@@ -0,0 +1,60 @@
|
||||
# BAT-008 Design
|
||||
|
||||
- Status: confirmed
|
||||
- Batch: BAT-008
|
||||
|
||||
## Architecture Summary
|
||||
- 코드 변경 없이 baseline 4종 문서(`docs/interface-contract.md`, `docs/runtime-flows.md`, `docs/data-model.md`, `docs/project-structure.md`)를 편집한다.
|
||||
- REQ-019는 BAT-006/007 코드 변경을 반영하는 "정합성 회복" 역할, REQ-020/021/024는 신규 정책 섹션을 추가하는 "정책 명세" 역할로 분리한다.
|
||||
|
||||
## Changed Areas
|
||||
- Docs:
|
||||
- `docs/data-model.md` — auth_tokens 인덱스 조건 갱신, client token 제거
|
||||
- `docs/interface-contract.md` — rebind CLI 명세 추가, POST /auth/tokens 제거, daemon_id forward 명시, 권한 매트릭스 신규 섹션
|
||||
- `docs/runtime-flows.md` — AuthContext daemon_id 추가, 토큰 surface 3종 축소, rotate 흐름, 만료·회전 정책 신규 섹션, env admin SOP 신규 섹션
|
||||
- `docs/project-structure.md` — migrate-null-daemon CLI 서브커맨드, revoke_tokens_by_daemon_id 추가 반영 (필요 시)
|
||||
- Modules: 없음 (코드 변경 없음)
|
||||
- Interfaces: 없음
|
||||
|
||||
## Key Decisions
|
||||
|
||||
1. **파일별 REQ 담당 분리 (충돌 방지)**
|
||||
- `docs/data-model.md`: REQ-019 단독 담당 (인덱스 변경, client 타입 제거)
|
||||
- `docs/interface-contract.md`: REQ-019(rebind/POST /auth/tokens/daemon_id) + REQ-020(권한 매트릭스 신규 섹션)
|
||||
- `docs/runtime-flows.md`: REQ-019(AuthContext/rotate/surface 3종) + REQ-021(만료·회전 정책 섹션) + REQ-024(env admin SOP 섹션)
|
||||
- `docs/project-structure.md`: REQ-019(선택 — CLI/메서드 추가 반영)
|
||||
|
||||
2. **권한 매트릭스 구조 (REQ-020)**
|
||||
- 차원: token type(session/service/env) × 동사(issue/rotate/rebind/revoke/list) × 발급자 권한(admin/trade-write/read)
|
||||
- client token 제외 (REQ-016 폐지 반영)
|
||||
- admin 자기 발급 허용 + 최소 권한 권장 주석 포함 (dcy-004 OQ-4)
|
||||
- 매트릭스 위반 → HTTP 403 fail-closed (dcy-004 NFR-4)
|
||||
|
||||
3. **만료·회전 정책 섹션 위치 (REQ-021)**
|
||||
- `docs/runtime-flows.md`에 "토큰 만료·회전 정책" 섹션 신규 추가
|
||||
- type별 TTL: session=settings.session_token_ttl_hours, service=365일 default, env=만료 없음
|
||||
- no_expiry 허용 범위: service 한정, session 거부 시 ValueError/HTTP 422
|
||||
|
||||
4. **env admin SOP 위치 (REQ-024)**
|
||||
- `docs/runtime-flows.md`에 "env admin token 운영 SOP" 섹션 추가 (README.md 링크 선택)
|
||||
- 7단계 회전 절차 + rollback + token 강도 가이드 + 권장 회전 주기(분기)
|
||||
|
||||
5. **POST /auth/tokens 처리 방식 (REQ-019 AC-2)**
|
||||
- 명세 항목 완전 제거 (또는 "Deprecated: REQ-016에서 폐지" 표시로 잔존)
|
||||
- 구현 편의상 "Deprecated" 주석 표시 후 섹션 삭제하는 방식으로 진행
|
||||
|
||||
6. **project-structure.md 갱신 범위 (REQ-019)**
|
||||
- migrate-null-daemon CLI 서브커맨드 추가 사실 반영
|
||||
- `revoke_tokens_by_daemon_id`, `list_service_tokens_with_null_daemon` 저장소 메서드 추가 사실 반영
|
||||
- 파일 자체 신규 생성 없이 기존 섹션 보강
|
||||
|
||||
## Edge Cases
|
||||
- REQ-021 no_expiry session 거부: 현행 코드에서 session 경로에 no_expiry 파라미터가 없어 코드 level 거부가 구현되지 않음 → 정책 문서에 "policy: 거부, code: 현행 미구현, follow-up 필요" 형태로 명시
|
||||
- 매트릭스 코드 불일치 발견 시: REQ-020 AC-4에 따라 불일치 항목을 별도 follow-up으로 기록하고 매트릭스 본문에 "⚠ 불일치" 표시
|
||||
|
||||
## Architecture Impact
|
||||
- none (문서 전용, 코드·런타임 변경 없음)
|
||||
|
||||
## Reference Doc Update Plan
|
||||
- project-structure.md: CLI 서브커맨드·저장소 메서드 추가 사실 반영 (소규모 갱신)
|
||||
- runtime-flows.md: 신규 정책 섹션 2개 추가 + AuthContext 갱신 + rotate 흐름 보강
|
||||
@@ -0,0 +1,32 @@
|
||||
# BAT-008 Implementation
|
||||
|
||||
- Status: completed
|
||||
- Batch: BAT-008
|
||||
|
||||
## Plan Summary
|
||||
- REQ-019: baseline 4종 문서에 BAT-006/007 코드 변경 사항 반영 (정합성 회복)
|
||||
- REQ-020: docs/interface-contract.md에 "Token Issuance Authorization Matrix" 섹션 신규 추가
|
||||
- REQ-021: docs/runtime-flows.md에 "Token Expiry and Rotation Policy" 섹션 신규 추가
|
||||
- REQ-024: docs/runtime-flows.md에 "env admin token 운영 SOP" 섹션 신규 추가
|
||||
|
||||
## Changed Files
|
||||
|
||||
1. `docs/data-model.md` — AuthToken token_type "client" 제거 반영; idx_auth_tokens_service_name_unique에 AND revoked_at IS NULL 조건 추가(REQ-017); Daemon deactivation 시 auto-revoke 정책 반영(REQ-022); User/AuthToken Purpose 문구 갱신; Change Log 추가
|
||||
2. `docs/interface-contract.md` — service-token rebind/migrate-null-daemon CLI 명세 추가; POST /auth/tokens 제거 명시(REQ-016); POST /auth/service-tokens daemon_id forward 명세 추가(REQ-018); Token Type Branching 갱신(client→Removed, session/env 명시); Daemon Authorization Model 갱신; "Token Issuance Authorization Matrix" 섹션 신규 추가(REQ-020); Change Log 추가
|
||||
3. `docs/runtime-flows.md` — DB Token Auth flow AuthContext 설명 보강; POST /auth/service-tokens flow daemon_id 반영; service-token rebind 흐름 추가; daemon update --deactivate 흐름 추가; "Token Expiry and Rotation Policy" 섹션 신규 추가(REQ-021); "env admin token 운영 SOP" 섹션 신규 추가(REQ-024); Change Log 추가
|
||||
4. `docs/project-structure.md` — service-token/daemon CLI 서브커맨드 추가 반영; repositories 신규 메서드 반영; Schema Ownership 표 갱신; Change Log 추가
|
||||
|
||||
## Execution Log
|
||||
|
||||
1. `docs/data-model.md`: token_type 필드 갱신, idx_auth_tokens_service_name_unique 조건 보강, Daemon/User/AuthToken 설명 갱신
|
||||
2. `docs/interface-contract.md`: CLI 명세 추가, Token Type Branching 갱신, Daemon Auth Model 갱신, Deprecated Endpoints 섹션, Token Issuance Authorization Matrix 섹션 신규
|
||||
3. `docs/runtime-flows.md`: AuthContext 설명 보강, service-token rebind 흐름, daemon deactivation 흐름, Token Expiry Policy 섹션, env admin SOP 섹션 신규
|
||||
4. `docs/project-structure.md`: CLI 그룹, 저장소 메서드, Schema Ownership 표 갱신
|
||||
|
||||
## Validation
|
||||
- 코드 변경 없음 — 단위 테스트/lint 불필요
|
||||
- grep AC 검증은 confirm-batch-verification 단계에서 수행
|
||||
|
||||
## Remaining Risks
|
||||
- REQ-021 AC-4: session no_expiry 코드 enforcement 미구현 — 정책 문서에 "follow-up 필요" 명시로 대응
|
||||
- 사람 리뷰(AC-5 등)는 verify 단계에서 수행
|
||||
@@ -0,0 +1,33 @@
|
||||
# BAT-008: dcy-004 토큰 surface baseline 문서화
|
||||
|
||||
- Status: release-candidate
|
||||
- Profile: standard
|
||||
- Source Discovery: dcy-004
|
||||
- Included REQ: REQ-019, REQ-020, REQ-021, REQ-024
|
||||
- Excluded REQ: (없음 — dcy-004 Documentation REQ 4건 전부 포함)
|
||||
|
||||
## Summary
|
||||
- BAT-006(REQ-016/017/018) 및 BAT-007(REQ-022/023) 코드 변경 사항을 baseline 4종 문서에 일괄 반영하고(REQ-019), 토큰 발급 권한 매트릭스(REQ-020)·토큰 만료·회전 정책(REQ-021)·env admin token 운영 SOP(REQ-024)를 신규 명시한다.
|
||||
- 코드 변경 없이 문서 편집만으로 완결되므로 구현 단계는 markdown 편집, 검증 단계는 grep + 사람 리뷰로 수행한다.
|
||||
|
||||
## Scope
|
||||
- In Scope:
|
||||
- `docs/interface-contract.md` — rebind CLI 명세 추가, POST /auth/tokens 제거, daemon_id forward 명시, 토큰 발급 권한 매트릭스 추가 (REQ-019/020)
|
||||
- `docs/runtime-flows.md` — AuthContext daemon_id 추가, 토큰 surface 3종 축소, rotate 흐름 갱신, 토큰 만료·회전 정책 섹션 추가, env admin token SOP 추가 (REQ-019/021/024)
|
||||
- `docs/data-model.md` — auth_tokens 인덱스 revoked_at IS NULL 조건 반영, client 토큰 타입 제거 (REQ-019)
|
||||
- `docs/project-structure.md` — migrate-null-daemon CLI, revoke_tokens_by_daemon_id 추가에 따른 패키지 책임 갱신 (REQ-019, 필요 시)
|
||||
- Out of Scope:
|
||||
- 코드 변경 없음
|
||||
- v1 portfolio 관련 문서 (→ dcy-003 REQ-025~032, 별도 batch)
|
||||
- 새 정책 코드 enforcement (현행 구현 유지, 정책 baseline 명시에 집중)
|
||||
|
||||
## Documents
|
||||
- Planning: [planning.md](./planning.md)
|
||||
- Design: [design.md](./design.md)
|
||||
- Implementation: [implementation.md](./implementation.md)
|
||||
- Verification: [verification.md](./verification.md)
|
||||
|
||||
## Notes
|
||||
- R-1 (Low): REQ-019/020/021/024는 모두 동일 파일 세트를 편집하므로 섹션 충돌 방지를 위해 구현 전 design에서 파일별 담당 REQ를 명확히 분리한다.
|
||||
- R-2 (Low): grep AC는 baseline 정합성만 확인하고 정책 정확도는 사람 리뷰로 보완한다.
|
||||
- 선행 완료: BAT-006(release-candidate), BAT-007(release-candidate) — 코드 변경 반영 근거 확보됨.
|
||||
@@ -0,0 +1,40 @@
|
||||
# BAT-008 Planning
|
||||
|
||||
- Status: confirmed
|
||||
- Batch: BAT-008
|
||||
- Profile: standard
|
||||
|
||||
## Included REQ
|
||||
- REQ-019: 토큰 surface baseline 문서 정합성 회복 (docs/interface-contract.md, runtime-flows.md, data-model.md, project-structure.md)
|
||||
- REQ-020: 토큰 발급 권한 매트릭스 정의 (docs/interface-contract.md 신규 섹션)
|
||||
- REQ-021: 토큰 만료·회전 정책 정의 (docs/runtime-flows.md 신규 섹션)
|
||||
- REQ-024: env admin token 운영 SOP 정의 (docs/runtime-flows.md 또는 README.md 신규 섹션)
|
||||
|
||||
## Delivery Plan
|
||||
1. **Design** (파일별 REQ 담당 분리 + 섹션 충돌 방지 계획 수립)
|
||||
2. **Implementation** — 아래 순서로 편집:
|
||||
a. `docs/data-model.md` — auth_tokens 인덱스 변경 반영, client 토큰 타입 제거 (REQ-019 AC-4/5)
|
||||
b. `docs/interface-contract.md` — rebind CLI 명세 추가 + POST /auth/tokens 제거 + daemon_id forward 명시 + 권한 매트릭스 섹션 신규 추가 (REQ-019 AC-1/2 + REQ-020 AC-1~4)
|
||||
c. `docs/runtime-flows.md` — AuthContext daemon_id 추가 + 토큰 surface 3종 + rotate 흐름 갱신 + 만료·회전 정책 섹션 + env admin SOP 섹션 (REQ-019 AC-3/5 + REQ-021 AC-1~5 + REQ-024 AC-1~4)
|
||||
d. `docs/project-structure.md` — 필요 시 패키지 책임 갱신 (REQ-019, optional)
|
||||
3. **Verification** — grep AC(REQ별) + 사람 리뷰
|
||||
|
||||
## Dependencies
|
||||
- Internal:
|
||||
- BAT-006 (release-candidate): client token 폐지, rotate index 보강, daemon_id forward 코드 변경 — 반영 근거 확보
|
||||
- BAT-007 (release-candidate): daemon deactivation auto-revoke, NULL daemon migration CLI — project-structure 갱신 근거
|
||||
- External:
|
||||
- 없음
|
||||
|
||||
## Design Gate
|
||||
- Design Required Before Implementation: yes
|
||||
- Reason: 4개 REQ가 동일 파일 세트(interface-contract.md, runtime-flows.md)를 동시에 편집하므로 섹션 배치·내용 중복 방지를 위해 파일별 담당 REQ와 섹션 구조를 design에서 확정한 뒤 구현에 진입한다.
|
||||
|
||||
## Milestones
|
||||
1. Design confirmed — 파일별 담당 REQ, 섹션 구조, 내용 범위 확정
|
||||
2. Implementation completed — 4개 docs 파일 편집 완료
|
||||
3. Verification release-candidate — grep AC 전부 통과, 사람 리뷰 완료
|
||||
|
||||
## Risks
|
||||
- R-1 (Low): 동일 파일 다수 REQ 편집 → 섹션 충돌 또는 내용 중복 가능 → design 단계에서 파일별 REQ 담당 분리로 완화
|
||||
- R-2 (Low): grep 기반 AC는 키워드 존재 여부만 확인 → 정책 정확도는 사람 리뷰로 보완
|
||||
@@ -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에 포함 예정
|
||||
Reference in New Issue
Block a user