Files
skelet/docs/review/phase2-review.md
T

9.2 KiB
Raw Blame History

Phase 2 前台 MVP 评审

评审日期:2026-07-06
评审角色:全栈开发工程师
评审对象:DeepSeek 完成的 Phase 2(T-201 至 T-206)

结论

Phase 2 暂不达标。

基础页面、首页、项目详情、文章详情等主要页面已经可访问,自动化测试也通过;但筛选搜索的组合参数存在 500 错误,且场景页没有实现任务详单要求的分页。因此不能把 Phase 2 视为完整验收通过。

阻断问题

P0:项目列表 min_score + q 组合筛选会 500

  • 影响任务:T-204
  • 位置:core/models.py:151 至 core/models.py:162
  • 现象:min_score 合法时,代码把 projects 从 QuerySet 转成 list;后续如果同时存在 q,继续调用 projects.filter(...),触发 AttributeError: 'list' object has no attribute 'filter'。
  • 复现:
.venv/bin/python3.12.exe manage.py shell -c "from django.test import Client; c=Client(raise_request_exception=False); print(c.get('/projects/?min_score=18&q=Django').status_code)"

实际结果:500

任务契约要求 language / framework / database / min_score / q / page 多参数同时出现时按 AND 组合,见 docs/04-architecture.md:157 至 docs/04-architecture.md:161。当前实现只覆盖了单项筛选测试,没有覆盖组合筛选,见 core/tests.py:119 至 core/tests.py:136。

建议修复方向:

  • 保持筛选链路的数据类型一致。
  • 可以先用 ORM 对 q、language、framework、database 过滤,再对 min_score 做 Python 层过滤;也可以用 annotation 计算总分后在 ORM 层过滤。
  • 增加组合筛选测试,例如 /projects/?language=python&framework=django&min_score=18&q=Django。

P1:场景页未实现分页

  • 影响任务:T-203
  • 位置:core/models.py:32 至 core/models.py:40,core/templates/core/scenario_page.html:7 至 core/templates/core/scenario_page.html:27
  • 现象:场景页直接把全部匹配项目放进 context["projects"],模板也没有分页控件。
  • 任务详单要求:场景页只列 live 项目,分页每页 20,空场景渲染空状态。

当前只满足 live 项目和空状态;分页缺失。已有测试只验证有项目和空状态,未验证超过 20 条时分页行为,见 core/tests.py:40 至 core/tests.py:75。

建议修复方向:

  • 在 ScenarioPage.get_context() 中使用 Paginator(projects, 20)。
  • 支持非法 page 回退到第一页,行为和项目列表页一致。
  • 在 scenario_page.html 复用项目列表页的分页 UI。
  • 增加 21 个项目的场景页分页测试。

非阻断问题

P2:docs/current-state.md 测试数量已过期

  • 位置:docs/current-state.md:19
  • 现象:文档写的是 home/tests.py 5 个、core/tests.py 17 个;实际 manage.py test 输出为 31 个测试。
  • 影响:不影响运行,但会误导后续 agent 判断当前状态。

建议修复:更新当前快照里的测试数量。

P2:文章列表实现偏薄,但可接受

  • 影响任务:T-206
  • 位置:core/templates/core/article_index_page.html:7 至 core/templates/core/article_index_page.html:13
  • 现状:文章列表通过 page.get_children.live 直接渲染标题链接,没有自定义 get_context(),也没有分页。
  • 评估:T-206 只要求文章可访问、文章详情可链接项目详情;当前能满足最低验收。后续内容量增长时建议补排序、摘要和分页。

逐任务验收

任务 结论 说明
T-201 基础页面框架 达标 base.html 有 viewport meta,导航、页脚、基础 CSS 已实现,容器使用 max-width 和响应式宽度。
T-202 首页 达标 首页展示场景入口、推荐骨架、最新文章,内容来自数据库上下文。
T-203 场景页和项目列表页 未达标 项目列表页有分页和空状态;场景页有项目和空状态,但缺少每页 20 的分页。
T-204 筛选与基础搜索 未达标 单项筛选可用,但 min_score 与 q 组合请求返回 500,不符合 AND 组合契约。
T-205 骨架详情页 达标 展示详情字段、评分、推荐理由,is_sponsored=True 时渲染 Sponsored 标识。
T-206 文章列表和详情 达标 /articles/ 和文章详情可访问,文章详情可链接关联项目;实现较薄但满足最低验收。

验证记录

已执行:

