perf(backend): 大纲卷过滤下推 DB WHERE——list_for_project 加 volume 参数

GET /outline?volume=N 原在端点 Python 侧过滤全部章节;现把 volume 条件下推到
OutlineRepo.list_for_project 的 DB WHERE,只查该卷行(少读多余卷 + 语义正确)。
Protocol/SqlOutlineRepo/各 OutlineRepo fake 同步加 keyword-only volume;补 repo 级
下推断言测试。向后兼容:不传 volume 仍返回全部(默认 None)。
This commit is contained in:
Yaojia Wang
2026-07-08 12:34:06 +02:00
parent c22f6b41d1
commit c596a8d342
17 changed files with 1330 additions and 18 deletions

View File

@@ -264,6 +264,25 @@ async def test_get_outline_with_volume_filters_to_that_volume() -> None:
assert all(c["volume"] == 2 for c in vol2_chapters)
@pytest.mark.asyncio
async def test_outline_repo_volume_filter_pushed_into_query() -> None:
# 卷过滤下推到 repoDB WHERE而非端点 Python 侧过滤:直接调 repo 断言只回该卷。
repo = FakeOutlineReadRepo()
pid = uuid.uuid4()
repo.add_chapter(pid, volume=1, chapter_no=1, beats=["卷一·1"])
repo.add_chapter(pid, volume=1, chapter_no=2, beats=["卷一·2"])
repo.add_chapter(pid, volume=2, chapter_no=3, beats=["卷二·3"])
vol1 = await repo.list_for_project(pid, volume=1)
vol2 = await repo.list_for_project(pid, volume=2)
all_rows = await repo.list_for_project(pid)
assert [v.chapter_no for v in vol1] == [1, 2]
assert all(v.volume == 1 for v in vol1)
assert [v.chapter_no for v in vol2] == [3]
assert [v.chapter_no for v in all_rows] == [1, 2, 3]
@pytest.mark.asyncio
async def test_get_outline_returns_empty_list_when_no_outline() -> None:
project_repo = FakeProjectRepo()