feat(req-013): add portfolio-list-user-required requirement and batch
- Add REQ-013: Portfolio list filtered by user requirement with acceptance criteria - Add DCY-003 discovery document for portfolio list user filtering - Create BAT-003 batch with planning, design, implementation, and verification - Enhance app/cli/commands/portfolio.py with user-based list filtering - Add comprehensive tests for portfolio list CLI command with user filtering - Update docs indices (discovery, srs, batches) - Improve README with latest capability status
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# REQ-013: CLI `portfolio list --user` 필수화 및 소유자 기반 조회
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- Priority: Medium
|
||||
- Owner: repository-maintainers
|
||||
|
||||
## Intent
|
||||
- CLI `pfhub portfolio list`는 현재 `--user` 옵션이 없어 `owner_user_id=None`으로 호출되며 전체 포트폴리오를 반환한다. 이 동작은 소유자 구분 없이 DB 전체를 노출하는 문제가 있다.
|
||||
- `--user <username>` 옵션을 필수로 지정하여 CLI 실행 시 항상 특정 사용자의 포트폴리오만 조회하도록 강제한다.
|
||||
- username을 `owner_user_id`(UUID)로 변환하는 로직을 CLI 내부에 추가하여, `PortfolioService.list_portfolios` 호출 시 소유자 필터가 항상 적용되게 한다.
|
||||
|
||||
## Requirement
|
||||
- CLI `pfhub portfolio list` 명령은 `--user <username>` 옵션을 필수로 받아야 한다.
|
||||
- `--user` 없이 실행하면 오류 메시지를 출력하고 exit code 1로 종료해야 한다.
|
||||
- `--user`로 전달된 username을 user repository(`get_user_by_username`)로 조회하여 `owner_user_id`(UUID)를 얻고, 이를 `PortfolioService.list_portfolios(owner_user_id=...)` 호출에 전달해야 한다.
|
||||
- 존재하지 않는 username이 전달되면 기존 CLI 오류 출력 형식(Rich Console 또는 typer.echo)과 일관된 오류 메시지를 출력하고 비정상 종료해야 한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
1. Given `--user` 옵션 없이 `pfhub portfolio list`를 실행할 때, When 명령이 실행되면, Then 오류 메시지("--user 옵션이 필요합니다" 또는 동등한 내용)가 출력되고 exit code 1로 종료된다.
|
||||
2. Given 유효한 username `alice`로 `pfhub portfolio list --user alice`를 실행할 때, When 명령이 실행되면, Then `alice`의 `owner_user_id`로 필터된 포트폴리오 목록만 반환되고 다른 사용자 소유 포트폴리오는 포함되지 않는다.
|
||||
3. Given 존재하지 않는 username으로 `pfhub portfolio list --user unknown`을 실행할 때, When 명령이 실행되면, Then "사용자를 찾을 수 없습니다" 형태의 오류 메시지가 출력되고 exit code 1로 종료된다.
|
||||
4. Given in-memory 모드(`pfhub_DB_ENABLED=false`)에서 `pfhub portfolio list --user alice`를 실행할 때, When 명령이 실행되면, Then DB 모드와 동일하게 `alice` 소유 포트폴리오만 반환된다.
|
||||
5. Given 오류 발생 시, When 오류 메시지가 출력될 때, Then 메시지 형식은 기존 CLI 오류 출력 형식(Rich Console stderr 또는 typer.echo)과 일관성을 유지한다.
|
||||
|
||||
## Impacted Area
|
||||
- Docs:
|
||||
- `README.md` — `pfhub portfolio list` 예제 라인에 `--user <username>` 옵션 추가 및 breaking change 안내
|
||||
- Modules:
|
||||
- `app/cli/commands/portfolio.py` — `list_portfolios` 명령 시그니처에 `--user` 필수 옵션 추가, username → owner_user_id 변환 로직 추가, `PortfolioService.list_portfolios` 호출 시 `owner_user_id` 전달
|
||||
- `app/repositories/portfolio_repository.py` — `get_user_by_username` Protocol stub 기존 존재 확인(line 16), 추가 변경 불필요
|
||||
- `app/repositories/postgres.py` — `get_user_by_username` 기존 구현 확인(line 419), 추가 변경 불필요
|
||||
- Tests:
|
||||
- `tests/test_cli.py` — AC 1~5 커버 테스트 케이스 추가:
|
||||
- `test_cli_portfolio_list_without_user_exits_error`
|
||||
- `test_cli_portfolio_list_with_valid_user_filters_by_owner`
|
||||
- `test_cli_portfolio_list_with_unknown_user_exits_error`
|
||||
- `test_cli_portfolio_list_in_memory_mode_works`
|
||||
|
||||
## Notes
|
||||
- `PortfolioService.list_portfolios` 시그니처는 변경하지 않는다. CLI 호출부에서만 `owner_user_id`를 전달한다 (A-3, dcy-003).
|
||||
- HTTP API `GET /portfolios`의 접근 통제는 이번 REQ 범위 밖이다 (Out of Scope).
|
||||
- `--all` 관리자 전체 조회 옵션은 이번 REQ에 포함하지 않는다. 후속 Discovery로 분리한다.
|
||||
- username → owner_user_id 변환은 `repository.get_user_by_username(username)` 직접 호출로 구현한다. `UserService`에는 해당 메서드가 없음을 확인하였다.
|
||||
- 기존 `_with_service` 헬퍼는 `PortfolioService`만 생성한다. username 조회를 위해 별도로 repository를 직접 사용하거나 `_with_service` callback 안에서 repository 접근이 필요하다. 구현 시 `app_context.repository_factory(settings)` 반환 객체를 통해 `get_user_by_username`을 호출하는 방식으로 처리한다.
|
||||
- Source Discovery: [dcy-003](../../discovery/dcy-003_20260502_portfolio-list-user-required.md)
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260502-03
|
||||
- Date: 2026-05-02
|
||||
- Author: repository-maintainers
|
||||
|
||||
#### Change Summary
|
||||
- Status Approved → Implemented. BAT-003(release-candidate) verification evidence 확인 완료.
|
||||
|
||||
#### Intent
|
||||
- confirm-req-implemented 실행. AC 1~5 전원 evidence 연결 확인, Blocking Issues 없음.
|
||||
|
||||
#### Evidence Batch
|
||||
- Batch: BAT-003 (release-candidate)
|
||||
- Verification: docs/batches/bat-003_20260502_portfolio-list-user-required/verification.md
|
||||
- Test result: 41 passed (pytest tests/test_cli.py)
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: 없음
|
||||
- Modules: 없음
|
||||
- Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: BAT-003 (release-candidate)
|
||||
- Releases: none (draft-release 대기 중)
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: draft-release
|
||||
|
||||
### CHG-20260502-02
|
||||
- Date: 2026-05-02
|
||||
- Author: repository-maintainers
|
||||
|
||||
#### Change Summary
|
||||
- Status Proposed → Approved. 승인 게이트 통과. 필수 필드, AC 5개, Impacted Area, Change Log 모두 충족.
|
||||
|
||||
#### Intent
|
||||
- confirm-req 실행으로 구현 delivery 입력 준비 확정.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added: 없음
|
||||
- Updated: 없음
|
||||
- Removed: 없음
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs: 없음
|
||||
- Modules: 없음
|
||||
- Tests: 없음
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: batch 생성 진행 (draft-batch)
|
||||
|
||||
### CHG-20260502-01
|
||||
- Date: 2026-05-02
|
||||
- Author: repository-maintainers
|
||||
|
||||
#### Change Summary
|
||||
- REQ-013 최초 생성 (Proposed). dcy-003 FR-1, FR-2, FR-3 통합. NFR-1, NFR-2는 AC 5에 흡수.
|
||||
|
||||
#### Intent
|
||||
- dcy-003 확정 Discovery를 REQ backlog로 정규화.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
- Added:
|
||||
- AC 1~5 신규 작성
|
||||
|
||||
#### Impacted Area Delta
|
||||
- Docs:
|
||||
- README.md breaking change 안내 추가 항목
|
||||
- Modules:
|
||||
- app/cli/commands/portfolio.py 신규 변경
|
||||
- Tests:
|
||||
- tests/test_cli.py 4개 테스트 케이스 신규 추가
|
||||
|
||||
#### Delivery Trace Delta
|
||||
- Batches: none (batch 미생성)
|
||||
- Releases: none
|
||||
|
||||
#### Revalidation Impact
|
||||
- Reverification Needed: no
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: confirm-req 실행 후 batch 계획 수립
|
||||
+5
-1
@@ -74,7 +74,7 @@
|
||||
|
||||
## Next Requirement ID
|
||||
|
||||
- Current: `REQ-013`
|
||||
- Current: `REQ-014`
|
||||
- Rule: `Requirement Register`에 있는 가장 큰 REQ 번호보다 정확히 1 커야 한다.
|
||||
|
||||
## Requirement Register
|
||||
@@ -93,9 +93,13 @@
|
||||
| REQ-010 | credential_payload Fernet 암호화 및 startup validation | Non-Functional | Approved | High | repository-maintainers | [REQ-010](./Non-Functional/req-010_credential-payload-fernet-encryption.md) |
|
||||
| REQ-011 | trex-basic 계약 반영을 위한 baseline 문서 갱신 | Documentation | Approved | Medium | repository-maintainers | [REQ-011](./Documentation/req-011_baseline-docs-update-for-trex-basic-contract.md) |
|
||||
| REQ-012 | service-token rotate CLI 명령 구현 | Interface | Approved | Medium | repository-maintainers | [REQ-012](./Interface/req-012_service-token-rotate-cli.md) |
|
||||
| REQ-013 | CLI `portfolio list --user` 필수화 및 소유자 기반 조회 | Interface | Implemented | Medium | repository-maintainers | [REQ-013](./Interface/req-013_portfolio-list-user-required.md) |
|
||||
|
||||
## Recent Change Log Summary
|
||||
|
||||
- 2026-05-02: REQ-013 Implemented 전환 — BAT-003 verification evidence 확인 (41 passed)
|
||||
- 2026-05-02: REQ-013 Approved 전환 — CLI `portfolio list --user` 필수화 및 소유자 기반 조회 (source Discovery: dcy-003)
|
||||
- 2026-05-02: REQ-013 Proposed 생성 — CLI `portfolio list --user` 필수화 및 소유자 기반 조회 (source Discovery: dcy-003)
|
||||
- 2026-05-02: REQ-012 Approved 직행 (minor-change) — service-token rotate CLI 명령 구현
|
||||
- 2026-05-02: REQ-011 Approved 전환 — trex-basic 계약 반영을 위한 baseline 문서 갱신 (source Discovery: dcy-002)
|
||||
- 2026-05-02: REQ-010 Approved 전환 — credential_payload Fernet 암호화 및 startup validation (source Discovery: dcy-002)
|
||||
|
||||
Reference in New Issue
Block a user