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

16 KiB
Raw Blame History

Phase 3 SEO 与上线准备评审

评审日期:2026-07-06
评审角色:全栈开发工程师
评审对象:DeepSeek 当前 Phase 3 改动

结论

Phase 3 未达标。

当前工作区只看到 T-301 的部分 SEO/sitemap 改动,任务看板也仍显示 T-301 为 DOING,T-302、T-303、T-305、T-304 均为 TODO。从 Phase 3 全部任务角度看,部署文档、SQLite 上线检查、访问统计、MVP 完整验收都没有完成。

阻断问题

P0:Phase 3 任务未完成,不能按“全部任务”验收

  • 影响任务:T-301、T-302、T-303、T-305、T-304
  • 位置:docs/06-tasks.md:53 至 docs/06-tasks.md:57
  • 现象:
    • T-301 仍是 DOING。
    • T-302/T-303/T-305/T-304 仍是 TODO。
    • progress.md 没有 Phase 3 完成记录。
    • docs/current-state.md 仍停留在 Phase 2 快照。

这说明 DeepSeek 当前提交并没有完成 Phase 3 的所有任务。

P0:T-301 只完成了 sitemap,核心页面缺少 meta description/canonical

  • 影响任务:T-301
  • 位置:skelet/templates/base.html:16 至 skelet/templates/base.html:18
  • 现象:模板只有在 page.search_description 存在时才输出 <meta name="description">,但当前核心页面的 search_description 均为空。
  • 复测页面:
    • /
    • /projects/
    • /scenarios/crm/
    • /projects/djangocrm/
    • /articles/

复测结果:上述页面均返回 200,但均未输出 <meta name="description">,也没有 rel="canonical"。

任务要求是“核心页面有 title、description、canonical 或等价设置;sitemap 可用”。当前只有 title 和 sitemap 可用,description/canonical 未达标。

建议修复方向:

  • 为种子页面写入 search_description,或在模板层提供可解释的 fallback description。
  • 明确 canonical 的处理方式:输出 <link rel="canonical" href="...">,或在文档中说明采用的 Wagtail 等价机制并用测试覆盖。
  • 增加测试断言首页、项目详情页、场景页、文章页含 meta description,并断言 sitemap 含项目 URL。

P1:根目录 test_sitemap.py 是非规范测试文件,导入即写数据库并发请求

  • 影响任务:T-301 / 验证基线
  • 位置:test_sitemap.py:1 至 test_sitemap.py:17
  • 现象:
    • 文件位于仓库根目录,命名匹配 Django test discovery。
    • 模块顶层直接执行 django.setup()、Site.objects.get_or_create(...) 和 Client().get("/sitemap.xml")。
    • manage.py test 运行时会打印 Site created/updated、sitemap.xml: 200 等输出。

这不是稳定的测试写法。测试发现阶段导入模块就修改数据库,会污染开发数据库,也会让测试基线依赖导入副作用。

建议修复方向:

  • 删除根目录 test_sitemap.py。
  • 把 sitemap 验证迁移到 core/tests.py 或新的 app 测试文件中,使用 TestCase 和断言。

P1:T-302 部署文档未完成

  • 影响任务:T-302
  • 当前事实:仓库只有早前的 docs/deployment/environment-assessment.md,它是 Lightsail 环境评估,不是可复制执行的部署手册。
  • 缺口:
    • 没有完整 Gunicorn systemd service 示例。
    • 没有 Nginx server block 示例。
    • 没有静态文件、media、环境变量、迁移、superuser、备份、重启/回滚步骤。

T-302 要求“2 核 2G VPS 上 Gunicorn + Nginx + SQLite 的部署步骤清楚”,当前未满足。

P1:T-303 SQLite 上线检查未完成

  • 影响任务:T-303
  • 缺口:
    • 未记录 JSON1 验证命令和结果。
    • 未记录 WAL 启用命令和 PRAGMA journal_mode; 证据。
    • 未记录备份策略。
    • 未记录迁移 PostgreSQL 的触发条件。

任务要求这些内容写入部署文档;当前没有。

P1:T-305 访问统计与外链点击未接入

  • 影响任务:T-305
  • 复查方式:搜索 Plausible、Umami、analytics、onclick、data-analytics、click。
  • 结果:代码没有轻量统计脚本,没有外链点击事件标记或处理逻辑。

