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:
@@ -1766,6 +1766,36 @@ class PostgresPortfolioRepository:
|
||||
if cur.rowcount == 0:
|
||||
raise ValueError(f"portfolio를 찾을 수 없습니다: {portfolio_id}")
|
||||
|
||||
def append_asset_tag_id(self, asset_id: str, tag_id: str) -> None:
|
||||
self.ensure_schema()
|
||||
with self._connect().cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
UPDATE assets
|
||||
SET tag_ids = array_append(tag_ids, %s::uuid)
|
||||
WHERE asset_id = %s AND NOT (%s::uuid = ANY(tag_ids))
|
||||
""",
|
||||
(tag_id, asset_id, tag_id),
|
||||
)
|
||||
if cur.rowcount == 0:
|
||||
cur.execute("SELECT asset_id FROM assets WHERE asset_id = %s", (asset_id,))
|
||||
if cur.fetchone() is None:
|
||||
raise ValueError(f"asset을 찾을 수 없습니다: {asset_id}")
|
||||
|
||||
def remove_asset_tag_id(self, asset_id: str, tag_id: str) -> None:
|
||||
self.ensure_schema()
|
||||
with self._connect().cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
UPDATE assets
|
||||
SET tag_ids = array_remove(tag_ids, %s::uuid)
|
||||
WHERE asset_id = %s
|
||||
""",
|
||||
(tag_id, asset_id),
|
||||
)
|
||||
if cur.rowcount == 0:
|
||||
raise ValueError(f"asset을 찾을 수 없습니다: {asset_id}")
|
||||
|
||||
def rotate_service_token(self, name: str) -> tuple[str, AuthToken]:
|
||||
from app.core.security import generate_token, hash_token, token_prefix as _token_prefix
|
||||
|
||||
|
||||
Reference in New Issue
Block a user