Files
portfolio-hub/docs/srs/Interface/req-026_v1-portfolios-update.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

5.9 KiB

REQ-026: PATCH /v1/portfolios/{portfolio_id} 신설

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

Intent

  • v1 API에 portfolio 부분 수정 경로(PATCH /v1/portfolios/{portfolio_id})를 신설해 user/admin이 HTTP로 portfolio 속성(broker/status/name/symbol/strategy 등)을 직접 수정할 수 있도록 한다.
  • 토큰 분기 + ownership 검증을 REQ-025와 동일 패턴으로 적용해 v1 portfolio CRUD 인가 일관성을 확보한다.

Requirement

  • 신규 라우트 PATCH /v1/portfolios/{portfolio_id} (Bearer 인증 필수).
  • 토큰 분기 규칙 (REQ-025 + dcy-003 OQ-2/OQ-5 결정과 정합):
    • token_type ∈ {service, client} → HTTP 403 fail-closed.
    • 그 외(token_type=session 또는 env token):
      • permission='admin' → 모든 portfolio 수정 가능.
      • permission ∈ {read, trade-write} → 자기 소유(owner_user_id = auth.user_id) portfolio만 수정 가능, 불일치 시 HTTP 403.
  • 비존재 portfolio는 HTTP 404.
  • 수정 가능 필드는 기존 UpdatePortfolioRequest 범위: broker, status, name, symbol, strategy_name, strategy_params, asset_price, managed_by_daemon_id 등.
  • disabled portfolio 보호 (REQ-027 soft delete 정책 정합): portfolios.status == 'disabled'인 portfolio에 대해 status 전이('enabled'로 복구) 외 다른 필드 변경 시 HTTP 409 또는 422로 거부.
  • 응답: HTTP 200 + 갱신된 PortfolioItem.

Acceptance Criteria

  1. Given admin token + 본인 또는 타 user portfolio, When PATCH /v1/portfolios/{id} body {"strategy_name": "..."}, Then HTTP 200 + 갱신된 portfolio 반환.
  2. Given session/env token with permission ∈ {read, trade-write} + 본인 portfolio, When PATCH /v1/portfolios/{id}, Then HTTP 200 + 갱신된 portfolio.
  3. Given session/env token with permission ∈ {read, trade-write} + 타 user portfolio, When PATCH /v1/portfolios/{id}, Then HTTP 403 (ownership 불일치).
  4. Given service token, When PATCH /v1/portfolios/{id}, Then HTTP 403 fail-closed.
  5. Given client token(폐지 전), When PATCH /v1/portfolios/{id}, Then HTTP 403 fail-closed.
  6. Given Bearer token 없음, When PATCH /v1/portfolios/{id}, Then HTTP 401.
  7. Given 비존재 portfolio_id, When PATCH /v1/portfolios/{id}, Then HTTP 404.
  8. Given status='disabled' portfolio + body {"strategy_name": "..."}(status 외 필드), When PATCH, Then HTTP 409 또는 422 (disabled write 차단).
  9. Given status='disabled' portfolio + body {"status": "enabled"} (admin), When PATCH, Then HTTP 200 + status 복구.

Impacted Area

  • Docs:
    • docs/interface-contract.md — PATCH /v1/portfolios/{id} 명세 추가 (REQ-032)
    • docs/runtime-flows.md — portfolio update flow + ownership 검증 + disabled 보호 (REQ-032)
  • Modules:
    • app/api/v1_portfolios.py — PATCH 라우트 추가 (REQ-025의 인증 헬퍼 재사용)
    • app/schemas/v1.py — PortfolioUpdateRequest 신규 (기존 UpdatePortfolioRequest 재사용 또는 v1 전용 래핑)
    • app/services/portfolio_service.py:update_portfolio — 기존 메서드 재사용 + disabled 보호 검증 추가
  • Tests:
    • 신규/갱신 tests/test_v1_portfolios_crud.py — AC-1~9 검증

Notes

  • ownership 검증은 admin/user 분기 후 service 계층 또는 라우터에서 일관 처리. 본 REQ의 검증 위치는 REQ-025 catalog 검증 위치 결정과 함께 결정한다.
  • disabled portfolio 보호는 REQ-027(soft delete) 정책의 일부로, 본 REQ에서 PATCH 측면 검증을 명시. ledger trade/tag/comment 측면은 REQ-029/030/031에서 각각 처리.
  • 본 REQ는 dcy-003 FR-3 산출물이며 NFR-1/NFR-3/NFR-4를 검증 기준에 흡수.
  • Source: dcy-003 FR-3, OQ-2, OQ-5, 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-009 confirm-batch-verification 완료. tests/test_v1_portfolios_crud.py AC-1~9 전 케이스 pytest 통과 (2026-05-21, 298 PASSED).

Acceptance Criteria Delta

  • No change

Impacted Area Delta

  • No change

Delivery Trace Delta

  • Batches: BAT-009 (release-candidate)
  • Releases: TBD

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: promote-to-implemented
  • Follow-up Action: 없음

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-3 산출물.

Intent

  • v1 portfolio mutation의 부분 수정 진입점 + ownership 검증 + disabled 보호.

Acceptance Criteria Delta

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

Impacted Area Delta

  • Docs: docs/interface-contract.md, docs/runtime-flows.md (REQ-032)
  • Modules: app/api/v1_portfolios.py, app/schemas/v1.py, app/services/portfolio_service.py — 최초 지정
  • Tests: tests/test_v1_portfolios_crud.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 계획 편입; REQ-025와 동일 batch 권장

Validation Plan

  • pytest TestClient로 AC-1~9 검증; ownership·token type·disabled 보호 시나리오