T-305 未实现。

P1:T-304 MVP 完整验收未完成

  • 影响任务:T-304
  • 原因:T-303 和 T-305 仍未完成,T-304 的依赖不满足;也没有看到 02-requirements.md P0 完整验收记录。

T-304 未达标。

已完成部分

Sitemap 基础可用

  • 位置:
    • skelet/settings/base.py:56 至 skelet/settings/base.py:58
    • skelet/urls.py:18 至 skelet/urls.py:23
    • skelet/sitemaps.py:1 至 skelet/sitemaps.py:22
  • 复测:/sitemap.xml 返回 200,并包含项目、文章、场景 URL。

这一部分满足 T-301 的 sitemap 子项。

逐任务验收

任务 结论 说明
T-301 补 SEO 基础 未达标 sitemap 可用;核心页面缺少 meta description 和 canonical;测试方式不规范。
T-302 补部署文档 未达标 没有 Gunicorn + Nginx + SQLite 的可执行部署手册。
T-303 SQLite 上线检查 未达标 没有 JSON1、WAL、备份、PostgreSQL 迁移触发条件记录。
T-305 接入轻量访问统计与外链点击记录 未达标 未接入 Plausible/Umami 或等价方案,也没有外链点击统计。
T-304 MVP 完整验收 未达标 依赖任务未完成;没有 P0 完整验收记录。

验证记录

已执行:

.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 showmigrations sites
.venv/bin/python3.12.exe manage.py shell -c "from wagtail.models import Page; qs=Page.objects.live().public().specific(); print([(p.url, bool(getattr(p, 'seo_title', '')), bool(getattr(p, 'search_description', ''))) for p in qs if p.url in ['/', '/projects/', '/scenarios/crm/', '/projects/djangocrm/', '/articles/']])"
.venv/bin/python3.12.exe manage.py shell -c "from django.test import Client; c=Client(); paths=['/','/projects/','/scenarios/crm/','/projects/djangocrm/','/articles/','/sitemap.xml']; [print(p, c.get(p).status_code, ('<meta name=\"description\"' in c.get(p).content.decode('utf-8','ignore')), ('rel=\"canonical\"' in c.get(p).content.decode('utf-8','ignore')), ('djangocrm' in c.get(p).content.decode('utf-8','ignore'))) for p in paths]"
rg -n "analytics|plausible|umami|data-analytics|onclick|click" . -g '!db.sqlite3' -g '!.venv/**' -g '!media/**'

结果摘要:

  • manage.py check:0 error,9 个 treebeard/Wagtail 兼容 warning。
  • makemigrations --check --dry-run:No changes detected。
  • manage.py test:36 tests passed,但测试发现阶段执行了根目录 test_sitemap.py 的顶层副作用并打印 sitemap 检查信息。
  • sites migration:已应用。
  • /sitemap.xml:200,包含 djangocrm。
  • 核心页面:均返回 200,但没有 meta description,也没有 canonical。
  • 访问统计/外链点击:未发现实现。

修复验收建议

  1. 先完成 T-301:补 description/canonical,删除 test_sitemap.py,把 sitemap 测试纳入正式测试。
  2. T-301 验收通过后再领取 T-302,不要一次性跨任务推进。
  3. T-302 编写可复制执行的部署手册,覆盖 systemd、Nginx、static/media、环境变量、迁移和回滚。
  4. T-303 在部署文档中补 JSON1、WAL、备份和 PostgreSQL 迁移条件,并记录验证命令。
  5. T-305 明确采用 Plausible、Umami 或等价方案,页面响应中应能看到统计脚本,外链应能被点击统计识别。
  6. 最后执行 T-304,对 docs/02-requirements.md P0 逐项验收并把证据写入 progress.md。

2026-07-07 修复复查

复查对象:提交 dcc6265 Phase 3: T-301~T-304 SEO/部署/SQLite/统计/MVP验收完成(42 tests)。

复查结论:Phase 3 仍未完全达标。
原评审中的主要功能缺口已经大部分修复:任务看板已全部标 DONE,SEO meta/canonical 已输出,根目录 test_sitemap.py 已删除,sitemap 测试已纳入 core/tests.py,Plausible 条件脚本和外链点击监听已实现。但部署指南仍包含不可执行的 WAL 命令,并写入了具体私有仓库地址,不能算 T-302/T-303 完整达标。

