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>
4.4 KiB
4.4 KiB
BAT-010 Planning
- Status: confirmed
- Batch: BAT-010
- Profile: standard
Included REQ
- REQ-030: portfolio tag 적용/해제/조회 v1 라우트 (Interface, Medium)
- REQ-031: portfolio comment CRUD v1 라우트 (Interface, Medium)
- REQ-032: portfolio v1 baseline 문서 갱신 (Documentation, Medium)
Delivery Plan
구현 범위 및 순서
-
REQ-030 기존 라우트 보강 + GET 신설
- 기존
POST /v1/portfolios/{id}/tags,DELETE /v1/portfolios/{id}/tags/{tag_id}라우트 감사 결과:- ownership 검증 ✓, tag 정책 검증 ✓ (POST만)
- disabled portfolio 보호 누락 → AC-8 충족을 위해 추가 필요
GET /v1/portfolios/{id}/tags신설:portfolio.tag_ids→repo.get_tags_by_ids()→PortfolioTagListResponse- schema 추가:
PortfolioTagListResponse(tags: list[TagItem], total: int)
- 기존
-
REQ-031 comment CRUD 구현
- 신규 4개 라우트:
POST,GET,PATCH,DELETE /v1/portfolios/{id}/comments[/{comment_id}] - 기존 repo 메서드 재사용:
create_comment,list_comments,update_comment,delete_comment - schema 추가 (app/schemas/v1.py):
PortfolioCommentItem,PortfolioCommentRequest,PortfolioCommentUpdateRequest,PortfolioCommentListResponse - ownership 검증:
_get_portfolio_or_404헬퍼 재사용 (BAT-009 패턴) - disabled 보호: POST/PATCH/DELETE → HTTP 409; GET → 허용
- comment 작성자 ownership: portfolio ownership만 적용 (REQ-031 Notes 결정)
- 신규 4개 라우트:
-
테스트 작성
tests/test_v1_portfolios_tags_comments.py신규- REQ-030 AC-1
11, REQ-031 AC-111 커버 - BAT-009의
_with_repo패치 패턴 재사용
-
REQ-032 baseline 문서 갱신
docs/interface-contract.md: v1 portfolio CRUD 엔드포인트 섹션 추가 (REQ-025~028), GET /v1/portfolios/{id}/tags 엔드포인트 추가, comment CRUD 엔드포인트 추가; POST /v1/assets/{asset_id}/ledger/trades 섹션 "pending REQ-029" 마킹docs/runtime-flows.md: portfolio mutation flow + GET /v1/portfolios 토큰 분기 + soft delete flow 추가docs/data-model.md: Portfolio.status='disabled' 의미 + 의존 데이터 보존 정책 추가docs/project-structure.md: app/api/v1_portfolios.py 책임 갱신 + app/schemas/v1.py schema 목록 갱신
선행 조건
- BAT-009 Implemented (REQ-025~028) ✓ —
_get_portfolio_or_404,_require_write_token,_close_repo헬퍼 재사용 - BAT-003 release-candidate (REQ-001/003):
portfolios.tag_ids UUID[],repo.append_portfolio_tag_id/remove_portfolio_tag_id/get_tags_by_ids✓ - BAT-004 release-candidate (REQ-004/005): POST/DELETE /v1/portfolios/{id}/tags 이미 구현 ✓
app/repositories/portfolio_repository.py:create_comment,list_comments,update_comment,delete_comment추상 메서드 이미 정의 ✓app/domain/models.py:PortfolioComment(id, portfolio_id, content, created_at, updated_at)✓
Dependencies
- Internal:
- BAT-009(REQ-025~028):
_get_portfolio_or_404,_require_write_token헬퍼,PortfolioItem스키마 패턴 - BAT-003(REQ-001~003):
portfolios.tag_ids,repo.get_tags_by_ids - BAT-004(REQ-005): POST/DELETE tag 라우트 (보강 대상)
- BAT-009(REQ-025~028):
- External:
- 없음
Design Gate
- Design Required Before Implementation: yes
- Reason:
- REQ-031 comment 작성자 ownership 정책 확정: portfolio ownership만 적용 (결정 완료)
- REQ-030 GET 응답 schema 확정:
PortfolioTagListResponse(tags: list[TagItem], total: int)(결정 완료) - REQ-032 ledger path 마킹 방식 확정: "pending REQ-029" 주석 처리 (결정 완료)
- 모든 설계 gate가 사전 해소됨 → design.md 확정 후 구현 착수 가능
Milestones
- planning.md confirmed ✓ (현재 단계)
- design.md confirmed — key decisions 기록
- REQ-030 disabled 보호 보강 + GET 신설 + tests
- REQ-031 comment CRUD 4종 + tests
- REQ-032 baseline docs 4종 갱신
- 전체 테스트 스위트 통과
- verification.md 완성
Risks
- R-1 (Low): 기존 POST/DELETE tag 라우트에 disabled 보호 추가 시
test_tags_http_api.py회귀 가능 → 기존 테스트가 disabled portfolio를 사용하지 않으면 영향 없음; 확인 후 보강 - R-2 (Low):
repo.get_tags_by_ids(portfolio.tag_ids)— tag_ids가 빈 배열일 경우 빈 dict 반환 → 빈 list 응답으로 정상 처리 - R-3 (Low):
update_comment/delete_commentpostgres 구현에서portfolio_comments테이블 존재 여부 확인 필요