diff --git a/docs/batches/bat-019_20260627_assets-read-permission-and-daemon-list/verification.md b/docs/batches/bat-019_20260627_assets-read-permission-and-daemon-list/verification.md new file mode 100644 index 0000000..72eae13 --- /dev/null +++ b/docs/batches/bat-019_20260627_assets-read-permission-and-daemon-list/verification.md @@ -0,0 +1,94 @@ +# BAT-019 Verification + +- Status: draft +- Batch: BAT-019 + +## Acceptance Mapping + +### REQ-044: GET /v1/assets 권한 완화 + +- AC: read 토큰 GET /v1/assets → 200 + - Evidence: `test_v1_daemons.py::test_assets_read_token_200_regression` PASSED + - Evidence: `test_v1.py::test_v1_assets_returns_asset_list` PASSED (200, total=0) + - Evidence: `test_v1.py::test_v1_assets_env_read_token_returns_200` PASSED + - Evidence: `test_v1.py::test_v1_assets_user_token` PASSED (200, total=0) + - Evidence: `test_asset_catalog.py::test_get_v1_assets_user_token_returns_200` PASSED + - Evidence: `test_asset_catalog.py::test_get_v1_assets_service_token_returns_200` PASSED + +- AC: admin GET 200(회귀) + - Evidence: `test_v1_daemons.py::test_assets_admin_get_200_regression` PASSED + - Evidence: `test_v1.py::test_v1_assets_admin_token_default` PASSED + - Evidence: `test_asset_catalog.py::test_get_v1_assets_admin_returns_catalog_response` PASSED + +- AC: status·market 필터 유지 + - Evidence: `test_v1.py::test_v1_assets_market_filter` PASSED (read 토큰 + market=KRX → 1개 반환) + - Evidence: `test_asset_catalog.py::test_get_v1_assets_market_filter` PASSED + - Evidence: `test_asset_catalog.py::test_get_v1_assets_status_filter_all_includes_inactive` PASSED + - Evidence: `test_asset_catalog.py::test_get_v1_assets_status_filter_inactive_only` PASSED + - Evidence: `test_asset_catalog.py::test_get_v1_assets_status_filter_default_active_only` PASSED + +- AC: read 토큰 쓰기 403 + - Evidence: `test_v1_daemons.py::test_assets_write_requires_admin_regression` PASSED (POST /v1/assets read → 403) + - Evidence: `test_asset_catalog.py::test_asset_http_non_admin_403` PASSED (POST /v1/assets read → 403) + +- AC: 무토큰 401 + - Evidence: `test_v1_daemons.py::test_assets_no_token_returns_401_regression` PASSED + - Evidence: `test_v1.py::test_v1_assets_requires_service_token` PASSED + - Evidence: `test_asset_catalog.py::test_get_v1_assets_no_token_returns_401` PASSED + +### REQ-045: GET /v1/daemons 신규 엔드포인트 + +- AC: 사용자A(데몬2) → 자기 2개만 + - Evidence: `test_v1_daemons.py::test_daemons_returns_caller_owned_daemons` PASSED + +- AC: 필드 4개(id, daemon_slug, display_name, is_active) 포함 + - Evidence: `test_v1_daemons.py::test_daemons_response_has_required_fields` PASSED + +- AC: 사용자B 데몬 비노출 + - Evidence: `test_v1_daemons.py::test_daemons_does_not_expose_other_user_daemons` PASSED (list_daemons_for_user("user-1") 호출 검증) + +- AC: 데몬 없으면 빈 목록 200 + - Evidence: `test_v1_daemons.py::test_daemons_empty_list_returns_200` PASSED + +- AC: 무토큰 401 + - Evidence: `test_v1_daemons.py::test_daemons_no_token_returns_401` PASSED + +- AC: admin도 caller 스코프 + - Evidence: `test_v1_daemons.py::test_daemons_admin_token_with_user_id_returns_caller_daemons` PASSED (admin user_id="admin-1" → admin-1 소유만) + - Evidence: `test_v1_daemons.py::test_daemons_admin_token_with_user_id_none_returns_empty` PASSED (env admin 토큰 user_id=None → 빈 목록) + +### Design 결정 AC 검증 + +- OQ-2 경로: GET /v1/daemons 사용 확인 (라우터 prefix="/v1", path="/daemons") +- OQ-3 스키마: DaemonListResponse{daemons: [...], total: int} 사용 확인 +- env토큰 처리: user_id=None → 빈 목록 200 (`test_daemons_admin_token_with_user_id_none_returns_empty` PASSED) +- active 필터: 소유 전체 반환, is_active로 구분 (`test_daemons_includes_inactive_daemons` PASSED) + +## Evidence + +- Test: + - 전체 실행: `pytest tests/ -v` + - 결과: **472 passed, 0 failed, 11 warnings** (2026-06-27) + - 신규 테스트: `tests/test_v1_daemons.py` 13개 전부 PASSED + - 업데이트된 테스트: `test_v1.py` 5개, `test_asset_catalog.py` 2→3개, `test_daemon_assignment.py` 2개, `test_tags_master.py` 3개 + - 기존 v1_assets 회귀: 0 (모두 PASSED) + - 기존 auth 회귀: 0 (모두 PASSED) + +``` +pytest 실행 원문 마지막 줄: +====================================================== 472 passed, 11 warnings in 24.83s ====================================================== +``` + +- Manual: + - 없음 (DB 연결 없는 환경에서 mock 기반 단위 테스트로 모든 AC 커버) + +- Logs: + - 없음 + +## Result + +- Ready for Release: false +- Blocking Issues: + - 없음 (모든 AC 충족, 테스트 전체 통과) + - DB 통합 테스트는 로컬 인프라 필요(비활성 환경) — mock 기반 커버로 대체 + - `confirm-batch-verification` 팀장 승인 대기 diff --git a/docs/batches/index.md b/docs/batches/index.md index c578c59..c46a2cb 100644 --- a/docs/batches/index.md +++ b/docs/batches/index.md @@ -26,3 +26,4 @@ | BAT-016 | standard | released | REQ-036, REQ-037, REQ-038 | dcy-006 | [bat-016](./bat-016_20260605_ledger-accounting-consolidation/) | | BAT-017 | standard | released | REQ-039, REQ-040, REQ-041, REQ-042 | dcy-007 | [bat-017](./bat-017_20260618_trade-history-and-pnl-api/) | | BAT-018 | batch-lite | release-candidate | REQ-043 | dcy-008 | [bat-018](./bat-018_20260625_holdings-cost-basis-endpoint/) | +| BAT-019 | standard | in-delivery | REQ-044, REQ-045 | dcy-009 | [bat-019](./bat-019_20260627_assets-read-permission-and-daemon-list/) |