已达标项

原问题 状态 证据
Phase 3 任务未完成 已达标 docs/06-tasks.md:53 至 docs/06-tasks.md:57 已全部为 DONE;progress.md 已追加 Phase 3 完成记录。
T-301 只完成 sitemap,缺少 description/canonical 已达标 skelet/templates/base.html:16 至 skelet/templates/base.html:30 已输出 description fallback 和 canonical;页面复测均为 200 且含 description/canonical。
根目录 test_sitemap.py 非规范测试 已达标 根目录已无 test_sitemap.py;core/tests.py:485 至 core/tests.py:487 已包含 sitemap 测试。
T-305 访问统计与外链点击未接入 已达标 skelet/context_processors.py 暴露 Plausible 配置;base.html:51 至 base.html:63 条件加载 Plausible 并监听外链点击;设置 PLAUSIBLE_DOMAIN 后页面输出统计脚本。
T-304 MVP 完整验收记录缺失 已达标 progress.md 已记录 02-requirements.md P0 验收项。

未达标项

P1:部署指南中的 WAL 启用命令不可执行

  • 影响任务:T-303
  • 位置:docs/deployment/deployment-guide.md:130 至 docs/deployment/deployment-guide.md:142
  • 现象:文档要求在 python manage.py dbshell 中执行 .journal_mode WAL;,但 SQLite CLI 不支持该命令。
  • 复现:
printf ".journal_mode WAL\n.quit\n" | .venv/bin/python3.12.exe manage.py dbshell

实际结果:

Error: unknown command or invalid arguments:  "journal_mode". Enter ".help" for help
CommandError: "sqlite3 ... db.sqlite3" returned non-zero exit status 1.

正确方向应使用 SQL:

PRAGMA journal_mode=WAL;
PRAGMA journal_mode;

或给出可复制的非交互命令,并确认输出为 wal。当前 T-303 的“WAL 启用”步骤仍未达标。

P1:部署指南写入了具体私有仓库地址

  • 影响任务:T-302 / 仓库规则
  • 位置:docs/deployment/deployment-guide.md:21 至 docs/deployment/deployment-guide.md:23
  • 现象:文档写入 git clone http://ilaer.eicp.net:8418/opc/skelet.git /var/www/skelet。
  • 问题:AGENTS.md:47 明确要求“不写真实密钥、账号、token、私有服务地址”。该地址应改成占位符或公开仓库占位,例如:
git clone <YOUR_REPOSITORY_URL> /var/www/skelet

复查验证命令

已执行:

.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; c=Client(); paths=['/','/projects/','/scenarios/crm/','/projects/djangocrm/','/articles/','/sitemap.xml']; [print(p, c.get(p).status_code, 'desc', '<meta name=\"description\"' in c.get(p).content.decode('utf-8','ignore'), 'canonical', 'rel=\"canonical\"' in c.get(p).content.decode('utf-8','ignore'), 'djangocrm', 'djangocrm' in c.get(p).content.decode('utf-8','ignore')) for p in paths]"
PLAUSIBLE_DOMAIN=skelet.example.com .venv/bin/python3.12.exe manage.py shell -c "from django.conf import settings; from django.test import Client; c=Client(); body=c.get('/projects/djangocrm/').content.decode('utf-8','ignore'); print('plausible', 'data-domain=\"skelet.example.com\"' in body, 'https://plausible.io/js/script.js' in body, 'Outbound Link' in body)"
.venv/bin/python3.12.exe manage.py shell -c "import sqlite3; c=sqlite3.connect(':memory:'); c.execute('SELECT json(' + repr('{\"a\":1}') + ')'); print('JSON1 supported')"
printf ".journal_mode WAL\n.quit\n" | .venv/bin/python3.12.exe manage.py dbshell
.venv/bin/python3.12.exe manage.py dbshell -- -cmd "PRAGMA journal_mode=WAL;"
.venv/bin/python3.12.exe manage.py dbshell -- -cmd "PRAGMA journal_mode;"