.venv/bin/python3.12.exe manage.py check
.venv/bin/python3.12.exe manage.py makemigrations --check --dry-run
.venv/bin/python3.12.exe manage.py test
.venv/bin/python3.12.exe manage.py shell -c "from core.models import ScenarioPage,SkeletonProjectPage,ArticlePage; print(ScenarioPage.objects.live().count(), SkeletonProjectPage.objects.live().count(), ArticlePage.objects.live().count())"
.venv/bin/python3.12.exe manage.py shell -c "from django.test import Client; c=Client(raise_request_exception=False); paths=['/','/projects/','/articles/','/projects/?language=python','/projects/?min_score=18','/projects/?q=Django','/projects/?min_score=18&q=Django']; [print(p, c.get(p).status_code) for p in paths]"

结果摘要:

  • manage.py check:0 error,9 个 treebeard/Wagtail 兼容 warning。
  • makemigrations --check --dry-run:No changes detected。
  • manage.py test:31 tests passed。
  • seed 数据:3 个 live 场景、5 个 live 项目、2 篇 live 文章。
  • URL 补测:
    • /:200
    • /projects/:200
    • /articles/:200
    • /projects/?language=python:200
    • /projects/?min_score=18:200
    • /projects/?q=Django:200
    • /projects/?min_score=18&q=Django:500

修复验收建议

修复后至少补充并通过以下测试:

  1. 项目列表组合筛选:language + framework + database + min_score + q 同时存在时返回 200,并只展示满足全部条件的项目。
  2. 项目列表组合筛选无结果时返回 200,并展示空状态。
  3. 场景页 21 个 live 项目时第一页展示 20 个,第二页展示剩余项目。
  4. 场景页非法 page 参数返回第一页,不报错。

修复完成后重新运行:

.venv/bin/python3.12.exe manage.py check
.venv/bin/python3.12.exe manage.py makemigrations --check --dry-run
.venv/bin/python3.12.exe manage.py test

2026-07-06 修复复查

复查对象:提交 714d218 Phase 2 评审修复: P0 min_score+&q=500 (ORM→list 顺序) + P1 场景分页(20/page) + P2 文档同步 + 36 tests

复查结论:原 Phase 2 阻断问题 已达标,Phase 2 当前可视为通过复查。

复查结果

原问题 状态 证据
P0:项目列表 min_score + q 组合筛选会 500 已达标 ProjectIndexPage.get_context() 先执行 q ORM 过滤,再做 min_score Python 过滤;/projects/?min_score=18&q=Django 复测返回 200。
P1:场景页未实现分页 已达标 ScenarioPage.get_context() 已使用 Paginator(projects, 20);scenario_page.html 已渲染分页控件;新增 21 条项目分页测试。
P2:docs/current-state.md 测试数量已过期 已达标 当前快照已更新为 31 个测试基线;修复后实际测试为 36 个。
P2:文章列表实现偏薄 可接受 该项原本非阻断,当前未要求扩展;仍满足 T-206 最低验收。

代码核对

  • core/models.py:32 至 core/models.py:46:场景页项目列表已分页,非法页码和越界页码回退第一页。
  • core/models.py:151 至 core/models.py:168:项目列表筛选顺序已调整,q 不再在 list 上调用 .filter()。
  • core/templates/core/scenario_page.html:26 至 core/templates/core/scenario_page.html:36:场景页已展示分页导航。
  • core/tests.py:78 至 core/tests.py:116:新增场景页分页测试。
  • core/tests.py:178 至 core/tests.py:190:新增组合筛选与空状态测试。

复查验证命令

已执行:

.venv/bin/python3.12.exe manage.py check
.venv/bin/python3.12.exe manage.py makemigrations --check --dry-run
.venv/bin/python3.12.exe manage.py test
.venv/bin/python3.12.exe manage.py shell -c "from django.test import Client; from core.models import ScenarioPage,SkeletonProjectPage,ArticlePage; c=Client(raise_request_exception=False); scenario=ScenarioPage.objects.live().first(); paths=['/projects/?min_score=18&q=Django','/projects/?language=python&framework=django&min_score=18&q=Django','/projects/?language=go&framework=django&min_score=18', scenario.url, scenario.url+'?page=2', scenario.url+'?page=abc']; print('counts', ScenarioPage.objects.live().count(), SkeletonProjectPage.objects.live().count(), ArticlePage.objects.live().count()); [print(p, c.get(p).status_code) for p in paths]"

结果摘要:

  • manage.py check:0 error,9 个 treebeard/Wagtail 兼容 warning。
  • makemigrations --check --dry-run:No changes detected。
  • manage.py test:36 tests passed。
  • seed 数据:3 个 live 场景、5 个 live 项目、2 篇 live 文章。
  • URL 复测:
    • /projects/?min_score=18&q=Django:200
    • /projects/?language=python&framework=django&min_score=18&q=Django:200
    • /projects/?language=go&framework=django&min_score=18:200
    • /scenarios/modern-desktop-app-templates/:200
    • /scenarios/modern-desktop-app-templates/?page=2:200
    • /scenarios/modern-desktop-app-templates/?page=abc:200