Files
cms-website/README.md
T
浅念 87d6b9a777 docs: ADR-018/README/Plan 5 移交清单
Plan 4 Task 9 收尾(阶段 4 收官):

- ADR-018(主题与构建决策八条):Astro 5.18 选型与 MIT/依赖只进主题包/
  vitest 双版本(根 2.1.9 + 主题 3.2.7——astro vite6 兼容);渲染信任链
  bodyHtml 不二次清洗(三段接力);分页 V1 不做——路由登记义务随迁移移交;
  P0 发布门禁偏离(issue 无 DB 源,Plan 5 SEO diff 重审);编码路径四层
  字节精确 + 资产键 URL 线形归一(236f3dc);预览零依赖 + host 白名单
  收紧(回环纪律,比 spec §12.2 更严);CSP style-src 'unsafe-inline'
  (Astro scoped 样式内联);报告 HTML 先写两域对齐
- README:快速开始补 publish→build→preview 全链命令链示例(含
  artifacts/jobs/<jobId>/ 产物路径);目录结构补 themes/ 与
  apps/preview-server/;当前状态阶段 4 完成(真实 hesupipe 190 页可
  浏览器预览/408 测试/23 验收断言/6 截图);ADR-001~018 导航;下一步
  指向 Plan 4 文末移交清单
- Plan 4 文档:Task 9 勾选 + 验收节 ✅ 全过;文末新增"移交 Plan 5 清单"
  7 项(SEO 三方 diff 新输入源/完整门禁六件含可复现双构建与 footer 年份
  固定化/sitemap-robots 预览可达/og 元数据/836 nginx conf 输出/Task 0.2
  备份续传/度量基线 ~64s 首跑·~15s 复跑)

三绿全量:lint 过 / typecheck 五段过 / test 408(根 382 + 主题 26)全绿。
不 push——推送由用户执行。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 15:59:48 +08:00

