Files
xsl 4764235343 fix(retrieval): list_gaps returns ORM entities; admin switches back to the domain API
T12 集成实测暴露:select(KbGap) 的结果调 .mappings(),行键是实体类,
GapSummary 按列名取值必然 AttributeError。改为 .scalars() 返回实体;
admin 的缺口看板从临时自实现切回 retrieval.list_gaps(语义单一定义)。
2026-08-14 21:22:51 +08:00

44 lines
1.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""知识缺口看板路由(FR-ADM-05):被问到却没有答案的查询,按热度排序。
数据来自检索无结果时的自动埋点(T-P2-06),看板只读:它回答「下一批内容
该生产什么」,是内容排期的输入,不是待办队列。
数据访问走 retrieval 域的 ``list_gaps``(T12 开发时它有个 mappings 误用
的缺陷,当时在 admin 内自实现了等价查询;上游已在合并阶段修复,现切回,
缺口语义只有一处定义)。
"""
from __future__ import annotations
from typing import Any
from fastapi import APIRouter, Depends, Query
from apps.admin.deps import SessionDep, admin_auth
from apps.admin.schemas import GapOut
from packages.retrieval import service as retrieval_service
from packages.shared.response import ok
router = APIRouter(prefix="/kb", tags=["admin:gaps"], dependencies=[Depends(admin_auth)])
@router.get("/gaps", summary="知识缺口列表(hit_count 降序:最常被问到的排最前)")
async def list_gaps(
session: SessionDep,
limit: int = Query(default=50, ge=1, le=200),
offset: int = Query(default=0, ge=0),
) -> dict[str, Any]:
summaries = await retrieval_service.list_gaps(session, limit=limit, offset=offset)
items = [
GapOut(
gap_id=str(g.gap_id),
query_text=g.query_text,
filter_ctx=dict(g.filter_ctx),
hit_count=g.hit_count,
first_seen_at=g.first_seen_at,
last_seen_at=g.last_seen_at,
).model_dump()
for g in summaries
]
return ok({"items": items, "total": len(items), "limit": limit, "offset": offset})