feat: REQ-005 assets table tag apply/remove SQL alignment (BAT-013)

- REQ-005 CHG-20260521-02 follow-up: clarify AC-1/AC-5 to target assets table
- Add append_asset_tag_id/remove_asset_tag_id on PostgresPortfolioRepository
- Replace internal calls in apply_asset_tag/remove_asset_tag routes (HTTP contract unchanged)
- 7 new regression tests: method existence, SQL target table, error branches, idempotency guard
- Update existing AC-1/AC-5 assertions to verify new methods + portfolios methods uncalled
- Documentation: runtime-flows.md flow body + change log; rel-001 includes BAT-013
- REQ-005 transition: Approved → Implemented (CHG-20260521-03) via BAT-013 verification
- Total tests: 362 → 369 passed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-22 00:04:33 +09:00
co-authored by Claude Opus 4.7
parent 9038f41010
commit 58899b1a94
15 changed files with 509 additions and 17 deletions
+3 -2
View File
@@ -158,11 +158,11 @@
- `repo.get(asset_id)` → ValueError → HTTP 404.
- `repo.get_tag_by_id(tag_id)` → None → HTTP 404.
- `not tag.is_admin_tag` → HTTP 403; `not tag.is_active` → HTTP 403.
- `repo.append_portfolio_tag_id(asset_id, tag_id)` → HTTP 200 `{"tag_id": ..., "status": "applied"}`.
- `repo.append_asset_tag_id(asset_id, tag_id)` → HTTP 200 `{"tag_id": ..., "status": "applied"}` (BAT-013에서 portfolios → assets 테이블 대상으로 정합화).
2. **DELETE /v1/assets/{asset_id}/tags/{tag_id}** (remove tag from asset — admin only):
- DB token required; admin permission.
- `repo.get(asset_id)` → ValueError → HTTP 404.
- `repo.remove_portfolio_tag_id(asset_id, tag_id)` → HTTP 200 `{"tag_id": ..., "status": "removed"}`.
- `repo.remove_asset_tag_id(asset_id, tag_id)` → HTTP 200 `{"tag_id": ..., "status": "removed"}` (BAT-013에서 portfolios → assets 테이블 대상으로 정합화).
3. **POST /v1/portfolios/{portfolio_id}/tags** (apply tag to portfolio — owner or admin):
- DB token required; trade-write or admin permission; service/client DB token → HTTP 403 (`_require_write_token`).
- `repo.get(portfolio_id)` → ValueError → HTTP 404.
@@ -449,6 +449,7 @@
## Change Log
- 2026-05-21 KST: BAT-013 (REQ-005 CHG-20260521-02) — /v1/assets/{id}/tags apply/remove SQL 대상 정합화: `repo.append_portfolio_tag_id`/`repo.remove_portfolio_tag_id` 호출을 `repo.append_asset_tag_id`/`repo.remove_asset_tag_id`로 교체. portfolios 테이블 mutation 호출은 portfolio 라우트(`/v1/portfolios/{id}/tags`) 전용으로 한정. HTTP contract 무변, BAT-012 신설 `assets.tag_ids` 컬럼이 비로소 정상 채워짐.
- 2026-05-21 KST: BAT-012 (REQ-002 / REQ-010 AC-9~12) — GET /v1/assets 흐름 재정의: 기존 token_type 분기 portfolio 조회 설명을 admin asset catalog 조회로 교체; tag_ids 배열 + archived 합성 흐름 신설(tags 마스터 is_active 조회로 비활성·미존재 tag_id를 `archived=True`로 응답).
- 2026-05-21 KST: BAT-011 (REQ-029) — ledger path migration: "POST /v1/assets/{asset_id}/ledger/trades" 흐름 → "POST /v1/portfolios/{portfolio_id}/ledger/trades"로 교체 (disabled 차단 + 인가 순서 명확화); Daemon Registry flow의 구 path 참조 갱신.
- 2026-05-21 KST: BAT-010 (REQ-032) — v1 portfolio surface 흐름 추가: "Portfolio Mutation" 흐름 신규 추가(REQ-025~028; ownership + disabled 보호 + write token 차단); "GET /v1/portfolios" token 분기 흐름 신규 추가(REQ-028); "Soft Delete and Dependent Data Preservation" 흐름 신규 추가(REQ-027; disabled 의미 + 의존 데이터 보존); POST/DELETE /v1/portfolios/{id}/tags에 disabled(409) + service/client(403) 보강(REQ-030); "GET /v1/portfolios/{id}/tags" 흐름 추가(REQ-030); "Portfolio Comment CRUD" 흐름 신규 추가(REQ-031); Source Discovery/Batch 헤더 갱신.