Files
portfolio-hub/docs/srs/Interface/req-031_v1-portfolios-comments-crud.md
T
genichinandClaude Sonnet 4.6 4bf6b554a7 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>
2026-05-21 07:25:39 +00:00

6.6 KiB

REQ-031: portfolio comment CRUD v1 라우트

  • Status: Implemented
  • Type: Interface
  • Priority: Medium
  • Owner: Justin Ko

Intent

  • v1 API에 portfolio comment CRUD 경로(/v1/portfolios/{portfolio_id}/comments)를 신설해 user/admin이 HTTP로 portfolio에 코멘트를 작성·관리할 수 있도록 한다.
  • ownership 규칙과 disabled 차단을 REQ-026/027과 동일 패턴으로 적용해 v1 portfolio surface 인가 일관성을 확보한다.

Requirement

  • 신규 라우트 (Bearer 인증 필수):
    • POST /v1/portfolios/{portfolio_id}/comments — body: {"content": "<text>"}. 응답 HTTP 201 + 생성된 comment.
    • GET /v1/portfolios/{portfolio_id}/comments — 응답 HTTP 200 + comment 목록(created_at desc 순).
    • PATCH /v1/portfolios/{portfolio_id}/comments/{comment_id} — body: {"content": "<updated>"}. 응답 HTTP 200 + 갱신된 comment.
    • DELETE /v1/portfolios/{portfolio_id}/comments/{comment_id} — 응답 HTTP 200 또는 204.
  • ownership 규칙 (REQ-026/030과 동일):
    • token_type ∈ {service, client} → HTTP 403 fail-closed.
    • permission='admin' → 모든 portfolio.
    • permission ∈ {read, trade-write} → 자기 소유 portfolio만, 불일치 시 HTTP 403.
  • disabled portfolio 차단 (REQ-027 정합): status='disabled'인 portfolio에 대해 POST/PATCH/DELETE는 HTTP 409 또는 422로 거부. GET은 허용.
  • 비존재 portfolio_id 또는 comment_id는 HTTP 404.
  • 기존 CommentCreateRequest/CommentUpdateRequest/CommentResponse schema 재사용 또는 v1 전용 래핑(PortfolioCommentRequest, PortfolioCommentResponse).
  • 기존 service 메서드(create_comment, list_comments, update_comment, delete_comment) 재사용.

Acceptance Criteria

  1. Given session token + 본인 active portfolio, When POST /v1/portfolios/{id}/comments body {"content": "..."}, Then HTTP 201 + 생성된 comment.
  2. Given session token + 본인 portfolio + 적용된 comments, When GET /v1/portfolios/{id}/comments, Then HTTP 200 + 코멘트 목록(created_at desc).
  3. Given session token + 본인 portfolio + 본인 comment, When PATCH /v1/portfolios/{id}/comments/{comment_id} body {"content": "..."}, Then HTTP 200 + 갱신된 comment.
  4. Given session token + 본인 portfolio + 본인 comment, When DELETE /v1/portfolios/{id}/comments/{comment_id}, Then HTTP 200/204.
  5. Given session token + 타 user portfolio, When 임의 동사 호출, Then HTTP 403 (ownership 불일치).
  6. Given service/client token, When 임의 동사 호출, Then HTTP 403 fail-closed.
  7. Given session token + disabled portfolio, When POST/PATCH/DELETE, Then HTTP 409 또는 422.
  8. Given session token + disabled portfolio, When GET /v1/portfolios/{id}/comments, Then HTTP 200 + 기존 comments 목록 반환(조회는 허용).
  9. Given admin token + 타 user portfolio, When 임의 동사 호출, Then HTTP 200/201/204 (admin은 모든 portfolio 허용).
  10. Given Bearer token 없음, When 호출, Then HTTP 401.
  11. Given 비존재 portfolio_id 또는 comment_id, When 호출, Then HTTP 404.

Impacted Area

  • Docs:
    • docs/interface-contract.md — /v1/portfolios/{id}/comments 명세 (REQ-032)
  • Modules:
    • app/api/v1_portfolios.py — comment 서브 라우트 추가
    • app/schemas/v1.py — comment 관련 스키마 (기존 app/schemas/portfolio.py:CommentCreateRequest/CommentUpdateRequest/CommentResponse 재사용 또는 v1 래핑)
    • app/services/portfolio_service.py:create_comment/list_comments/update_comment/delete_comment — 기존 메서드 재사용 + disabled 차단 검증 추가
  • Tests:
    • 신규/갱신 tests/test_v1_portfolios_tags_comments.py — AC-1~11 (comment 부분)

Notes

  • comment 작성자 ownership(본인 comment만 수정/삭제 가능)은 기존 portfolio_comments 테이블 구조에 따라 처리. dcy-003 본문은 portfolio ownership만 명시하고 comment 작성자 ownership은 별도 결정 사항 — 본 REQ에서는 portfolio ownership을 일관 적용하고 comment 작성자 ownership은 batch design 단계에서 확정.
  • 본 REQ는 dcy-003 FR-8 산출물. tag(REQ-030)와 별도 REQ로 분리해 동사 surface를 명확히 함.
  • Source: dcy-003 FR-8, NFR-1, NFR-3, NFR-4.

Change Log

CHG-20260521-01

  • Date: 2026-05-21
  • Author: Justin Ko

Change Summary

  • Status: Approved → Implemented

Intent

  • BAT-010 구현 완료: app/api/v1_portfolios.py에 POST/GET/PATCH/DELETE /v1/portfolios/{id}/comments 4종 신설; app/schemas/v1.py에 comment schema 4종 추가; tests/test_v1_portfolios_tags_comments.py AC-1~11 커버; comment 작성자 ownership은 portfolio ownership만 적용(design decision #3)

Acceptance Criteria Delta

  • No change

Impacted Area Delta

  • No change

Delivery Trace Delta

  • Batches: BAT-010 (release-candidate)
  • Releases: pending

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: implemented
  • Follow-up Action: BAT-010 release candidate → draft-release

CHG-20260520-02

  • Date: 2026-05-20
  • Author: Justin Ko

Change Summary

  • Status: Proposed → Approved

Intent

  • 승인 게이트 통과: 필수 필드(Status/Type/Priority/Owner/Intent/Requirement/AC/Impacted Area/Change Log) 모두 충족, AC 구체성 확인 완료, blocker 없음

Acceptance Criteria Delta

  • No change

Impacted Area Delta

  • No change

Delivery Trace Delta

  • Batches: none (미정)
  • Releases: none (미정)

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: promote-to-approved
  • Follow-up Action: batch 계획 편입

CHG-20260520-01

  • Date: 2026-05-20
  • Author: Justin Ko

Change Summary

  • 최초 생성 — dcy-003 confirm-discovery 후 draft-req 실행. dcy-003 FR-8 산출물.

Intent

  • v1 portfolio comment CRUD 라우트 신설 + ownership/disabled 검증 일관 적용.

Acceptance Criteria Delta

  • Added:
    • AC-1~11 최초 작성

Impacted Area Delta

  • Docs: docs/interface-contract.md (REQ-032)
  • Modules: app/api/v1_portfolios.py, app/schemas/v1.py, app/services/portfolio_service.py — 최초 지정
  • Tests: tests/test_v1_portfolios_tags_comments.py — 최초 지정

Delivery Trace Delta

  • Batches: none (미정)
  • Releases: none (미정)

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: confirm-req 후 batch 계획 편입; comment 작성자 ownership 정책은 batch design 단계에서 확정

Validation Plan

  • pytest TestClient로 AC-1~11 검증; ownership + disabled 차단 + admin 분기 시나리오