fix(knowledge): query tags on json columns
This commit is contained in:
@@ -190,7 +190,7 @@ class KnowledgeDBRepository:
|
||||
count_query = count_query.where(KnowledgeEntryRecord.status == status)
|
||||
if tags:
|
||||
for tag in tags:
|
||||
tag_filter = KnowledgeEntryRecord.tags.op('@>')(f'["{tag}"]')
|
||||
tag_filter = _json_string_array_has_tag(tag)
|
||||
query = query.where(tag_filter)
|
||||
count_query = count_query.where(tag_filter)
|
||||
if q:
|
||||
@@ -347,3 +347,18 @@ class KnowledgeDBRepository:
|
||||
created_at=record.created_at,
|
||||
updated_at=record.updated_at,
|
||||
)
|
||||
|
||||
|
||||
def _json_string_array_has_tag(tag: str):
|
||||
"""建立 JSON/JSONB 皆相容的 tag filter。
|
||||
|
||||
production 的 knowledge_entries.tags 目前是 JSON 欄位,不支援 json @> text。
|
||||
這裡改用帶引號的字串比對,避免把 tag 片段誤判成完整 tag。
|
||||
"""
|
||||
escaped = (
|
||||
tag
|
||||
.replace("\\", "\\\\")
|
||||
.replace("%", "\\%")
|
||||
.replace("_", "\\_")
|
||||
)
|
||||
return KnowledgeEntryRecord.tags.cast(String).ilike(f'%"{escaped}"%', escape="\\")
|
||||
|
||||
@@ -74,6 +74,16 @@ def test_review_context_keeps_succeeded_at_owner_review_stage():
|
||||
assert updated["worker_result"]["status"] == "draft_created"
|
||||
|
||||
|
||||
def test_knowledge_tag_filter_is_json_column_compatible():
|
||||
"""knowledge_entries.tags 是 JSON 欄位時不可使用 json @> text。"""
|
||||
from src.repositories.knowledge_repository import _json_string_array_has_tag
|
||||
|
||||
compiled = str(_json_string_array_has_tag("dispatch:abc-123"))
|
||||
|
||||
assert "CAST(knowledge_entries.tags AS VARCHAR)" in compiled
|
||||
assert "@>" not in compiled
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run_once_advances_pending_dispatch_to_review_draft():
|
||||
"""pending dispatch 應推進到 succeeded + waiting_owner_review read model。"""
|
||||
|
||||
Reference in New Issue
Block a user