74 lines
6.7 KiB
Markdown
Raw 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.
# SiteForge
WordPress 站点到静态站点迁移引擎:读取 WXR/Sitemap/媒体归档 → 清洗入不可变内容库 → 主题化构建为自包含静态站点(Astro),全程可审计、可复现、契约冻结。
## 快速开始
前置:Node.js >= 22.12、Docker、[corepack](https://nodejs.org/api/corepack.html)。
```bash
corepack enable # 激活 pnpm(或自行安装 pnpm@10)
pnpm install # 安装依赖
pnpm db:up # 启动 PostgreSQL 16(宿主端口 5434,等 healthcheck 就绪)
pnpm db:migrate # 开发库全量迁移(apps/api/drizzle)
pnpm db:test # 一键验收:起库 + 跑全部测试(测试用临时库,开发库零写入)
```
`pnpm sf` CLI 速览(tsx 直吃 TS,无需构建)——阶段 2 探测/登记 → 阶段 3 导入 → 阶段 4 发布/构建/预览:
```bash
pnpm sf wxr:probe --wxr path/to/export.xml # 只读诊断:流式解析→映射→清洗→计数报告(不入库)
pnpm sf source:register --site <key> --wxr <path> [--sitemap <path>] [--media <dir>] [--media-map <json>] # 快照登记(content-addressed、幂等)
pnpm sf import --site <key> [--snapshot <id>] [--products-path /products/] [--news-path /news/] # 导入落库(幂等 job + JSON/HTML 报告)
pnpm sf content:publish --site <key> [--confirm <token>] [--actor <label>] # 显式发布(缺省 dry-run 出清单+token;--confirm 执行;导入永不发布)
pnpm sf build:create --site <key> [--key <idempotencyKey>] # 冻结 Render Snapshot 六文件 → astro 构建 → 媒体落盘/sitemap/robots → 五门禁 → 产物登记
pnpm sf preview:start --build <jobId> [--port 4173] # 路由驱动本地预览(只读 dist+route-manifest;回环绑定;X-Robots-Tag noindex)
# 全链示例(register → import → publish → build → preview;同快照/同发布集合重复执行均幂等复用)
pnpm sf source:register --site demo --wxr storage/incoming/export.xml --media storage/incoming/media --media-map storage/incoming/media-map.json
pnpm sf import --site demo # 报告落 artifacts/import/<jobId>/reports/import.{json,html}
pnpm sf content:publish --site demo # dry-run:差异清单 + confirm token(零写入)
pnpm sf content:publish --site demo --confirm <token> # published ← current + audit_logs + site_config v1
pnpm sf build:create --site demo # 产物落 artifacts/jobs/<buildJobId>/{input,dist,manifests,reports}
# input/ 六文件快照 · dist/ 页面+媒体+sitemap.xml+robots.txt+404.html
# manifests/route-manifest.json · reports/build.{json,html}(HTML 先写)
pnpm sf preview:start --build <buildJobId> # http://127.0.0.1:4173/ ——六类页面/301/资产/404 按真实路由响应
```
日常质量门(等价于 CI):
```bash
pnpm lint && pnpm typecheck && pnpm test
```
说明:集成测试由 vitest `globalSetup` 自动创建临时库 `sf_test_<ts>` 并注入 `DATABASE_URL_TEST`,结束即 DROP——勿在 `.env` 手动设置该变量。
## 目录结构
```
apps/api/ NestJS standalone 骨架 + Drizzle schema/迁移(21 表,数据库约束即规格)+ source 快照登记 + 导入管道(四写入器编排)+ 发布/构建/门禁服务
apps/preview-server/ 本地预览服务器(纯 node:http 零依赖;route-manifest 驱动;回环绑定纪律)
packages/contracts/ UniversalRow / Route / Render / Theme 跨源契约(冻结,变更须升版)
packages/adapter-wordpress/ WXR 适配器(saxes 流式解析 + PHP unserialize + 映射 + HTML 白名单清洗,纯函数无 DB)
themes/pilot-minimal/ pilot 极简主题(Astro 5 静态构建;渲染数据唯一入口 load-render-data——五禁纪律的结构保证)
tests/ 单元 + 集成测试(fixtures:WXR/Sitemap/媒体样例;临时库 globalSetup)
infra/ docker-compose:PostgreSQL 16(端口 5434,避开 cms 项目 5433)
scripts/ migrate-test.sh 等运维脚本 · sf.ts(probe/register/import/publish/build/preview CLI)· e2e-real.mjs(真实数据端到端编排)
docs/ adr/ 决策记录 · evidence/ 基线证据 · superpowers/ 规格与计划
```
## 文档导航
- 设计基线(表结构/技术决策/阶段划分):`docs/superpowers/specs/2026-10-20-siteforge-vertical-slice-design-v2.md`
- 阶段 0+1 实施计划:`docs/superpowers/plans/2026-10-20-slice-foundation-phase0-1.md`
- 架构决策记录(ADR-001~018):`docs/adr/`
- 基线证据(环境/真实 WXR/阶段 3 导入/阶段 4 端到端预览验收):`docs/evidence/`
## 当前状态
- **阶段 1 已完成**:契约冻结、21 表数据模型全量落地(不可变触发器/唯一约束/CHECK 均落数据库并被 75 项测试锁定)、空环境一键启动+迁移验收通过。
- **阶段 2 已完成**:WXR 流式适配器(saxes 流式解析 → PHP unserialize → UniversalRow 映射 → HTML 白名单清洗 → 导入前报告)、`source:register` 快照登记(content-addressed、幂等)与 `pnpm sf` CLI;真实 hesupipe WXR(5.5MB)冒烟 18 项计数对照全过(峰值堆 62MiB < 100MiB,证据见 `docs/evidence/phase2-smoke.md`)。
- **阶段 3 已完成**:内容导入管道(`sf import`——content/term/media/route 四家写入器串行编排、稳定身份双轨幂等、checksum skip、route_registry §6.1 全表处置、JSON+HTML 导入报告与错误封顶);真实 hesupipe 全量导入验收通过——192 内容条目/1122 source_records/927 terms/2772 routes 落库,二导幂等(0 新修订)、published 指针全程未动(ADR-010),333 测试全绿(证据见 `docs/evidence/phase3-import.md`)。
- **阶段 4 已完成**:发布与静态预览全链(`content:publish` 显式发布/审计/站点配置首版 → Render Snapshot 六文件冻结(ADR-011)→ pilot-minimal 主题 Astro 构建(媒体本地化/sitemap/robots/route-manifest §12.1)→ 五项最小门禁 → 路由驱动本地 Preview(回环绑定/noindex));**真实 hesupipe 浏览器时刻兑现**——190 页全 200、1746 redirect 全 301、编码中文路径字节精确贯穿(ADR-018)、验收 23 断言 + 双视口 6 截图全过、五门禁 PASS(p0=0);主题与构建决策入册 ADR-018,**408 测试全绿**(证据见 `docs/evidence/phase4-preview.md`,截图 `docs/evidence/screenshots/`)。
- **下一步:阶段 5(Plan 5)**——SEO 三方差异 + 完整门禁 = M1 完整迁移预览;输入清单见 Plan 4 文末"移交 Plan 5 清单"(`docs/superpowers/plans/2026-10-21-slice-build-preview-phase4.md`)。