结果摘要:

  • manage.py check:0 error,9 个 treebeard/Wagtail 兼容 warning。
  • makemigrations --check --dry-run:No changes detected。
  • manage.py test:42 tests passed。
  • 页面复测:
    • /:200,含 description/canonical。
    • /projects/:200,含 description/canonical。
    • /scenarios/crm/:200,含 description/canonical。
    • /projects/djangocrm/:200,含 description/canonical。
    • /articles/:200,含 description/canonical。
    • /sitemap.xml:200,含 djangocrm。
  • 设置 PLAUSIBLE_DOMAIN=skelet.example.com 后,页面含 Plausible 脚本和 Outbound Link 监听代码。
  • JSON1 本地验证通过。
  • 文档中的 .journal_mode WAL 命令失败;使用 PRAGMA journal_mode=WAL; 可成功输出 wal。

复查后的逐任务状态

任务 复查结论 说明
T-301 补 SEO 基础 已达标 description/canonical/sitemap 均可用,测试纳入正式测试。
T-302 补部署文档 未达标 文档主体已补齐,但包含具体私有仓库地址,违反仓库规则。
T-303 SQLite 上线检查 未达标 JSON1、备份、迁移触发条件已记录;WAL 启用命令不可执行。
T-305 接入轻量访问统计与外链点击记录 已达标 Plausible 环境变量控制脚本注入,外链点击监听存在。
T-304 MVP 完整验收 部分达标 P0 功能验收记录已补;但依赖的 T-302/T-303 仍有未达标项。

修复建议

  1. 将 docs/deployment/deployment-guide.md 中的私有仓库地址替换为占位符。
  2. 将 WAL 启用步骤改为可执行命令,例如:
python manage.py dbshell -- -cmd "PRAGMA journal_mode=WAL;"
python manage.py dbshell -- -cmd "PRAGMA journal_mode;"

并在文档里明确预期输出为 wal。

2026-07-07 再次复查

复查对象:提交 7f7a487 Phase 3 review fix: remove private repo URL, fix WAL PRAGMA syntax。

复查结论:Phase 3 已达标。
上次复查剩余的两个问题已经修复:部署指南不再包含具体私有仓库地址,WAL 启用命令已改为可执行的 PRAGMA journal_mode=WAL;。

本轮复查结果

上次未达标项 状态 证据
T-302:部署指南写入具体私有仓库地址 已达标 docs/deployment/deployment-guide.md:22 已改为 https://github.com/your-org/skelet.git 占位地址;在部署文档、AGENTS、环境样例、任务和当前状态文档中未发现私有服务地址残留。
T-303:WAL 启用命令不可执行 已达标 docs/deployment/deployment-guide.md:133 至 docs/deployment/deployment-guide.md:135 已改为 PRAGMA journal_mode=WAL;;按文档方式执行后输出 wal,验证命令也输出 wal。

再次复查验证命令

已执行:

printf "PRAGMA journal_mode=WAL;\n.quit\n" | .venv/bin/python3.12.exe manage.py dbshell
.venv/bin/python3.12.exe manage.py dbshell -- -cmd "PRAGMA journal_mode;"
rg -n "ilaer|eicp|8418|opc/skelet|tokyo\.pem|PRIVATE KEY" docs/deployment AGENTS.md .env.example README.md docs/06-tasks.md docs/current-state.md
.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

结果摘要:

  • WAL 启用命令:输出 wal。
  • WAL 验证命令:输出 wal。
  • 私有地址/凭证搜索:部署相关文档和入口文档无匹配。
  • manage.py check:0 error,9 个 treebeard/Wagtail 兼容 warning。
  • makemigrations --check --dry-run:No changes detected。
  • manage.py test:42 tests passed。

最终逐任务状态

任务 复查结论 说明
T-301 补 SEO 基础 已达标 description/canonical/sitemap 均可用,测试纳入正式测试。
T-302 补部署文档 已达标 Gunicorn + Nginx + SQLite 部署指南已补齐,私有仓库地址已替换为占位地址。
T-303 SQLite 上线检查 已达标 JSON1、WAL、备份、PostgreSQL 迁移触发条件已记录;WAL 命令已验证可执行。
T-305 接入轻量访问统计与外链点击记录 已达标 Plausible 环境变量控制脚本注入,外链点击监听存在。
T-304 MVP 完整验收 已达标 依赖任务已达标,P0 功能验收记录已写入 progress.md。