feat: add knowledge content search

This commit is contained in:
2026-07-30 11:02:04 +08:00
parent c2655361b5
commit d1f573108e
7 changed files with 629 additions and 8 deletions

View File

@@ -11,14 +11,16 @@ from sqlalchemy.orm import Session
from sqlalchemy.pool import StaticPool
from app.api.admin_knowledge import delete_knowledge
from app.api.admin_knowledge_lifecycle import batch_sync, batch_update_metadata, update_metadata
from app.api.admin_knowledge_lifecycle import batch_sync, batch_update_metadata, content_search, update_metadata
from app.models import Base
from app.models.admin import Admin, Role
from app.models.knowledge import (
Knowledge,
KnowledgeCard,
KnowledgeChunk,
KnowledgeManifest,
KnowledgePublishLog,
KnowledgeSection,
KnowledgeSourceSnapshot,
KnowledgeSyncJob,
KnowledgeVersion,
@@ -268,3 +270,90 @@ def test_sync_validation_failure_keeps_current_version_active():
assert item.current_version_id == previous_version_id
assert current.status == "published"
assert len(versions) == 1
def test_content_search_finds_current_sections_cards_and_chunks():
with _database() as db:
item = _knowledge(db)
version_id = item.current_version_id
section = KnowledgeSection(
knowledge_id=item.id,
version_id=version_id,
section_key="S0098",
title="三十、练习一:静水流深静心",
content="选择舒适安全的姿势,觉察呼吸和身体,不适时立即停止。",
source_start=0,
source_end=40,
sort_order=1,
content_hash="section-hash",
)
db.add(section)
db.flush()
db.add_all([
KnowledgeChunk(
knowledge_id=item.id,
version_id=version_id,
section_id=section.id,
title=section.title,
content="静水流深静心需要选择舒适安全的姿势。",
normalized_text="静水流深静心 选择舒适安全的姿势",
keywords='["静水流深静心"]',
source_start=0,
source_end=20,
sort_order=1,
content_hash="chunk-hash",
),
KnowledgeCard(
knowledge_id=item.id,
version_id=version_id,
section_id=section.id,
title=section.title,
summary="静水流深静心的摘要",
core_conclusion="回到身体觉察",
applicable_questions="静水流深静心怎么做",
inapplicable_questions="天气",
keywords='["静水流深静心"]',
risk_level="normal",
source_range="0-40",
content_hash="card-hash",
generation_rule_version="test-v1",
review_status="approved",
),
])
db.commit()
response = content_search("静水流深", includeClosed=True, page=1, pageSize=10, db=db, current_admin=_admin())
data = response["data"]
assert data["total"] == 3
assert {item["itemType"] for item in data["items"]} == {"section", "card", "chunk"}
assert data["items"][0]["sectionKey"] == "S0098"
assert data["items"][0]["hasChunks"] is True
assert data["items"][0]["canAgentUse"] is True
assert "静水流深" in data["items"][0]["snippet"]
def test_content_search_can_exclude_closed_knowledge():
with _database() as db:
item = _knowledge(db)
item.status = 0
db.add(item)
db.add(KnowledgeSection(
knowledge_id=item.id,
version_id=item.current_version_id,
section_key="S0001",
title="合一作业",
content="合一作业内容",
source_start=0,
source_end=10,
sort_order=1,
content_hash="closed-section",
))
db.commit()
included = content_search("合一", includeClosed=True, page=1, pageSize=10, db=db, current_admin=_admin())
excluded = content_search("合一", includeClosed=False, page=1, pageSize=10, db=db, current_admin=_admin())
assert included["data"]["total"] == 1
assert included["data"]["items"][0]["canAgentUse"] is False
assert excluded["data"]["total"] == 0