From d60123ba41e37b75cbdc341a437e49a9c1315f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Tue, 20 Oct 2026 16:10:34 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20SiteForge=20=E8=A7=84=E5=88=92=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E5=9F=BA=E7=BA=BF=20+=20=E7=BA=B5=E5=90=91=E5=88=87?= =?UTF-8?q?=E7=89=87=E8=AE=BE=E8=AE=A1=E8=A7=84=E6=A0=BC=20V1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - V3.0 总体方案、主题与板块设计、实施计划 - cms 现状差距分析 V2.0(V1.0 已标注作废)与复用评估 V1.0 - 纵向切片设计规格(路线 C:全新架构 + 白名单资产移植) - .gitignore 先行(storage/artifacts/env 永不入库) Co-Authored-By: Claude Code --- .gitignore | 19 + SiteForge_主题与板块设计方案_V1.0.md | 900 +++++++++ SiteForge_完整项目计划方案_V3.0.md | 1731 +++++++++++++++++ SiteForge_现有CMS项目复用评估_V1.0.md | 552 ++++++ SiteForge_项目实施计划_V1.0.md | 1157 +++++++++++ cms现状与SiteForge差距分析_V1.0.md | 127 ++ cms现状与SiteForge差距分析_V2.0.md | 1011 ++++++++++ ...6-10-20-siteforge-vertical-slice-design.md | 249 +++ 8 files changed, 5746 insertions(+) create mode 100644 .gitignore create mode 100644 SiteForge_主题与板块设计方案_V1.0.md create mode 100644 SiteForge_完整项目计划方案_V3.0.md create mode 100644 SiteForge_现有CMS项目复用评估_V1.0.md create mode 100644 SiteForge_项目实施计划_V1.0.md create mode 100644 cms现状与SiteForge差距分析_V1.0.md create mode 100644 cms现状与SiteForge差距分析_V2.0.md create mode 100644 docs/superpowers/specs/2026-10-20-siteforge-vertical-slice-design.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e358d34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# 依赖与构建产物 +node_modules/ +dist/ +.artifacts/ +artifacts/ +coverage/ +.turbo/ + +# 试点数据与本地状态(WXR/媒体副本、数据库、密钥——绝不入库) +storage/ +.data/ +.env +.env.* +*.local + +# 日志与临时文件 +*.log +tmp/ +.DS_Store diff --git a/SiteForge_主题与板块设计方案_V1.0.md b/SiteForge_主题与板块设计方案_V1.0.md new file mode 100644 index 0000000..7000261 --- /dev/null +++ b/SiteForge_主题与板块设计方案_V1.0.md @@ -0,0 +1,900 @@ +# SiteForge 主题与板块设计方案 + +> 版本:V1.0 +> 日期:2026-10-20 +> 目标:支持每个网站拥有独立设计,同时让内容可以在后台结构化编辑并生成纯静态页面。 + +--- + +## 1. 设计结论 + +主题和板块必须解耦: + +- **主题(Theme)**负责页面结构、视觉风格、HTML、CSS、动画和响应式实现。 +- **板块(Block)**负责内容字段及其顺序,例如标题、图片、按钮、产品参数、FAQ。 +- **模板(Template)**规定一类页面默认由哪些区域组成,以及允许使用哪些板块。 +- **页面(Page)**保存所选模板和实际板块数据。 + +推荐模式是: + +```text +统一板块数据协议 + 每个主题自己的板块渲染器 +``` + +例如后台都保存 `hero` 数据,但汽车站可以显示全屏视频,工业站可以显示左文右图。两者共享内容语义,不共享强制布局。 + +V1 不做任意坐标、任意嵌套的低代码编辑器,只提供: + +- 选择板块。 +- 表单编辑字段。 +- 调整板块顺序。 +- 启用或隐藏板块。 +- 选择少量经过主题声明的样式变体。 +- PC/移动端静态预览。 + +这样既能快速维护,又不会让自由配置破坏设计、响应式和 SEO。 + +--- + +## 2. 四层结构 + +```mermaid +flowchart TB + CONTENT[内容:产品/文章/页面/媒体] + BLOCK[板块实例:type + data + settings] + TEMPLATE[页面模板:区域与板块约束] + THEME[主题:组件、样式、交互] + HTML[静态 HTML/CSS/JS] + + CONTENT --> BLOCK + BLOCK --> TEMPLATE + TEMPLATE --> THEME + THEME --> HTML +``` + +### 2.1 内容层 + +保存可复用的业务数据,例如产品名称、参数、文章正文和媒体资源。内容不应该写死在主题代码里。 + +### 2.2 板块层 + +保存某个页面中的展示内容和顺序。板块数据尽量不包含颜色、像素、CSS 类名等主题实现细节。 + +### 2.3 模板层 + +定义首页、产品详情、新闻详情、普通页面等页面类型及允许的区域。模板可以自动插入由业务数据驱动的系统区域。 + +### 2.4 主题层 + +每个主题提供自己的 Astro 页面、组件、样式和板块渲染器,最终生成静态文件。 + +--- + +## 3. 板块分类 + +### 3.1 全局板块 + +全站复用,单独管理: + +- Header +- Footer +- 顶部通知条 +- 全局询价 CTA +- 联系方式 +- 社交媒体链接 +- Cookie/隐私提示 + +修改全局板块后,会重建所有引用它的页面;V1 可以直接触发该站全量构建。 + +### 3.2 页面内容板块 + +由管理员在页面中新增、排序和编辑: + +- Hero +- Rich Text +- Image + Text +- Image Gallery +- Video +- Feature List +- Statistics +- Logo/Brand List +- Product Grid +- Article List +- Specification Table +- Download List +- FAQ +- Testimonials +- CTA +- Contact Information +- Map Embed + +### 3.3 模板系统板块 + +由模板根据当前内容自动生成,通常不允许页面编辑者删除: + +- 面包屑 +- 产品主信息 +- 产品参数 +- 文章标题、日期和正文 +- 分类列表与分页 +- 相关推荐 +- SEO Head + +管理员可以在允许范围内控制显示、顺序或样式变体,但不直接维护其核心业务数据。 + +### 3.4 站点专属板块 + +某些页面效果只属于一个站点,可以由主题声明自定义板块,例如: + +```text +vehicle-360-view +charging-calculator +factory-process-timeline +dealer-map +``` + +站点专属板块仍需提供数据 schema 和后台表单定义,不能只在代码中写死内容。 + +### 3.5 Legacy HTML 板块 + +用于暂时无法结构化的历史内容: + +- 只接受清洗后的 HTML。 +- 删除脚本、事件属性和危险 URL。 +- 使用隔离样式容器。 +- 后台醒目标记为“待结构化”。 +- 不能作为新页面的默认编辑方式。 + +--- + +## 4. 板块数据协议 + +### 4.1 板块实例 + +```ts +export interface BlockInstance> { + id: string; + type: string; + schemaVersion: number; + variant?: string; + data: TData; + settings?: { + anchorId?: string; + themeMode?: 'default' | 'light' | 'dark'; + spacing?: 'none' | 'small' | 'medium' | 'large'; + }; + visibility: { + enabled: boolean; + locales?: string[]; + }; +} +``` + +### 4.2 页面内容示例 + +```json +{ + "contentId": "page_home", + "templateKey": "home", + "blocks": [ + { + "id": "block_hero_01", + "type": "hero", + "schemaVersion": 1, + "variant": "image-right", + "data": { + "eyebrow": "New Energy Vehicles", + "title": "Build Your Next Journey", + "description": "A short introduction.", + "mediaId": "asset_1001", + "primaryAction": { + "label": "View Products", + "href": "/products/" + } + }, + "settings": { + "spacing": "large", + "themeMode": "dark" + }, + "visibility": { + "enabled": true + } + } + ] +} +``` + +### 4.3 内容和样式边界 + +建议保存在板块数据中的字段: + +- 标题、描述和按钮文案。 +- 媒体资源引用。 +- 内部/外部链接。 +- 产品、文章、分类等内容引用。 +- 允许的语义变体,例如 `featured`、`compact`。 + +不建议保存: + +- 任意 CSS。 +- Tailwind/CSS 类名。 +- 像素坐标。 +- 随意输入的颜色值。 +- 主题组件文件路径。 +- 可执行 JavaScript。 + +颜色、字体和间距默认由主题控制。如果确实需要运营配置,只允许主题 manifest 中声明的有限选项。 + +--- + +## 5. 板块定义与表单生成 + +每个板块类型包含两份声明: + +1. `schema`:数据校验规则。 +2. `uiSchema`:后台如何展示编辑表单。 + +### 5.1 Hero Schema 示例 + +```json +{ + "$id": "siteforge://blocks/hero/v1", + "type": "object", + "required": ["title"], + "properties": { + "eyebrow": { "type": "string", "maxLength": 80 }, + "title": { "type": "string", "minLength": 1, "maxLength": 160 }, + "description": { "type": "string", "maxLength": 500 }, + "mediaId": { "type": "string" }, + "primaryAction": { + "type": "object", + "properties": { + "label": { "type": "string", "maxLength": 40 }, + "href": { "type": "string" } + }, + "required": ["label", "href"] + } + }, + "additionalProperties": false +} +``` + +### 5.2 UI Schema 示例 + +```json +{ + "title": { "widget": "text", "label": "主标题" }, + "description": { "widget": "textarea", "label": "说明" }, + "mediaId": { "widget": "media-picker", "label": "主视觉" }, + "primaryAction.href": { "widget": "link-picker", "label": "按钮链接" } +} +``` + +管理后台根据这些声明生成表单,不需要为每个主题重复开发一套内容编辑页面。 + +推荐使用 JSON Schema 作为跨前后端协议,并使用 Ajv 校验。主题内可以生成对应 TypeScript 类型,避免重复维护接口。 + +--- + +## 6. 主题协议 + +### 6.1 主题清单 + +```json +{ + "id": "automotive-premium", + "name": "Automotive Premium", + "version": "1.0.0", + "engine": "astro", + "siteConfigSchema": "./schemas/site-config.schema.json", + "templates": { + "home": { + "entry": "src/templates/HomePage.astro", + "allowedBlocks": ["hero", "feature-list", "product-grid", "cta"], + "requiredBlocks": ["hero"], + "maxPerType": { "hero": 1 } + }, + "product": { + "entry": "src/templates/ProductDetail.astro", + "allowedBlocks": ["gallery", "specification-table", "download-list", "faq", "cta"] + }, + "page": { + "entry": "src/templates/GenericPage.astro", + "allowedBlocks": ["hero", "rich-text", "image-text", "gallery", "faq", "cta"] + } + }, + "blocks": { + "hero": { + "renderer": "src/blocks/HeroBlock.astro", + "schema": "siteforge://blocks/hero/v1", + "variants": ["fullscreen", "image-right", "minimal"] + }, + "product-grid": { + "renderer": "src/blocks/ProductGridBlock.astro", + "schema": "siteforge://blocks/product-grid/v1", + "variants": ["cards", "editorial"] + } + } +} +``` + +### 6.2 主题目录 + +```text +themes/automotive-premium/ + theme.json + schemas/ + site-config.schema.json + src/ + templates/ + HomePage.astro + ProductDetail.astro + ArticleDetail.astro + GenericPage.astro + blocks/ + HeroBlock.astro + RichTextBlock.astro + ProductGridBlock.astro + FaqBlock.astro + components/ + Header.astro + Footer.astro + Breadcrumb.astro + layouts/ + BaseLayout.astro + styles/ + tokens.css + global.css + lib/ + block-renderers.ts + public/ +``` + +### 6.3 不使用主题继承 + +V1 不建议建立复杂的父主题/子主题覆盖机制。公共能力通过普通包复用: + +```text +packages/theme-runtime +packages/seo-components +packages/block-contracts +packages/media-components +``` + +每个主题仍然明确拥有自己的模板和 CSS。这样升级公共包时更可控,也避免多层覆盖难以追踪。 + +### 6.4 四层组件化复用架构 + +为了提高新主题和新网站的开发速度,组件按复用程度分为四层: + +```mermaid +flowchart TB + C1[第一层:数据契约与工具] + C2[第二层:无样式基础组件] + C3[第三层:业务逻辑与 Headless 组件] + C4[第四层:主题展示组件] + PAGE[页面模板] + + C1 --> C2 + C1 --> C3 + C2 --> C4 + C3 --> C4 + C4 --> PAGE +``` + +#### 第一层:数据契约与工具,完全复用 + +- Block、Page、Media、Menu、SEO 类型。 +- JSON Schema 和数据验证。 +- 内部链接解析。 +- 图片地址、`srcset` 和尺寸计算。 +- URL、Canonical、Hreflang 和结构化数据生成。 +- HTML 净化、日期格式化和多语言工具。 + +这一层不包含任何主题样式。 + +#### 第二层:无样式基础组件,高度复用 + +- Container +- Grid +- Stack +- Media +- Picture +- Link +- Button 基础行为 +- Dialog +- Accordion +- Tabs +- Carousel 控制逻辑 +- Pagination + +组件提供语义、可访问性和交互状态,不固定颜色、字体和视觉效果。主题通过 CSS、自定义属性和组合方式决定最终外观。 + +#### 第三层:业务逻辑与 Headless 组件,高度复用 + +- 产品列表查询与分页。 +- 文章列表查询。 +- 产品参数分组。 +- 菜单树解析。 +- 面包屑生成。 +- FAQ 展开状态。 +- 表单校验和提交状态。 +- 搜索数据适配。 +- 相关推荐规则。 + +这类组件输出数据或状态,不直接决定最终 DOM 结构。例如 `createProductGridModel()` 负责得到产品卡片数据,汽车主题和工业主题分别决定如何渲染卡片。 + +#### 第四层:主题展示组件,按主题独立 + +- Header、Footer、Mega Menu。 +- Hero 的具体布局。 +- Product Card 的视觉结构。 +- 首页各板块的组合方式。 +- 动画、颜色、字体和响应式细节。 + +这一层允许完全不同,避免为了复用而把所有网站做成同一种风格。 + +### 6.5 公共组件包结构 + +```text +packages/ + content-contracts/ # Page、Block、Product、Post 等类型 + block-contracts/ # 板块 schema、版本和迁移 + theme-runtime/ # 主题加载、模板解析、渲染上下文 + ui-primitives/ # 无样式基础组件 + headless-components/ # 菜单、分页、Tabs、Accordion 等逻辑 + content-resolvers/ # 产品/文章/分类引用解析 + media-components/ # Picture、Video、资源地址与 srcset + seo-components/ # Meta、Canonical、Hreflang、JSON-LD + form-runtime/ # 表单 schema、校验和提交适配 + design-tokens/ # 公共 token 协议,不存具体品牌值 +``` + +主题只引用公共包的正式入口,不能跨主题引用另一个主题内部文件。 + +```text +允许:theme-a → packages/ui-primitives +禁止:theme-a → themes/theme-b/src/components/ProductCard.astro +``` + +如果多个主题确实重复使用一个展示组件,应先将其中的通用行为和结构抽到公共包,再由各主题提供外观;不要直接复制后形成多个无法同步的版本。 + +### 6.6 设计令牌 + +公共组件只使用语义化 token,不使用某个网站的品牌颜色: + +```css +:root { + --sf-color-primary: #1f4b7a; + --sf-color-accent: #e8792e; + --sf-color-text: #1b1f24; + --sf-color-surface: #ffffff; + --sf-radius-control: 0.5rem; + --sf-space-section: clamp(4rem, 8vw, 8rem); + --sf-container-width: 75rem; +} +``` + +每个主题覆盖这些 token,也可以增加自己的 token。公共包不得依赖只有某个主题才存在的 token。 + +### 6.7 组合优于大量 Variant + +公共组件保持小而稳定,通过组合形成页面板块: + +```astro +
+ + + + + + +
+``` + +不要给一个公共 Hero 增加几十个布尔属性来适应所有网站,例如 `rounded`、`centered`、`overlay`、`video`、`reverse`、`compact` 的任意组合。稳定的数据协议可以复用,最终板块应由主题组合基础组件实现。 + +### 6.8 组件复用矩阵 + +| 能力 | 公共包复用 | 主题独立 | +|---|---:|---:| +| 数据类型与 Schema | 是 | 否 | +| SEO Head | 是 | 可提供少量站点配置 | +| Picture/srcset | 是 | 可控制画面比例和样式 | +| 菜单树和展开逻辑 | 是 | Header 结构和动画独立 | +| 产品查询与分页 | 是 | 产品卡片独立 | +| FAQ 数据与交互状态 | 是 | 排版和图标独立 | +| 表单校验与提交 | 是 | 字段布局和视觉独立 | +| Hero 内容协议 | 是 | Hero 渲染完全独立 | +| 页面模板 | 否 | 是 | +| 品牌色、字体、间距 | 仅协议 | 是 | + +### 6.9 组件版本与兼容 + +- 公共包遵循语义化版本。 +- 破坏性变更必须提供迁移说明或兼容适配层。 +- 主题 manifest 记录公共运行时的兼容范围。 +- 每个公共组件提供最小、完整、异常三个测试 fixture。 +- 公共组件升级后,自动构建所有示范主题并执行截图回归。 +- 发布 release 锁定公共包和主题版本,回滚时不能自动升级依赖。 + +### 6.10 组件预览与文档 + +建立独立的组件预览页,展示: + +- 基础组件的状态和可访问性。 +- 每种板块的最小/完整数据。 +- 同一板块在不同主题中的效果。 +- 桌面、平板和手机断点。 +- 空数据、超长标题、图片缺失等异常状态。 + +预览页可以采用 Storybook 或项目内 Astro 组件目录。V1 的重点是可查看和自动截图,不强制依赖某个文档工具。 + +--- + +## 7. 模板约束 + +模板除了渲染页面,还负责约束后台可配置范围。 + +```ts +export interface TemplateDefinition { + key: string; + contentTypes: string[]; + allowedBlocks: string[]; + requiredBlocks?: string[]; + maxPerType?: Record; + lockedRegions?: string[]; +} +``` + +示例: + +- 首页必须有一个 Hero,最多一个。 +- 产品详情固定显示产品标题、价格/询价入口和核心参数。 +- FAQ、下载、CTA 可以由管理员添加、删除和排序。 +- SEO Head、Header、Footer 是锁定区域,不出现在自由排序列表里。 + +后台新增板块时,只显示当前主题、当前模板支持的类型和变体。 + +--- + +## 8. 数据库存储 + +推荐将板块实例按修订版本独立存储,而不是直接写入已发布页面。 + +```sql +CREATE TABLE page_blocks ( + id UUID PRIMARY KEY, + site_id UUID NOT NULL REFERENCES sites(id), + revision_id UUID NOT NULL REFERENCES content_revisions(id), + block_type TEXT NOT NULL, + schema_version INTEGER NOT NULL, + variant TEXT, + position INTEGER NOT NULL, + data JSONB NOT NULL DEFAULT '{}'::jsonb, + settings JSONB NOT NULL DEFAULT '{}'::jsonb, + visibility JSONB NOT NULL DEFAULT '{"enabled":true}'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX idx_page_blocks_revision_position + ON page_blocks(revision_id, position); +``` + +全局板块可以使用: + +```text +global_fragments +global_fragment_revisions +global_fragment_usages +``` + +发布时锁定内容修订和全局板块修订,确保历史 release 可以准确回滚。 + +--- + +## 9. 后台编辑体验 + +### 9.1 页面编辑器布局 + +```text +┌────────────────────────────────────────────────────────────┐ +│ 页面标题 / URL / 模板 / 保存 / 预览 / 发布 │ +├──────────────────────┬─────────────────────────────────────┤ +│ 板块列表 │ 当前板块表单 │ +│ │ │ +│ 1. Hero │ 标题 [________________] │ +│ 2. Product Grid │ 描述 [________________] │ +│ 3. FAQ │ 图片 [选择媒体] │ +│ 4. CTA │ 样式变体 [image-right ▼] │ +│ │ │ +│ [+ 添加板块] │ │ +└──────────────────────┴─────────────────────────────────────┘ +``` + +首版功能: + +- 点击新增板块。 +- 拖动调整纵向顺序。 +- 复制、隐藏和删除板块。 +- 编辑结构化字段。 +- 从媒体库、产品、文章和内部路由中选择引用。 +- 保存草稿。 +- 创建静态预览。 +- 显示字段和模板校验错误。 + +### 9.2 不在 V1 实现 + +- 画布上任意拖动位置。 +- 任意列宽和像素级布局。 +- 无限层级嵌套板块。 +- 管理员输入 CSS/JavaScript。 +- 在一个主题中自由调用另一个主题的组件。 + +--- + +## 10. Astro 渲染实现 + +### 10.1 渲染器注册 + +```ts +import HeroBlock from '../blocks/HeroBlock.astro'; +import RichTextBlock from '../blocks/RichTextBlock.astro'; +import ProductGridBlock from '../blocks/ProductGridBlock.astro'; + +export const blockRenderers = { + hero: HeroBlock, + 'rich-text': RichTextBlock, + 'product-grid': ProductGridBlock, +} as const; +``` + +### 10.2 页面循环 + +```astro +--- +import { blockRenderers } from '../lib/block-renderers'; + +const { page } = Astro.props; +const blocks = page.blocks.filter((block) => block.visibility.enabled); +--- + +{blocks.map((block) => { + const Renderer = blockRenderers[block.type]; + return Renderer + ? + : null; +})} +``` + +实际构建前必须已经验证所有板块类型。生产构建发现未知板块时应失败,不能静默生成空白区域;后台预览可以显示“当前主题不支持该板块”的占位提示。 + +### 10.3 数据解析顺序 + +```text +读取发布快照 +→ 获取页面与内容引用 +→ 获取模板定义 +→ 验证允许的板块和数量 +→ 按 schema 校验每个板块 +→ 解析媒体与内部链接 +→ 选择主题渲染器 +→ 生成 HTML +→ 执行 SEO/链接/资源验收 +``` + +### 10.4 客户端 JavaScript + +Astro 默认输出静态 HTML。只有轮播、菜单、筛选等确需交互的组件才使用客户端 hydration,并选择合适的加载策略。普通文本、产品参数和 FAQ 不应无条件加载完整前端框架。 + +--- + +## 11. 主题切换策略 + +### 11.1 可以直接切换的条件 + +- 新主题支持当前页面模板。 +- 新主题支持页面使用的全部板块类型。 +- 每个板块的 schema 版本兼容。 +- 主题所需站点配置完整。 + +### 11.2 切换前检查 + +系统先生成兼容报告: + +```text +支持的模板 +缺失的板块渲染器 +不支持的 variant +缺失的站点配置 +需要迁移的数据版本 +``` + +存在不支持板块时,不允许直接用于生产构建。可以: + +- 为新主题增加渲染器。 +- 将板块转换为兼容类型。 +- 由管理员明确删除或替换。 + +### 11.3 主题切换不是主要目标 + +平台需要支持主题版本升级和兼容检查,但不必把“任何网站一键换任意主题”作为 V1 目标。不同网站设计差异很大,强行互换会让板块协议变得臃肿。 + +--- + +## 12. 板块版本与数据迁移 + +板块必须携带 `schemaVersion`。 + +```ts +type BlockMigration = { + blockType: string; + fromVersion: number; + toVersion: number; + migrate: (oldData: unknown) => unknown; +}; +``` + +例如 Hero V2 将 `buttonText` 和 `buttonUrl` 合并为 `primaryAction`: + +```text +v1 data +→ 运行纯函数迁移 +→ v2 data +→ schema 校验 +→ 生成新的内容修订 +``` + +禁止直接批量覆盖已发布修订。迁移失败的板块进入人工处理列表,旧版本数据继续保留。 + +--- + +## 13. API 建议 + +```text +GET /api/v1/themes +GET /api/v1/themes/:themeId/manifest +GET /api/v1/sites/:siteId/theme +PUT /api/v1/sites/:siteId/theme + +GET /api/v1/sites/:siteId/pages/:pageId/blocks +POST /api/v1/sites/:siteId/pages/:pageId/blocks +PATCH /api/v1/sites/:siteId/pages/:pageId/blocks/:blockId +DELETE /api/v1/sites/:siteId/pages/:pageId/blocks/:blockId +POST /api/v1/sites/:siteId/pages/:pageId/blocks/reorder +POST /api/v1/sites/:siteId/pages/:pageId/validate +POST /api/v1/sites/:siteId/pages/:pageId/preview + +GET /api/v1/sites/:siteId/fragments +POST /api/v1/sites/:siteId/fragments +PATCH /api/v1/sites/:siteId/fragments/:fragmentId +``` + +后端负责验证模板、板块类型、schema、variant、媒体和内部链接;不能只在管理后台进行校验。 + +--- + +## 14. 测试策略 + +### 14.1 契约测试 + +- 每个主题 manifest 格式正确。 +- 模板引用的板块都有渲染器。 +- 板块数据能通过对应 schema。 +- 主题声明的 variant 都能渲染。 +- 必需板块和最大数量约束有效。 + +### 14.2 渲染测试 + +- 每个模板至少有一份标准 fixture。 +- 每个板块测试最少字段、完整字段和异常字段。 +- 生成 HTML 不包含预览域名、危险脚本和无效资源。 +- 核心内容在输出 HTML 中真实存在,而非仅客户端加载。 + +### 14.3 视觉测试 + +- 为首页、产品详情、文章详情和普通页面生成桌面/移动截图。 +- 主题版本变化时对比关键页面。 +- 视觉差异由超级管理员确认后才能用于生产发布。 + +### 14.4 性能与可访问性 + +- 图片包含宽高并使用合适尺寸。 +- 交互组件按需加载。 +- 标题层级、链接、按钮和表单具有正确语义。 +- 颜色对比、键盘操作和焦点状态在主题验收中检查。 + +--- + +## 15. V1 实现顺序 + +### Sprint 1:契约和最小渲染 + +- 建立 `block-contracts`。 +- 建立 `ui-primitives`、`theme-runtime` 和 `content-resolvers` 的最小公共包。 +- 定义 Hero、Rich Text、Image Text、Gallery、CTA、FAQ 六个基础板块。 +- 建立主题 manifest 和模板协议。 +- 使用固定 JSON 生成一个静态首页。 + +### Sprint 2:数据库和后台编辑 + +- 建立 `page_blocks` 和内容修订。 +- 根据 schema 生成表单。 +- 支持新增、编辑、删除、排序和隐藏。 +- 支持媒体和内部链接选择。 + +### Sprint 3:主题与预览 + +- 完成第一套主题的首页、普通页面、产品详情和文章详情。 +- 建立预览构建。 +- 增加模板与板块兼容检查。 + +### Sprint 4:第二主题验证 + +- 使用相同基础板块数据开发视觉完全不同的第二主题。 +- 验证哪些字段真正通用,哪些需要站点专属板块。 +- 将两个主题中重复的非视觉逻辑提取到公共组件包。 +- 固化主题 SDK、测试 fixture 和开发文档。 + +### Sprint 5:生产质量 + +- 板块版本迁移。 +- 全局板块。 +- 视觉回归、可访问性和性能检查。 +- 与发布门禁和不可变 release 集成。 + +--- + +## 16. 首版基础板块清单 + +建议首版只实现以下 12 个,真实试点需要后再增加: + +| 板块 | 核心字段 | +|---|---| +| Hero | eyebrow、title、description、media、actions | +| Rich Text | content | +| Image Text | title、content、media、mediaPosition、action | +| Gallery | title、items | +| Feature List | title、items、icon/media | +| Statistics | title、items(value/label) | +| Product Grid | title、productRefs/query、limit、action | +| Article List | title、category/query、limit、action | +| Specification Table | title、groups/rows 或 product field binding | +| Download List | title、assetRefs | +| FAQ | title、items(question/answer) | +| CTA | title、description、media、actions | + +Header、Footer、Breadcrumb、产品主信息和文章主内容作为全局/模板系统组件单独实现,不计入可自由添加板块。 + +--- + +## 17. 开发验收标准 + +主题与板块模块达到以下条件即可视为 V1 完成: + +1. 超级管理员能为页面选择模板。 +2. 能新增、编辑、排序、隐藏和删除模板允许的板块。 +3. 后台字段由 schema 驱动,并在前后端双重验证。 +4. 相同板块数据能被两套主题渲染成明显不同的设计。 +5. 主题不支持某板块时,生产构建会被阻止并给出明确错误。 +6. 产品详情和文章详情能混合系统板块与可配置板块。 +7. 全局 Header/Footer 修改后能够重新构建站点。 +8. 所有发布版本锁定主题版本和板块修订,可准确回滚。 +9. 页面输出为静态 HTML,核心内容无需 JavaScript 即可读取。 +10. 主题和板块变更进入现有 URL、SEO、内容和视觉发布门禁。 +11. 两套主题复用相同的数据契约、媒体、SEO 和 Headless 逻辑,但最终页面视觉明显不同。 + +--- + +## 18. 最终建议 + +首版主题系统的重点不是“让管理员设计网页”,而是让开发者能够快速制作不同主题,让管理员安全地维护结构化内容。 + +必须守住三个边界: + +1. 内容数据中不写 CSS 和组件路径。 +2. 主题不能自己决定历史 URL 和 SEO。 +3. 未知或不兼容板块不能在生产构建中静默消失。 + +按“统一协议、独立渲染、有限配置、严格校验”实现,既能保留每个网站的设计自由度,也能让后续内容维护和新站迁移真正复用同一套系统。 diff --git a/SiteForge_完整项目计划方案_V3.0.md b/SiteForge_完整项目计划方案_V3.0.md new file mode 100644 index 0000000..030556c --- /dev/null +++ b/SiteForge_完整项目计划方案_V3.0.md @@ -0,0 +1,1731 @@ +# SiteForge 多站点静态迁移与内容发布平台 + +> 完整项目计划方案 V3.0 +> 编制日期:2026-10-20 +> 文档状态:立项、研发与试点执行基线 +> 适用范围:WordPress 为主,兼容 HTML、PHP/MySQL、自研 CMS、API 与标准数据文件 +> 设计原则:单一超级管理员、组件化复用、每站独立设计、纯静态生产、URL/SEO 优先、可审计发布与回滚 + +--- + +## 0. 执行摘要 + +SiteForge 是一套面向多网站运营的迁移与发布控制平台。它负责扫描旧站、导入内容、保留 URL 和 SEO、重新设计主题、生成静态网站,并在后续持续管理产品、新闻、页面和媒体。 + +平台不是另一个 WordPress,也不是通用拖拽建站器。它的核心价值是把多次网站迁移中重复发生的工作标准化: + +```text +旧站盘点 +→ 全量导入 +→ 数据标准化 +→ URL/SEO 冻结 +→ 独立主题实现 +→ 差量同步 +→ 静态构建 +→ 自动验收 +→ 发布确认 +→ 原子切换 +→ 监测与回滚 +``` + +生产网站输出独立的 HTML、CSS、JavaScript 和媒体文件,不实时依赖 SiteForge 数据库。表单、搜索等必须动态运行的能力通过独立 API 或服务提供。 + +V1 采用以下核心技术方向: + +- Art Design Pro 管理后台底座(Vue 3 + TypeScript + Element Plus)。 +- NestJS 模块化单体 API。 +- PostgreSQL 数据库。 +- Redis + BullMQ 任务队列。 +- TypeScript 抓取与 Playwright 渲染兜底。 +- Astro 静态构建。 +- S3 兼容对象存储。 +- Docker Compose 部署控制面。 +- Nginx/SSH 和对象存储/CDN 两类发布适配器。 + +V1 只设置一种系统角色 `super_admin`,默认由一个超级管理员账号管理全部功能,不建设 RBAC、成员和复杂审批系统。高风险操作通过二次确认、MFA、不可变日志和可回滚发布降低风险。 + +--- + +## 1. 建设背景与目标 + +### 1.1 当前问题 + +- 多个网站主要使用 WordPress,也存在其他 CMS、PHP、自研系统或纯 HTML 网站。 +- 每次迁移都需要重新处理内容、URL、SEO、图片、服务器规则和发布流程。 +- 网站之间设计差异大,无法直接使用同一套页面模板。 +- 旧站积累了历史路径、外链和搜索流量,不能随意改变 URL。 +- 新站希望保持纯静态,同时仍需要持续新增产品、新闻和页面。 +- 现有迁移通常依赖人工脚本,缺少可重复、可审计和可回滚的标准流程。 + +### 1.2 建设目标 + +1. 一个后台集中管理多个网站。 +2. 优先深度支持 WordPress,通过适配器兼容其他来源。 +3. 精确保留旧 URL、状态码、跳转和 SEO 行为。 +4. 每个站点可使用完全独立的主题和页面设计。 +5. 使用组件化、板块化机制提高开发复用率。 +6. 后台可以长期维护产品、新闻、页面、菜单和媒体。 +7. 生产站以纯静态方式部署,控制面故障不影响线上访问。 +8. 每次构建、验收、发布和回滚都有完整记录。 +9. 完成两个差异化试点后,新站主要投入集中在来源映射、异常处理和主题设计。 + +### 1.3 成功标准 + +| 维度 | V1 成功标准 | +|---|---| +| URL | 基线 URL 100% 有明确处置结果或批准例外 | +| SEO | 关键 SEO 属性有来源快照、目标值和差异报告 | +| 内容 | 核心页面、产品、文章、分类、媒体通过业务抽检 | +| 设计 | 至少两套视觉差异明显的独立主题运行在同一平台 | +| 发布 | 构建可追溯、发布原子化、回滚经过实际演练 | +| 稳定性 | SiteForge 短时离线不影响已经发布的生产站点 | +| 运营 | 超级管理员可无代码新增产品、新闻和普通页面 | +| 复用 | 第二个站点复用迁移、URL、SEO、构建和发布链路 | + +### 1.4 不做承诺 + +- 仅凭公开 URL 自动发现后台未公开内容和私有字段。 +- 任意复杂页面构建器内容零人工转换成理想的新设计。 +- 电商交易、支付、订单和会员系统完全静态化。 +- 网站迁移后搜索排名绝对不波动。 +- V1 支持所有 CMS、任意主题切换和通用低代码设计。 + +--- + +## 2. 产品范围与版本边界 + +### 2.1 V1 必须交付 + +| 能力 | 是否阻塞试点 | 验收方式 | +|---|---:|---| +| 多站点与环境管理 | 是 | 至少两个站点隔离运行 | +| 单一超级管理员 | 是 | 登录、MFA、恢复、会话撤销可用 | +| WordPress REST/WXR/SQL/uploads 导入 | 是 | 真实试点数据导入通过 | +| Sitemap/HTML/Playwright 扫描 | 是 | 输出可审计 URL 与页面清单 | +| 原始快照与差量同步 | 是 | 重跑不重复,切站前完成最终增量 | +| 统一内容与内容修订 | 是 | 产品、新闻、页面可编辑和回滚 | +| URL 注册表与路由编译 | 是 | 目标部署环境真实 HTTP 验证 | +| SEO 快照与差异报告 | 是 | P0/P1 门禁有效 | +| 媒体迁移与旧路径保持 | 是 | 关键媒体无未处理 404 | +| 主题/模板/板块协议 | 是 | 两个差异化主题使用同一协议 | +| 组件化公共包 | 是 | 两个主题复用数据、SEO、媒体和交互逻辑 | +| Astro 全量静态构建 | 是 | 产物可独立部署 | +| 预览、验收、发布、回滚 | 是 | 完成一次上线及回滚演练 | +| Nginx/SSH 发布 | 是 | 试点目标发布通过 | +| S3/OSS + CDN 发布 | 二选一 | 如作为试点目标则验收 | +| 表单基础服务 | 按站点 | 提交、重试、隐私和反垃圾通过 | +| 备份、监控和操作日志 | 是 | 完成恢复演练与告警测试 | + +### 2.2 V1.1 建议能力 + +- 多语言内容和 hreflang 完整工作流。 +- 定时发布和批量发布。 +- 简单站内搜索或独立搜索服务接入。 +- 图片 WebP/AVIF 衍生和更精细的媒体优化。 +- PHP/MySQL、Drupal、Joomla 等第二批深度适配器。 +- 页面依赖图驱动的选择性重建。 +- WebHook 和外部业务系统联动。 + +### 2.3 暂不建设 + +- 自由画布式低代码编辑器。 +- 无限层级嵌套板块。 +- 复杂商城、订单、支付和会员中心。 +- 多角色、成员、细粒度 RBAC 和站内审批流。 +- 跨组织 SaaS 计费和主题市场。 +- 自动发布未经人工确认的 AI 生成或迁移结果。 +- Kubernetes、多区域主动容灾和复杂微服务拆分。 + +--- + +## 3. 总体架构 + +```mermaid +flowchart TB + subgraph Sources[旧站与数据来源] + WP[WordPress] + WEB[HTML / JS 网站] + DB[PHP / MySQL / 自研 CMS] + FILE[WXR / CSV / JSON / XML / ZIP] + LOG[访问日志 / GSC / GA4] + end + + subgraph Control[SiteForge 控制面] + ADMIN[超级管理员后台] + API[模块化 API] + JOB[任务调度与 Worker] + RAW[原始快照] + CDM[统一内容库] + ROUTE[URL / SEO 引擎] + THEME[主题 / 板块 / 组件] + BUILD[隔离静态构建] + QA[自动验收门禁] + RELEASE[Release 与部署] + end + + subgraph Production[独立生产面] + NGINX[Nginx 静态站] + CDN[对象存储 / CDN] + DYNAMIC[表单 / 搜索等独立 API] + end + + Sources --> JOB + ADMIN --> API + API --> JOB + JOB --> RAW + RAW --> CDM + CDM --> ROUTE + ROUTE --> THEME + THEME --> BUILD + BUILD --> QA + QA --> RELEASE + RELEASE --> NGINX + RELEASE --> CDN + NGINX -.按需调用.-> DYNAMIC + CDN -.按需调用.-> DYNAMIC +``` + +### 3.1 控制面与生产面 + +控制面包含后台、API、数据库、队列、采集、内容、构建和发布。生产面只包含不可变静态文件、部署规则和明确的动态服务。 + +生产网页不得在请求时读取 SiteForge 数据库,也不得依赖 WordPress/PHP 运行时。 + +### 3.2 模块化单体 + +V1 使用模块化单体 API 与独立 Worker,不拆分大量微服务: + +```text +API:认证、站点、内容、URL、SEO、主题、任务、发布 +Worker:扫描、导入、媒体、构建、验证、部署 +共享契约:Schema、DTO、事件、状态机 +``` + +### 3.3 四个发布输入 + +```text +Release = ContentSnapshot + + RouteSeoSnapshot + + ThemeBuildSnapshot + + SiteEnvironmentSnapshot +``` + +发布后的 release 必须能准确回答:用了哪些内容、路由、SEO、媒体、主题代码、依赖、环境配置和构建镜像。 + +--- + +## 4. 超级管理员与操作流程 + +### 4.1 唯一系统角色 + +V1 只定义 `super_admin` 一种角色,管理: + +- 全部网站和环境。 +- 数据源、扫描、导入和字段映射。 +- 产品、新闻、页面、分类、菜单和媒体。 +- URL、SEO、Sitemap 和跳转。 +- 主题、模板、板块和组件版本。 +- 预览、构建、发布、回滚和备份。 +- 系统配置、密钥引用和操作日志。 + +默认只启用一个日常超级管理员账号,不建设团队成员和权限分配。系统需提供: + +- 强密码策略。 +- MFA。 +- 一次性恢复码。 +- 登录失败限流。 +- 会话列表和远程撤销。 +- 登录异常提醒。 +- 高风险操作重新输入密码/MFA。 +- 操作日志记录账号、会话、IP、时间、对象和结果。 + +### 4.2 简化内容状态 + +不建设复杂审批流: + +```text +draft → ready_to_publish → publishing → published → archived +``` + +外部内容、SEO或设计人员的确认结果可以作为备注和附件保存,由超级管理员执行最终发布确认。 + +### 4.3 高风险操作 + +以下操作必须二次确认: + +- 生产发布。 +- 生产回滚。 +- 删除发布中的内容或 URL。 +- 清空导入批次。 +- 删除媒体原件。 +- 更换生产域名或部署目标。 +- 修改密钥、备份和安全配置。 + +--- + +## 5. 端到端迁移与切站流程 + +### 5.1 完整流程 + +```mermaid +flowchart TD + A[创建站点与授权确认] --> B[连接数据源] + B --> C[URL/SEO/功能全量盘点] + C --> D[第一次全量导入] + D --> E[标准化与字段映射] + E --> F[主题和板块实现] + F --> G[预览与多轮修复] + G --> H[迁移期间差量同步] + H --> I[上线前内容冻结] + I --> J[最终差量导入与全站重扫] + J --> K[锁定发布快照] + K --> L[静态构建与自动验收] + L -->|失败| E + L -->|通过| M[超级管理员发布确认] + M --> N[原子发布与缓存刷新] + N --> O[上线监测与保护期] + O -->|严重异常| P[回滚] + O -->|稳定| Q[关闭旧站写入并归档] +``` + +### 5.2 差量同步 + +差量判断综合使用: + +- 来源稳定 ID。 +- WordPress `modified_gmt` 等更新时间。 +- 内容和元数据 checksum。 +- 媒体哈希。 +- 页面最终 HTML/SEO checksum。 +- 删除、隐藏和状态变化标记。 + +每次同步输出:新增、更新、删除、无变化、冲突和失败。人工修改过的目标内容不得被来源更新静默覆盖,必须进入冲突队列。 + +### 5.3 切站时间线建议 + +```text +T-7天:完整彩排,验证发布和回滚 +T-3天:缩短 DNS TTL,确认旧站备份 +T-1天:执行倒数第二次差量同步 +T-2小时:冻结旧站内容写入 +T-90分钟:最终差量导入和 URL/SEO 重扫 +T-45分钟:锁定快照、构建、门禁检查 +T-15分钟:发布确认和临时入口冒烟 +T时刻:切换生产并刷新缓存 +T+2小时:高频关键 URL、表单和日志监测 +T+7天/约定期:确认稳定后归档旧环境 +``` + +实际时间按网站规模调整。 + +### 5.4 回滚触发条件 + +- 关键 URL 大量 404/500。 +- Canonical/Robots 全站错误。 +- 核心页面内容或媒体系统性缺失。 +- 表单等关键业务无法使用。 +- 发布规则与静态文件版本不一致。 +- 性能或可用性达到站点约定的严重阈值。 + +--- + +## 6. URL 全集与扫描系统 + +### 6.1 URL 发现来源 + +不能只依赖 Sitemap 和站内爬虫。基线合并以下来源: + +1. Sitemap 和 Sitemap Index。 +2. 首页、导航、分类、分页和全部站内链接。 +3. WordPress数据库中的公开内容、附件和历史 permalink。 +4. REST API/WXR/其他结构化导出。 +5. Nginx/Apache/CDN访问日志中的落地 URL。 +6. Search Console 页面数据。 +7. GA4/其他分析工具的历史着陆页。 +8. 现有 Nginx、Apache、CDN 重定向规则。 +9. 业务提供的广告、邮件、二维码和重要外链。 +10. 已知媒体、PDF和站点验证文件。 + +### 6.2 URL 基线状态 + +每条 URL 标记: + +```text +discovered +verified_active +verified_redirect +verified_not_found +requires_auth +unknown +excluded_with_reason +``` + +报告必须区分“确认遗漏”和“无法证明是否存在”。所谓 100% URL 处置率,是指已确认的 URL 基线全部有明确处理,而不是声称发现了互联网上所有历史地址。 + +### 6.3 扫描策略 + +- 明确允许的域名、子域名、协议和端口。 +- HTTP 抓取优先,JS 页面进入 Playwright 队列。 +- 每站设置并发、速率、深度、最大页面数和文件大小。 +- 保留原始 URL,同时生成规范化辅助键。 +- 不粗暴合并大小写、尾斜杠、查询参数和编码形式。 +- 任务支持断点续跑、重试、取消和恢复。 +- 保存响应头、状态码、跳转链、原始 HTML、渲染 DOM 和 checksum。 + +### 6.4 URL 注册表 + +```text +host +original_path +normalized_lookup_key +query_policy +source_status +target_status +route_kind +target_content_id +target_file +redirect_location +indexable +priority +source_snapshot_id +verification_status +``` + +`route_kind`:`html`、`redirect`、`asset`、`gone`、`dynamic`。 + +### 6.5 路径兼容 + +必须区分: + +- `/about`、`/about/`、`/about.html` +- `/Article/`、`/article/` +- Unicode 原文与不同百分号编码 +- `/news/page/2/`、标签和归档页 +- `?p=123`、`?page_id=123` +- `.php` 历史入口 +- 媒体、PDF、字体和验证文件 + +系统内部路径采用 UTF-8,并定义唯一的编码/解码规则。发布前检查 Windows 与 Linux 文件系统的大小写、保留名称和 Unicode 规范化冲突。 + +--- + +## 7. 部署能力矩阵与路由编译 + +### 7.1 部署适配器契约 + +每种部署目标声明能力: + +```ts +interface DeploymentCapabilities { + exactStatusCodes: boolean; + redirects: boolean; + queryRouting: boolean; + caseSensitivePaths: boolean; + customHeaders: boolean; + custom404: boolean; + gone410: boolean; + atomicSwitch: boolean; + rollback: boolean; + cachePurge: boolean; + edgeLogic: boolean; +} +``` + +### 7.2 路由编译 + +统一 `route-manifest` 根据目标平台编译成: + +- Nginx location/rewrite/map 规则。 +- Apache规则(后续按需)。 +- 对象存储静态文件结构。 +- CDN Redirect/Rewrite/Edge 规则。 +- 自定义错误页和响应头配置。 + +若部署目标无法实现某个关键 URL 的状态码或查询路由,预检必须阻止发布,并给出替代建议。 + +### 7.3 基础输出方式 + +- `/about-us/` → `about-us/index.html` +- `/news/a.html` → `news/a.html` +- `.php` 页面 → 服务器规则映射到静态文件 +- 查询参数语义路由 → Edge规则或独立服务 +- 历史媒体路径 → 原样文件或精确映射 + +### 7.4 部署能力验收 + +不能只检查文件是否存在,必须在与生产一致的 Web Server/CDN 预览环境中逐 URL 发起 HTTP 请求,验证状态码、Location、Content-Type、缓存头和页面内容。 + +--- + +## 8. 来源适配器与数据导入 + +### 8.1 可信度顺序 + +```text +数据库/平台 API > 标准导出文件 > 页面 HTML/渲染 DOM +``` + +HTML 同时用于验证最终对外页面,因此即使拥有数据库也应抓取旧站 HTML Head 和正文摘要进行交叉核对。 + +### 8.2 适配器接口 + +```ts +export interface SourceAdapter { + readonly id: string; + detect(ctx: ScanContext): Promise; + probe(ctx: ImportContext): Promise; + discover(ctx: ImportContext): AsyncIterable; + extract(ref: SourceResourceRef, ctx: ImportContext): Promise; + normalize(record: SourceRecord, ctx: MappingContext): Promise; + collectAssets?(ctx: ImportContext): AsyncIterable; + extractSiteSettings?(ctx: ImportContext): Promise; + diff?(from: SnapshotRef, to: SnapshotRef): Promise; + verify?(ctx: ImportContext): Promise; +} +``` + +统一错误码: + +```text +AUTH_REQUIRED +RATE_LIMITED +PRIVATE_CONTENT +UNSUPPORTED_FIELD +UNSUPPORTED_DYNAMIC_FEATURE +MISSING_ASSET +PARSE_FAILURE +SOURCE_CHANGED +SECURITY_REJECTED +``` + +### 8.3 WordPress 首版范围 + +- `wp_posts`、`wp_postmeta`。 +- 分类、标签及关联。 +- 页面、文章、公开 CPT。 +- 菜单、附件、特色图片。 +- WXR 内容和 postmeta。 +- REST API 公开内容。 +- `wp-content/uploads`。 +- Yoast SEO、Rank Math 常见字段,并与最终 HTML Head 比对。 +- Gutenberg 基础块。 +- ACF 原始字段保留和人工映射。 +- WooCommerce 商品基础信息、属性、变体和图库按试点评估。 + +专项适配:Elementor、WPBakery、多语言插件、自定义表、复杂短代码、主题私有字段。 + +### 8.4 导入幂等与冲突 + +源记录唯一键: + +```text +site_id + source_connection_id + source_type + source_id + locale +``` + +使用 checksum 区分新增、变化和未变化。人工编辑过的字段保存 `override` 标记;再次导入时保留来源新值和人工值,产生冲突,不自动覆盖。 + +### 8.5 原始快照 + +保存: + +- 原始文件或响应位置。 +- 来源连接与适配器版本。 +- 提取时间和时区。 +- 源 ID、URL 和状态。 +- checksum。 +- 导入批次。 +- 清洗、映射和异常日志。 + +--- + +## 9. 统一数据模型 + +### 9.1 模型原则 + +- PostgreSQL 保存关系和业务状态。 +- JSONB 保存扩展字段,但核心关系使用独立表。 +- 对象存储保存原始快照、媒体、报告和 release。 +- 所有业务实体包含 `site_id`。 +- 发布内容采用不可变 revision。 +- 跨实体引用可追踪,删除有影响分析。 + +### 9.2 核心实体 + +| 领域 | 实体 | +|---|---| +| 管理员 | admin_user、admin_session、recovery_code | +| 站点 | site、domain、environment、site_setting | +| 来源 | source_connection、import_job、source_snapshot、source_record | +| 内容 | content_entry、content_revision、page_block | +| 引用 | content_reference、global_fragment_usage | +| 分类 | taxonomy、term、content_term | +| 媒体 | media_asset、media_variant、media_usage | +| 导航 | menu、menu_item | +| 路由 | route_registry、redirect_rule、route_snapshot | +| SEO | seo_record、seo_snapshot、seo_change_note | +| 主题 | theme、theme_version、template_binding、block_schema | +| 构建 | build_job、build_input_snapshot、build_artifact | +| 验收 | validation_run、validation_issue、exception_note | +| 发布 | release、deployment_target、deployment、rollback_event | +| 运维 | job_lease、dead_letter_job、audit_log、credential_reference | + +### 9.3 核心内容类型 + +- `page` +- `post` +- `product` +- `product_category` +- `brand` +- `taxonomy_term` +- `menu` +- `global_fragment` +- `media_asset` + +### 9.4 内容引用关系 + +板块引用的产品、文章、媒体和路由写入 `content_reference`: + +```text +site_id +source_revision_id +source_block_id +reference_type +target_content_id +target_media_id +target_route_id +``` + +用途: + +- 删除前影响分析。 +- 防止悬空引用。 +- 计算需要重建的页面。 +- 媒体垃圾回收。 +- 生成相关推荐和反向引用报告。 + +### 9.5 删除与下线 + +已发布内容不能直接物理删除。操作步骤: + +1. 显示引用页面和媒体影响。 +2. 选择保留页面、301/308、410或取消发布。 +3. 验证站内链接和 Sitemap。 +4. 创建新的内容和路由快照。 +5. 构建并发布。 +6. 达到保留期限后再清理无引用媒体。 + +### 9.6 并发编辑 + +所有草稿更新包含 revision/version。后台使用 ETag 或版本号进行乐观锁;即使只有一个账号,也要防止多标签页或重复请求覆盖较新的修改。 + +--- + +## 10. 内容、主题、板块与组件化 + +### 10.1 基本关系 + +```text +内容数据 → 板块实例 → 页面模板 → 主题渲染 → 静态页面 +``` + +- 内容保存业务数据。 +- 板块保存结构化展示数据。 +- 模板约束页面区域和允许的板块。 +- 主题决定最终 HTML、CSS、动画和响应式效果。 + +### 10.2 板块类型 + +全局板块:Header、Footer、顶部通知、全局 CTA、联系方式。 + +页面板块:Hero、富文本、图文、图库、Feature、数据指标、产品列表、文章列表、参数表、下载、FAQ、CTA。 + +模板系统板块:面包屑、产品主信息、产品参数、文章正文、列表分页、SEO Head。 + +站点专属板块:360 展示、工厂流程、经销商地图等。 + +Legacy HTML:只用于未完成结构化的历史页面,必须清洗、隔离并标记。 + +### 10.3 板块实例 + +```ts +interface BlockInstance> { + id: string; + type: string; + schemaVersion: number; + slotKey: string; + position: number; + variant?: string; + data: T; + settings?: { + anchorId?: string; + themeMode?: 'default' | 'light' | 'dark'; + spacing?: 'none' | 'small' | 'medium' | 'large'; + }; + visibility: { enabled: boolean; locales?: string[] }; +} +``` + +`slotKey` 支持 `main`、`sidebar`、`before_content`、`after_content` 等有限区域,不提供自由坐标布局。 + +### 10.4 Schema 驱动后台 + +每个板块提供: + +- JSON Schema:字段、类型、长度、必填和枚举。 +- UI Schema:后台控件、标签、媒体选择和内部链接选择。 +- Schema Version:板块升级和数据迁移。 + +前端表单和后端保存均执行校验。生产构建遇到未知或不兼容板块时必须失败。 + +### 10.5 四层组件复用 + +```text +第一层:数据契约与工具 +第二层:无样式基础组件 +第三层:Headless 业务逻辑 +第四层:主题展示组件 +``` + +前三层公共复用,第四层由主题独立实现。 + +公共包: + +```text +content-contracts +block-contracts +theme-runtime +ui-primitives +headless-components +content-resolvers +media-components +seo-components +form-runtime +design-tokens +``` + +复用边界: + +| 能力 | 公共复用 | 主题独立 | +|---|---:|---:| +| 数据类型、Schema、迁移 | 是 | 否 | +| URL、SEO和媒体解析 | 是 | 可配置 | +| 菜单树、分页、表单状态 | 是 | 展示独立 | +| 产品和文章查询 | 是 | 卡片独立 | +| Hero内容协议 | 是 | 渲染独立 | +| Header/Footer | 逻辑可复用 | 结构与视觉独立 | +| 页面模板、动画、品牌样式 | 否 | 是 | + +主题之间禁止直接引用对方内部组件。两个主题重复出现的非视觉逻辑提取到公共包,纯视觉实现留在主题。 + +### 10.6 主题清单 + +主题 manifest 声明: + +- 主题 ID、版本和构建引擎。 +- 兼容的 runtime 和公共包版本。 +- 模板及入口文件。 +- 每个模板允许、必需和最大数量的板块。 +- 板块 renderer、schema 和 variant。 +- 站点配置 schema。 +- 可编辑区域。 + +### 10.7 主题版本 + +- 公共包遵循语义化版本。 +- 破坏性变更提供迁移函数或兼容层。 +- Release 锁定主题、公共包和构建镜像版本。 +- 两套示范主题自动执行契约和截图回归。 +- 主题切换前生成兼容报告,缺少 renderer 时禁止生产构建。 + +详细实现可参考 `SiteForge_主题与板块设计方案_V1.0.md`,V3 中与该文档冲突时以本方案为准。 + +--- + +## 11. SEO 迁移 + +### 11.1 三套数据 + +```text +source_raw → source_rendered → target_build +``` + +- `source_raw`:数据库、插件、API中的数据。 +- `source_rendered`:旧站最终 HTML 和响应头。 +- `target_build`:新站预览环境真实 HTTP 结果。 + +最终对外行为以 `source_rendered` 作为重要基线,插件字段用于补充来源和解释差异。 + +### 11.2 对比字段 + +- Title、Description。 +- Canonical。 +- Robots Meta与响应头。 +- H1/H2和正文摘要。 +- Hreflang。 +- Open Graph和Twitter Card。 +- JSON-LD。 +- Sitemap收录。 +- 图片alt。 +- 内部链接。 +- 发布和更新时间。 +- 面包屑。 + +### 11.3 严重级别 + +| 级别 | 示例 | 处理 | +|---|---|---| +| P0 | 关键 URL 缺失、全站 noindex、Canonical 错域、重定向循环 | 阻止发布 | +| P1 | 核心正文缺失、关键 Title 未批准改变、大量资源 404 | 修复或记录例外后确认 | +| P2 | 次要 OG、ALT、非核心结构化数据差异 | 可带记录发布 | +| P3 | 性能、语义和图片优化建议 | 进入优化清单 | + +原站存在 SEO 错误时,迁移和优化分开记录;只有超级管理员明确确认后才在迁移中修复。 + +--- + +## 12. 媒体与静态资源 + +### 12.1 媒体数据 + +- 来源 URL和旧路径。 +- MIME、扩展名、尺寸和大小。 +- SHA-256。 +- 原件位置和衍生资源。 +- alt、caption和语言。 +- 引用内容和板块。 +- 迁移、验证和安全状态。 + +### 12.2 处理策略 + +- 保存原始二进制,不只保存远程地址。 +- 已索引或被外链引用的旧路径优先保持。 +- WebP/AVIF和缩略图作为衍生资源。 +- 处理 `src`、`srcset`、懒加载、CSS URL、PDF、SVG、字体和视频封面。 +- 不通过全局字符串替换修改 HTML 引用。 +- 清理无引用媒体前执行引用和 URL 影响分析。 + +### 12.3 安全 + +- 限制类型、大小、文件数量和解压总量。 +- 防 ZIP/TAR目录穿越和压缩炸弹。 +- SVG/HTML净化。 +- 禁止可执行文件进入公开产物。 +- 对上传附件执行恶意文件和敏感信息扫描。 + +--- + +## 13. 构建系统 + +### 13.1 构建输入快照 + +构建开始时创建不可变 `build_input_snapshot`: + +```text +site_id +environment_id +content_snapshot_id +route_snapshot_id +seo_snapshot_id +asset_manifest_id +theme_version_id +site_config_version +dependency_lock_hash +source_commit +runtime_version +container_image_digest +locale +timezone +build_timestamp +``` + +构建过程中发生的新编辑不进入本次 build。 + +### 13.2 可复现构建 + +- 使用锁定依赖和固定运行时。 +- 构建镜像按 digest 固定。 +- 外部资源必须下载并固定哈希,或明确列入允许的远程依赖。 +- 时间、时区、随机数和排序规则固定。 +- 输出 manifest 和 checksums。 +- 历史 release 回滚直接恢复产物,不重新构建。 + +### 13.3 隔离执行 + +构建和第三方适配器运行在隔离容器/沙箱中: + +- 只读代码和输入快照。 +- 独立可写临时目录。 +- CPU、内存、磁盘和执行时长限制。 +- 默认禁止任意网络访问,按任务白名单开放。 +- 不挂载控制面密钥和主数据库凭据。 +- 构建完成后销毁临时环境。 + +### 13.4 构建并发 + +- 同站点同环境只允许一个发布构建持有租约。 +- 普通预览构建可以排队或按限额并行。 +- 每个 Job 有唯一幂等键。 +- 旧构建完成时如果输入版本已经落后,不得自动发布。 +- 取消只在定义好的安全点生效。 +- Worker 通过心跳续租,失联后任务可安全恢复。 + +### 13.5 构建产物 + +```text +releases// + dist/ + build-input.json + build-manifest.json + route-manifest.json + asset-manifest.json + validation-summary.json + migration-report.html + checksums.txt +``` + +### 13.6 全量与增量 + +V1 使用按站全量构建。全局板块、主题或路由变化均全量构建。V1.1 根据 `content_reference` 建立依赖图,再实现选择性重建。 + +--- + +## 14. 发布、原子切换与回滚 + +### 14.1 发布状态机 + +```text +created +→ snapshot_locked +→ building +→ validating +→ ready_to_publish +→ publishing +→ verifying +→ published +``` + +异常状态:`failed`、`cancelled`、`rolled_back`、`partially_deployed`。 + +### 14.2 发布锁 + +生产发布获取 `environment_publish_lock`。切换时使用当前 `active_release_id` 做比较并交换:只有当前线上版本与启动发布时一致,才能切换到新 release,避免旧任务覆盖新版本。 + +### 14.3 发布步骤 + +1. 锁定构建输入。 +2. 在隔离环境生成 release。 +3. 执行本地校验。 +4. 上传不可变版本目录。 +5. 校验文件数量、大小和哈希。 +6. 使用临时入口执行真实 HTTP 验收。 +7. 获取发布锁并再次检查当前版本。 +8. 原子切换静态目录和路由规则。 +9. 刷新必要 CDN 缓存。 +10. 立即执行生产冒烟。 +11. 标记 `published` 或执行补偿/回滚。 + +### 14.4 对象存储注意事项 + +对象存储根目录直接同步不一定原子。优先使用版本前缀加入口指针/部署版本切换;HTML和路由规则作为同一部署事务处理。静态指纹资源长期缓存,HTML、Sitemap和非指纹文件按变更策略刷新。 + +### 14.5 回滚 + +回滚切换到上一个已验证 release,包括: + +- 静态文件。 +- 路由规则。 +- 响应头配置。 +- 必要的动态服务配置版本。 +- CDN缓存策略。 + +首个试点正式上线前必须完成一次生产等价环境回滚演练。 + +--- + +## 15. 动态能力 + +### 15.1 处置原则 + +每个旧站动态功能必须选择: + +```text +保留原服务 / 新 API 承接 / 第三方替换 / 静态降级 / 正式下线 +``` + +没有结论的动态功能不能视为迁移完成。 + +### 15.2 功能方案 + +| 功能 | 推荐实现 | +|---|---| +| 联系/询价 | 独立 Form API + 邮件/CRM | +| 小站搜索 | 构建时生成客户端索引 | +| 大站搜索 | 独立搜索服务 | +| 分析统计 | 站点配置化接入 | +| 下载统计 | CDN/边缘日志或下载 API | +| 多语言 | V1.1 locale内容 + hreflang + 路由规则 | +| 定时发布 | V1.1调度构建与部署 | +| 会员/订单/支付 | 独立业务系统 | +| 复杂筛选 | 客户端索引或搜索 API | + +### 15.3 Form API 要求 + +- 站点和来源域名白名单。 +- CSRF/Origin检查。 +- 验证码、IP/指纹限流和反垃圾。 +- 请求幂等键,防止重复询盘。 +- 字段 schema 和长度限制。 +- 隐私同意及政策版本记录。 +- 敏感字段加密和日志脱敏。 +- 数据保留、导出和删除策略。 +- 邮件/CRM WebHook重试与死信队列。 +- 附件类型、大小和恶意文件检查。 +- 提交已接收、转发成功和转发失败分开记录。 + +--- + +## 16. 管理后台 + +### 16.1 前端技术选型 + +管理后台确定采用 **Art Design Pro** 作为工程底座,其底层技术为 **Vue 3 + TypeScript + Element Plus**。三者不是二选一关系: + +- Art Design Pro:后台布局、菜单、标签页、登录页面、基础工程规范和通用页面框架。 +- Vue 3 + TypeScript:业务页面、状态管理、组合式逻辑和类型约束。 +- Element Plus:表单、表格、弹窗、分页、上传、树形控件等基础 UI。 + +V1 只有超级管理员,不启用 Art Design Pro 中复杂的角色、按钮和动态权限配置。路由和菜单由系统模块固定声明,登录后拥有全部功能。 + +后台建议沿用底座已有的 Vue Router、Pinia、请求封装、国际化和构建工具;具体依赖版本在项目初始化时锁定。业务 API 类型由共享契约或 OpenAPI 生成,避免前后端各自维护重复接口类型。 + +管理后台主题只影响 SiteForge 控制台,不得与生产网站的 Astro 主题系统混用。 + +### 16.2 信息架构 + +| 菜单 | 主要能力 | +|---|---| +| 工作台 | 站点状态、迁移进度、失败任务、线上告警 | +| 网站 | 域名、环境、语言、主题、部署目标 | +| 数据源 | 连接、凭据引用、导出文件、能力探测 | +| 扫描与导入 | URL 来源、任务、差量、冲突和失败 | +| 数据映射 | 源字段、标准字段、转换、未识别字段 | +| 内容 | 页面、产品、新闻、分类、品牌、菜单 | +| 页面板块 | 模板、板块、顺序、区域、预览 | +| 媒体 | 原件、衍生、引用、旧路径和安全状态 | +| URL | 路径、状态、跳转、冲突、部署兼容 | +| SEO | 元信息、Sitemap、结构化数据、差异 | +| 主题 | 主题版本、模板、组件兼容、预览 | +| 构建 | 输入快照、任务、日志、产物 | +| 测试 | URL、SEO、内容、资源、视觉报告 | +| 发布 | Release、发布确认、部署、回滚 | +| 系统 | 超管账号、会话、密钥、备份、日志、通知 | + +页面编辑器仅提供板块新增、复制、排序、隐藏、删除、字段编辑、媒体/内容引用和静态预览,不提供自由画布和任意 CSS/JavaScript。 + +--- + +## 17. 任务队列与可观测性 + +### 17.1 队列类型 + +- Probe +- Crawl +- Import +- Normalize +- Asset +- Build +- Validate +- Deploy +- Cache Purge +- Form Delivery + +### 17.2 任务规则 + +- Job ID和幂等键。 +- 最大重试次数。 +- 指数退避和随机抖动。 +- 可重试错误与永久错误分类。 +- Worker心跳和租约。 +- 超时和失联任务回收。 +- 死信队列与人工重放。 +- 每站点并发、抓取速率和资源配额。 +- 取消和恢复检查点。 +- 外部副作用记录,避免重复发送或重复部署。 + +### 17.3 关键指标 + +- 队列长度、等待时间和失败率。 +- 扫描页面数、成功率和每分钟请求。 +- 导入新增/更新/冲突/失败数量。 +- 构建时长、页面数、产物大小。 +- 验收问题分布。 +- 发布成功率和回滚次数。 +- 生产 4xx/5xx、关键 URL 可用性。 +- 表单接收与转发成功率。 +- 存储、数据库和备份状态。 + +### 17.4 告警 + +- 关键任务连续失败。 +- 队列长时间无消费者。 +- 构建或发布超时。 +- 关键 URL不可访问。 +- 生产出现全站 noindex/Canonical错误。 +- 表单转发积压。 +- 备份失败或恢复验证失败。 +- 存储容量接近阈值。 + +--- + +## 18. 自动验收与发布门禁 + +### 18.1 测试矩阵 + +| 维度 | 自动检查 | 通过条件 | +|---|---|---| +| URL来源 | 多来源合并与去重 | 未处理 URL 为0或有明确例外 | +| HTTP行为 | 状态、跳转、Header、Content-Type | 与路由注册表一致 | +| SEO | Title、Canonical、Robots、Hreflang、JSON-LD | P0为0,P1修复或记录例外 | +| 内容 | 标题、正文摘要、产品核心字段 | 满足站点验收清单 | +| 引用 | 内容、媒体、路由反向关系 | 无悬空关键引用 | +| 媒体 | 文件、MIME、哈希、尺寸 | 无未处理关键缺失 | +| 内链 | href/src/srcset/CSS URL | 无未处理内部死链 | +| 主题契约 | 模板、板块、schema、renderer | 全部兼容 | +| 视觉 | 典型页面桌面/移动截图 | 新设计基线审核通过 | +| 可访问性 | 语义、键盘、焦点、对比度 | 达到项目基线 | +| 动态功能 | 表单、搜索和外部服务冒烟 | 每项成功用例通过 | +| 性能 | Lighthouse/Web Vitals | 达到各站约定目标 | +| 安全 | 敏感文件、依赖、CSP、恶意内容 | 无高危问题 | +| 部署 | 目标能力和路由预检 | 无关键不兼容 | +| 回滚 | 完整 release 恢复 | 演练通过 | + +### 18.2 强制阻止发布 + +- 最终差量同步未完成。 +- 关键 URL 未映射或意外 404/500。 +- 重定向循环或关键查询路由无法实现。 +- 生产页面存在错误 noindex、Canonical或预览域名。 +- 大量核心内容、媒体或引用缺失。 +- 主题缺少板块渲染器或 schema 不兼容。 +- 部署目标不支持关键路由行为。 +- 构建输入快照不完整或版本已过期。 +- 当前环境存在其他发布任务。 +- Release 无法回滚。 +- 未通过超级管理员发布确认。 + +### 18.3 报告 + +```text +inventory.csv +route-diff.csv +seo-diff.csv +content-diff.csv +reference-diff.csv +assets-diff.csv +broken-links.csv +deployment-capability.json +issues.json +screenshots/ +summary.html +``` + +--- + +## 19. 安全设计 + +### 19.1 认证与会话 + +- 超级管理员强密码和MFA。 +- 密码使用成熟算法加盐哈希。 +- 短期会话、HttpOnly/Secure/SameSite Cookie。 +- CSRF防护。 +- 登录限流和异常提醒。 +- 恢复码离线保存。 +- 高风险操作重新验证。 + +### 19.2 凭据 + +- 数据源和部署凭据进入密钥管理。 +- 数据库只保存引用,不保存可见明文。 +- 优先只读凭据。 +- 日志自动脱敏。 +- 密钥支持轮换和撤销。 + +### 19.3 SSRF与采集 + +- 域名、协议和端口白名单。 +- DNS解析后检查IP。 +- 每次重定向重新校验。 +- 拒绝内网、回环、链路本地和云元数据地址。 +- 受限网络出口和请求速率。 + +### 19.4 供应链与构建 + +- 锁定依赖和运行时。 +- 依赖漏洞和许可证扫描。 +- 生成软件物料清单。 +- 主题/适配器来源和版本可追溯。 +- 构建沙箱默认无控制面密钥。 +- 发布产物执行敏感信息扫描。 + +### 19.5 Web安全 + +- CSP及必要安全响应头。 +- Legacy HTML和SVG净化。 +- 外部脚本、iframe和域名白名单。 +- 预览站访问控制和禁止索引。 +- 表单输入校验、限流和隐私保护。 + +--- + +## 20. 备份、恢复与数据保留 + +### 20.1 备份对象 + +- PostgreSQL。 +- 对象存储中的原始快照和媒体。 +- 构建 release 和报告。 +- 路由与部署规则。 +- 加密密钥配置和恢复材料。 +- 系统配置及审计日志。 + +### 20.2 建议目标 + +首版建议基线,可按实际业务调整: + +- PostgreSQL RPO:24小时以内;关键迁移/发布窗口前额外备份。 +- 控制面 RTO:8小时以内。 +- 已发布静态站 RTO:1小时以内,通过现有 release 恢复。 +- 至少保留最近30天数据库备份。 +- 生产 release 至少保留最近10个和所有人工标记版本。 +- 原始迁移快照保留至站点迁移验收完成后的约定期限。 + +### 20.3 一致性与演练 + +数据库备份记录对应的对象存储清单和密钥版本。恢复时按同一备份点恢复数据库、对象和配置。首个试点上线前完成一次恢复演练,此后至少每季度验证一次。 + +### 20.4 数据删除 + +制定原始 SQL、个人数据、表单数据、日志和媒体的保留期限。清理任务先生成预览清单,超级管理员确认后执行,并保留删除审计。 + +--- + +## 21. 非功能要求 + +### 21.1 性能 + +- 管理后台常用查询应分页。 +- 大型导入和构建全部异步执行。 +- 静态页面按站点设定性能目标。 +- 图片包含尺寸并生成适配资源。 +- 客户端 JavaScript 按需加载。 + +### 21.2 可访问性 + +建议以 WCAG 2.1 AA 为基础目标:语义结构、键盘操作、焦点状态、颜色对比、表单标签、替代文本和减少动画偏好。 + +### 21.3 浏览器 + +项目启动时确定支持矩阵,默认支持主流浏览器最近两个稳定版本及当前主流移动浏览器。特殊旧浏览器按站点单独评估。 + +### 21.4 配额 + +每站配置: + +- 最大 URL 数。 +- 最大抓取深度和并发。 +- 最大媒体和单文件大小。 +- 最大构建时长和产物大小。 +- 预览版本和 release 保留数量。 + +超出配额时停止任务并给出明确原因,不自动无限消耗资源。 + +--- + +## 22. 技术栈与仓库结构 + +### 22.1 技术栈 + +| 层级 | 技术 | +|---|---| +| 后台 | Art Design Pro(Vue 3 + TypeScript + Element Plus) | +| API | NestJS + TypeScript | +| 数据库 | PostgreSQL | +| ORM | 预研阶段在 Prisma与团队既有方案中确定,并记录ADR | +| 队列 | Redis + BullMQ | +| 抓取 | Crawlee/Undici + Cheerio | +| JS渲染 | Playwright | +| 静态构建 | Astro + TypeScript | +| Schema | JSON Schema + Ajv | +| 媒体 | Sharp | +| 对象存储 | S3兼容存储/MinIO | +| 运行 | Docker Compose | +| 测试 | 单元、契约、集成、Playwright E2E、HTTP验收 | + +### 22.2 仓库 + +```text +siteforge/ + apps/ + admin/ + api/ + worker/ + builder/ + form-api/ + packages/ + contracts/ + content-contracts/ + block-contracts/ + adapter-sdk/ + adapter-wordpress/ + adapter-generic-web/ + route-engine/ + seo-engine/ + asset-engine/ + validation-engine/ + deployment-engine/ + theme-runtime/ + ui-primitives/ + headless-components/ + content-resolvers/ + media-components/ + seo-components/ + form-runtime/ + design-tokens/ + themes/ + pilot-wordpress/ + pilot-secondary/ + infra/ + docker/ + nginx/ + database/ + monitoring/ + docs/ + adr/ + api/ + runbooks/ + migrations/ + tests/ + fixtures/ + contract/ + integration/ + e2e/ +``` + +### 22.3 ADR 决策记录 + +以下决策必须形成 ADR: + +- ORM选择。 +- 对象存储与生产部署目标。 +- URL 编码和文件映射规则。 +- 主题/公共包版本策略。 +- 富文本与 HTML 净化方案。 +- 构建沙箱实现。 +- Form API 数据保留和邮件/CRM策略。 + +--- + +## 23. API 范围 + +```text +POST /api/v1/auth/login +POST /api/v1/auth/mfa/verify +POST /api/v1/auth/logout +GET /api/v1/auth/sessions +DELETE /api/v1/auth/sessions/:id + +POST /api/v1/sites +GET /api/v1/sites/:siteId +POST /api/v1/sites/:siteId/connections +POST /api/v1/sites/:siteId/scans +POST /api/v1/sites/:siteId/imports +POST /api/v1/sites/:siteId/imports/:id/diff + +GET /api/v1/sites/:siteId/content +PATCH /api/v1/sites/:siteId/content/:contentId +GET /api/v1/sites/:siteId/content/:contentId/references + +GET /api/v1/sites/:siteId/routes +POST /api/v1/sites/:siteId/routes/validate +GET /api/v1/sites/:siteId/seo/diff + +GET /api/v1/themes +GET /api/v1/themes/:themeId/manifest +PUT /api/v1/sites/:siteId/theme + +POST /api/v1/sites/:siteId/builds +GET /api/v1/sites/:siteId/builds/:buildId +POST /api/v1/sites/:siteId/validations + +POST /api/v1/sites/:siteId/releases/:releaseId/publish +POST /api/v1/sites/:siteId/deployments/:deploymentId/rollback +GET /api/v1/sites/:siteId/reports/:type +``` + +所有站点 API 在服务端验证登录状态、`site_id`、对象归属、版本号和并发条件。 + +--- + +## 24. 测试策略 + +### 24.1 单元测试 + +- URL规范化辅助键。 +- 重定向循环检测。 +- SEO差异分类。 +- Schema验证和板块迁移。 +- 内容引用和删除影响。 +- checksum和差量判断。 +- 部署能力匹配。 + +### 24.2 契约测试 + +- 每个来源适配器使用相同 fixture 契约。 +- 每个部署适配器满足 capability 接口。 +- 每个主题 manifest、模板、板块和 renderer 完整。 +- API DTO与事件版本兼容。 + +### 24.3 集成测试 + +- WordPress导入到内容修订。 +- 内容到Astro静态输出。 +- Route Manifest到Nginx/CDN规则。 +- 构建、校验、发布和回滚。 +- Form API到邮件/CRM和死信重放。 + +### 24.4 测试夹具 + +至少覆盖: + +- WordPress默认固定链接。 +- `.html`和`.php`路径。 +- 中文/Unicode路径。 +- 大小写冲突。 +- 尾斜杠混用。 +- 查询参数入口。 +- 多级分类和分页。 +- Yoast/Rank Math。 +- ACF/Gutenberg。 +- 重定向链和媒体重定向。 +- JS渲染页面。 +- 不支持板块和板块版本升级。 + +### 24.5 视觉测试 + +新旧站只比较内容和关键结构,不做像素一致要求。新主题建立自己的视觉基线,后续主题升级与该基线做截图回归。 + +--- + +## 25. 项目阶段与排期 + +以下按约5人核心团队估算:1名项目/产品负责人、2名前后端工程师、1名迁移/数据工程师、1名测试/运维,设计师阶段性参与。 + +### 阶段0:真实数据盘点与技术预研(第1–2周) + +任务: + +- 选择WordPress试点和第二来源试点。 +- 获取数据库、WXR、uploads、日志、Sitemap和服务器规则。 +- 建立URL/SEO/功能初始基线。 +- 验证重点插件、页面构建器和路径类型。 +- 确定ORM、存储、部署和构建沙箱ADR。 + +交付:试点评估报告、来源能力报告、风险清单、字段样本、最终V1范围与校准排期。 + +### 阶段1:平台骨架与安全基础(第3–5周) + +任务: + +- Monorepo、环境、CI。 +- 超管登录、MFA、会话和日志。 +- PostgreSQL、Redis、对象存储。 +- 站点、环境、快照、任务和密钥引用。 +- Worker租约、重试和死信框架。 + +交付:可登录、创建站点、运行并观察后台任务。 + +### 阶段2:扫描、导入与URL/SEO基线(第6–9周) + +任务: + +- Sitemap/HTML/Playwright扫描。 +- WordPress REST/WXR/SQL/uploads导入。 +- 多来源URL合并。 +- 原始快照、差量同步和冲突处理。 +- 内容、媒体、URL和SEO核心模型。 + +交付:首站真实数据可重复导入,生成URL/SEO/内容清单。 + +### 阶段3:主题、板块和静态构建(第10–13周) + +任务: + +- Block Schema、模板和主题manifest。 +- 公共组件包。 +- 后台板块编辑。 +- 首套试点主题。 +- 隔离可复现构建。 +- 内容引用和删除影响分析。 + +交付:首站能从后台内容生成完整静态预览。 + +### 阶段4:第二主题、第二来源与动态功能(第14–16周) + +任务: + +- 第二套明显不同的主题。 +- 通用网页/第二来源适配。 +- 公共组件复用验证。 +- 表单或试点必需动态服务。 +- 目标部署适配器和能力预检。 + +交付:两个站点、两种来源、两套主题在同一平台运行。 + +### 阶段5:门禁、发布与生产化(第17–20周) + +任务: + +- URL/SEO/内容/媒体/视觉验收。 +- 发布锁、原子切换和CDN策略。 +- 回滚、监控、告警和备份恢复。 +- 最终差量同步和切站Runbook。 +- 上线彩排、正式切换和保护期。 + +交付:至少一个试点正式上线,两个试点均完成完整迁移与回滚闭环。 + +### 25.1 计划区间 + +建议按20–24周预留项目周期,目标20周,额外4周用于复杂插件、历史路径、内容清理和试点反馈。若团队少于4人,应减少第二来源范围或顺延工期。 + +--- + +## 26. 团队职责 + +这里是项目职责,不是系统角色: + +| 职能 | 责任 | +|---|---| +| 项目/产品 | 范围、优先级、试点协调和业务结论 | +| 架构/后端 | 数据、API、任务、构建、发布和安全 | +| 前端/主题 | 管理后台、组件包、主题和响应式页面 | +| 迁移/数据 | 扫描、适配器、字段映射、URL/SEO基线 | +| 测试/运维 | 自动验收、部署、监控、备份和回滚 | +| 设计 | 品牌规范、模板设计和视觉验收 | +| SEO/内容业务 | 提供线下确认,由超管记录结论 | + +系统内所有操作仍由超级管理员完成。 + +--- + +## 27. 试点资料清单 + +### 27.1 WordPress试点 + +- 域名、授权和主机信息。 +- WXR、SQL、网站目录和uploads。 +- 插件/主题列表及版本。 +- SEO插件、ACF/CPT和页面构建器信息。 +- Sitemap和服务器重写规则。 +- 访问日志、GSC、GA4落地页。 +- 重要页面和高流量页面。 +- 表单、搜索、多语言、会员、交易和第三方脚本。 +- DNS、CDN、证书和生产发布权限。 + +### 27.2 第二试点 + +- 非WordPress或只能从HTML/API/数据库迁移。 +- 页面结构与第一站明显不同。 +- 可验证独立主题和通用适配器。 +- 能提供足够数据和业务确认人。 + +### 27.3 设计资料 + +- Logo、字体、颜色和品牌规范。 +- 桌面/移动设计稿。 +- 页面类型和组件清单。 +- 内容优先级和典型页面。 +- 目标浏览器和性能要求。 + +--- + +## 28. 风险管理 + +| 风险 | 影响 | 应对 | +|---|---|---| +| 数据来源不完整 | 页面或字段遗漏 | 多来源URL全集、明确未知范围 | +| 迁移期间旧站继续更新 | 切站时丢内容 | 差量同步、冻结窗口、最终重扫 | +| 页面构建器复杂 | 无法自动结构化 | 原始数据保留、映射、Legacy兜底 | +| URL规则混合 | 404或错误跳转 | 注册表、部署能力预检、真实HTTP测试 | +| 部署目标能力不足 | 无法保持状态码和查询规则 | 路由编译器、Edge或更换目标 | +| 构建并发 | 旧版本覆盖新版本 | 输入快照、租约、CAS发布锁 | +| 主题过度通用 | 所有网站设计雷同 | 复用数据与逻辑,视觉独立 | +| 公共组件耦合 | 升级影响全部主题 | 语义版本、契约测试、截图回归 | +| 动态功能遗漏 | 表单/搜索失效 | 功能处置表和上线冒烟 | +| 构建代码不可信 | 泄密或破坏环境 | 隔离容器、限额、默认断网 | +| 超管账号丢失 | 无法管理系统 | MFA恢复码、离线备份、恢复Runbook | +| 备份不可恢复 | 故障时数据永久丢失 | RPO/RTO、关联清单、季度演练 | +| 范围扩张 | V1延期 | 版本矩阵和变更评审 | +| SEO波动 | 搜索流量下降 | 基线、门禁、监测和快速回滚 | + +--- + +## 29. 最终交付物 + +### 29.1 软件 + +- SiteForge管理后台。 +- API、数据库迁移和Worker。 +- 超管认证、MFA、会话和操作日志。 +- WordPress与通用网页适配器。 +- URL、SEO、内容、媒体和引用引擎。 +- 主题SDK、组件公共包和两套主题。 +- Astro隔离构建系统。 +- 路由编译和部署适配器。 +- 验收报告、发布锁、回滚和监控。 +- Form API或试点动态能力。 +- Docker、Nginx、备份和运维配置。 + +### 29.2 文档 + +- 产品功能与后台说明。 +- 系统架构和ADR。 +- 数据库字典和ER图。 +- API、队列和状态机协议。 +- 适配器SDK。 +- 主题、板块和组件开发规范。 +- URL/SEO迁移规范。 +- 安全和数据保留规范。 +- 部署、监控、备份和恢复手册。 +- 切站与回滚Runbook。 +- 自动测试和验收模板。 +- 两个试点迁移报告。 + +### 29.3 最终验收流程 + +两个试点能够完成: + +```text +多来源盘点 +→ 全量导入 +→ 标准化与映射 +→ 独立主题 +→ 差量同步 +→ URL/SEO冻结 +→ 静态构建 +→ 自动门禁 +→ 目标环境预检 +→ 发布确认 +→ 原子发布 +→ 生产验证 +→ 回滚演练 +``` + +所有未支持内容和功能必须进入异常清单,不能静默遗漏。 + +--- + +## 30. 立项前需要确认 + +1. 首个WordPress试点站。 +2. 第二个不同来源试点站。 +3. 两个站点的页面数、媒体量、语言和动态功能。 +4. 是否能提供SQL、uploads、访问日志、GSC和服务器规则。 +5. 生产主要部署到Nginx还是对象存储/CDN。 +6. 表单提交到邮箱、CRM还是两者。 +7. V1是否只做单语言和手动发布。 +8. 目标RPO、RTO和旧站保留期。 +9. 品牌设计稿和页面类型是否已经确定。 +10. 超级管理员账号和恢复材料由谁保管。 + +--- + +## 31. 立即执行计划 + +1. 收集两个试点资料并建立只读备份。 +2. 从Sitemap、数据库、日志、GSC和业务清单合并URL初始全集。 +3. 建立10–20个真实页面的最小纵向PoC。 +4. 验证:导入 → 标准化 → URL/SEO → 主题渲染 → 静态发布。 +5. 确定ORM、部署目标、构建沙箱和Form API ADR。 +6. 冻结V1范围矩阵和验收清单。 +7. 再进入20周左右的正式开发与试点实施。 + +--- + +## 32. 最终结论 + +本方案将SiteForge定位为“多站点迁移与静态发布控制平台”。系统统一的是数据、URL、SEO、组件协议、构建和发布,不强制统一每个网站的设计。 + +项目成功的关键不只是采集页面,而是: + +- 从多来源建立可信URL全集。 +- 迁移期间持续差量同步,切站时不丢数据。 +- 使用可追溯的内容和路由快照。 +- 用公共数据/逻辑组件提高复用,同时保留主题视觉独立。 +- 在目标部署环境验证真实HTTP行为。 +- 通过构建锁、发布锁和不可变release避免版本错乱。 +- 通过门禁、监控、备份和回滚控制上线风险。 + +按本方案完成两个差异化试点后,后续网站可以复用迁移、内容、URL、SEO、构建、测试和发布能力,把新增站点的主要工作收敛到数据映射、异常处理和独立主题设计。 + +--- + +## 附录A:发布前检查表 + +| 检查项 | 结果 | 备注 | +|---|---|---| +| 旧站写入已冻结 | | | +| 最终差量同步完成 | | | +| URL多来源基线完成 | | | +| 关键URL状态与跳转通过 | | | +| SEO P0/P1处理完成 | | | +| 内容和媒体抽检通过 | | | +| 主题/板块契约通过 | | | +| 表单/搜索等动态功能通过 | | | +| 部署能力预检通过 | | | +| 构建输入快照锁定 | | | +| 生产冒烟脚本准备 | | | +| 回滚版本和脚本确认 | | | +| 数据库/对象存储备份完成 | | | +| 超级管理员完成发布确认 | | | + +## 附录B:核心状态机 + +内容: + +```text +draft → ready_to_publish → published → archived +``` + +迁移记录: + +```text +raw → normalized → needs_review → verified +``` + +构建发布: + +```text +created → snapshot_locked → building → validating +→ ready_to_publish → publishing → verifying → published +``` + +任务异常: + +```text +failed / cancelled / dead_lettered / partially_deployed / rolled_back +``` + +## 附录C:官方实现参考 + +- WordPress REST API: +- WordPress WXR: +- WP-CLI export: +- Astro路由: +- Google不变URL的站点迁移: +- Google URL变更迁移: +- OWASP SSRF防护: + +> 框架版本、插件兼容性、部署供应商能力、项目周期和RPO/RTO,应在阶段0完成真实试点盘点后最终确认。 + +> 对应的详细Sprint、任务分解、依赖、验收门槛和上线时间线,见 `SiteForge_项目实施计划_V1.0.md`。 diff --git a/SiteForge_现有CMS项目复用评估_V1.0.md b/SiteForge_现有CMS项目复用评估_V1.0.md new file mode 100644 index 0000000..868832e --- /dev/null +++ b/SiteForge_现有CMS项目复用评估_V1.0.md @@ -0,0 +1,552 @@ +# SiteForge 现有 CMS 项目复用评估 V1.0 + +> 评估对象:`D:\project\cms` +> 目标项目:`D:\project\cms-one`(SiteForge) +> 评估日期:2026-10-20 +> 依据:现有源码、数据库 Schema、测试、构建脚本、基础设施配置,以及 SiteForge V3.0 方案与实施计划。 + +--- + +## 1. 结论 + +`D:\project\cms` 不是简单样例,而是一个已经具备管理后台、控制 API、WordPress 迁移、内容模型、Astro 静态站运行时和基础测试的早期平台原型。 + +它与 SiteForge 的目标高度同源,适合作为**代码底座和经验来源**,不建议把 SiteForge 完全从零重写。但它当前仍然是“单站 MVP 向平台化演进”的状态,部分文档设计明显领先于实际代码,因此不能整体原样搬入。 + +推荐原则: + +1. SiteForge V3.0 方案继续作为当前项目的唯一产品与架构基线。 +2. 选择性继承 `cms` 中已经验证的代码,不继承其过时的权限、发布、路由和数据边界。 +3. 优先复用迁移解析、内容版本、管理后台壳、Astro 组件、测试夹具等高价值资产。 +4. 对认证、发布、路由注册、主题架构、媒体安全和表单服务进行结构性重构。 +5. 不复制缓存、依赖目录、构建产物、真实客户数据和历史存储文件。 + +--- + +## 2. 当前项目可以直接参考或复用的部分 + +### 2.1 Monorepo 工程骨架 + +来源: + +- `D:\project\cms\package.json` +- `D:\project\cms\pnpm-workspace.yaml` +- `D:\project\cms\turbo.json` +- `D:\project\cms\.github\workflows` + +可复用内容: + +- pnpm Workspace + Turborepo 的项目组织方式。 +- 管理后台、控制 API、构建 Worker、站点运行时和公共包的目录边界。 +- TypeScript、Vitest、CI 的基础配置。 +- 统一执行 `typecheck`、`test`、`build` 的任务编排。 + +需要调整: + +- CI 安装应使用冻结锁文件,而不是 `--no-frozen-lockfile`。 +- 增加数据库迁移校验、OpenAPI 契约校验、静态站质量门禁、安全扫描和产物校验。 +- 不复制 `node_modules`、`.turbo`、`.data`、本地日志和构建输出。 + +复用等级:**高,可以直接作为工程骨架参考。** + +### 2.2 Art Design Pro 管理后台基础 + +来源:`D:\project\cms\apps\admin-web` + +已有能力: + +- Vue 3 + TypeScript + Element Plus。 +- Art Design Pro 布局、菜单、路由、Pinia、Axios 和通用组件。 +- 站点列表、站点管理、内容管理、媒体、导航、设置、线索和迁移页面。 +- WordPress 迁移的步骤式界面。 + +建议保留: + +- 登录后主布局、导航、标签页、请求封装、异常处理和基础表格表单组件。 +- 站点切换、站点列表、迁移向导和媒体选择器的交互结构。 +- Element Plus 设计体系以及 Art Design Pro 已有的工程规范。 + +必须精简: + +- 删除注册、找回密码、动态权限演示和多角色菜单逻辑。 +- 用户角色只保留一个全局 `super_admin`,不设计复杂 RBAC。 +- 清理仪表盘、电商演示、Mock 页面和无关组件。 +- 将体积过大的站点管理页面拆成独立领域页面和复用组件。 +- 内容表单由硬编码逐步改为 Schema 驱动。 +- 复用前确认 Art Design Pro 及第三方资源的许可证适用范围。 + +复用等级:**高,建议直接继承后台壳和通用能力,业务页面按新方案重构。** + +### 2.3 NestJS + Fastify + Drizzle 后端基础 + +来源:`D:\project\cms\services\control-api` + +已有模块: + +- 认证。 +- 站点管理。 +- 内容类型、内容条目和内容版本。 +- 媒体管理。 +- WordPress 迁移。 +- 线索管理。 +- 构建触发。 + +可复用内容: + +- NestJS 模块化结构和 Fastify 适配。 +- Drizzle + PostgreSQL 的访问方式。 +- Zod 输入校验思路。 +- 显式 `site_id` 上下文和站点隔离测试。 +- 内容版本不可变、草稿与发布版本分离的基础设计。 +- 站点模板初始化和默认导航生成逻辑。 + +需要重构: + +- 用户表当前为站点级并带历史角色字段,应改为平台级单超管模型。 +- 自制 HMAC Token 缺少成熟的过期、刷新、撤销和 MFA 机制,应替换。 +- 审计日志、发布记录、构建任务和路由记录需要成为正式数据表,而不是内存或 JSON 附属数据。 +- API 应补齐 OpenAPI、统一错误码、幂等键、操作审计和敏感操作二次确认。 + +复用等级:**高,适合作为后端起点,但认证和发布领域不可原样沿用。** + +### 2.4 WordPress REST/WXR 迁移能力 + +来源: + +- `D:\project\cms\services\control-api\src\migration` +- `D:\project\cms\apps\admin-web\src\views\sites\migrate-tab.vue` +- `D:\project\cms\tests` + +已有能力: + +- WordPress REST API 拉取。 +- WXR 文件解析。 +- 文章、产品等内容转换为中间结构。 +- 媒体下载、去重和关联。 +- 类型映射、迁移预览、批次导入和结果报告。 +- 基于旧地址生成部分重定向。 +- 幂等迁移和相关端到端测试。 + +这是旧项目中最值得保留的资产之一。现有文档还记录了多个真实网站迁移规模,说明相关代码不是纯概念设计。 + +必须调整: + +- 迁移后不能自动发布,必须进入“导入批次 → 校验 → 人工审核 → 预览 → 发布”的流程。 +- 旧 URL 不能只保存在 `siteSettings` JSON 中,应写入正式的 `route_registry`。 +- 页面、分类、标签、自定义文章类型、附件和 SEO 元数据需要统一映射策略。 +- 不能把无法映射的旧页面一律跳转首页,应进入冲突清单并人工处理。 +- 语言不能硬编码为 `en/es`,应使用站点 Locale 配置。 +- 增加断点续传、失败重试、限流、增量迁移、差异报告和可回滚批次。 +- 从 HTML 提取内容时增加 XSS 清理和资源地址标准化。 + +复用等级:**很高,保留解析器、UniversalRow 思路、媒体抓取和测试夹具,重做迁移编排。** + +### 2.5 内容模型、版本与导入幂等 + +来源: + +- `D:\project\cms\services\control-api\src\content` +- `D:\project\cms\services\control-api\src\db` +- `D:\project\cms\docs\contracts\导入模板V1.md` + +可复用内容: + +- 内容类型定义与内容条目分离。 +- 多语言内容记录。 +- 不可变版本记录。 +- 通过 `externalRef`、Slug 等键进行幂等合并。 +- 导入预校验、错误报告、状态机和 CSV 安全方面的设计经验。 + +建议作为 SiteForge 内容中台的起点,但需要补充: + +- 内容发布状态机。 +- 计划发布和撤回。 +- 关联内容完整性。 +- Slug/URL 冲突检测。 +- 导入批次与每条记录的来源追踪。 +- 批次级回滚。 +- 删除保护和引用检查。 + +复用等级:**高。** + +### 2.6 Astro 静态站运行时和页面质量门禁 + +来源:`D:\project\cms\runtimes\astro-site-runtime` + +已有能力: + +- Astro 5 静态站构建。 +- 首页、产品、分类、新闻、项目、关于、联系、支持和 Sitemap 页面。 +- Header、Footer、Hero、分页、表单、卡片网格、CTA 等组件。 +- 基础主题 Token。 +- Title、Description、Canonical、H1、内部链接、图片和 Sitemap 检查。 +- 重定向文件生成。 +- 版本化构建产物和基础回滚脚本。 + +可直接复用: + +- Astro 的构建基础。 +- 现有语义组件和样式 Token 的代码经验。 +- 门禁脚本和重定向生成器作为第一版基础。 +- SEO 页面输出和 Sitemap 生成思路。 + +必须重构: + +- 页面不能继续依赖硬编码站点配置和默认内容。 +- 编译器必须读取冻结的发布快照,而不是构建过程中读取变化中的在线数据。 +- 主题应拆成主题包、主题清单、Token、布局、区块注册表和站点配置。 +- 区块应由统一 Block Renderer 渲染,不能每个网站复制页面文件。 +- 构建产物切换要使用真正的原子发布机制,而不是删除后复制。 +- 门禁检查应使用 HTML 解析器而不是仅靠正则,并增加重复元数据、结构化数据、hreflang、孤链、重定向环、状态码和性能预算。 + +复用等级:**中高,适合作为静态运行时原型,不应直接作为最终主题架构。** + +### 2.7 主题 Token 和组件契约文档 + +来源: + +- `D:\project\cms\docs\contracts\ThemeToken契约V1.md` +- `D:\project\cms\docs\contracts\组件契约V1.md` + +值得吸收的内容: + +- 使用语义 Token,而不是在组件中直接写颜色和尺寸。 +- 主题变体、版本号和升级迁移规则。 +- 组件输入、插槽、SEO、可访问性和懒加载约束。 +- Hero、CardGrid、FeatureGrid、CTA 等组件的标准化思路。 +- WCAG 2.2 AA 作为可访问性目标。 + +与 SiteForge 的结合方式: + +- 把“组件契约”升级为正式的 Block Manifest。 +- 每个组件声明字段 Schema、默认值、允许的布局、SEO 行为、资源依赖和兼容版本。 +- 区分基础 UI 组件、内容区块、页面模板和站点主题四个层级。 +- 主题只能组合和覆盖,不得复制修改公共组件源码。 + +复用等级:**高,适合作为当前主题与组件规范的补充输入。** + +### 2.8 PostgreSQL、Redis、MinIO 基础设施 + +来源:`D:\project\cms\infrastructure` + +建议沿用: + +- PostgreSQL:业务数据库。 +- Redis:队列、分布式锁、缓存和限流。 +- MinIO:本地开发的 S3 兼容对象存储。 + +需要修改: + +- 生产环境使用受控对象存储或独立部署的兼容服务。 +- 镜像必须固定版本,不能长期使用 `latest`。 +- 开发密码不得用于生产。 +- 增加备份、恢复演练、生命周期、跨环境配置和 Secret 管理。 + +复用等级:**高。** + +--- + +## 3. 可以参考,但必须重构后使用的部分 + +### 3.1 认证与权限 + +旧项目保留了多角色和站点级用户的历史痕迹,而 SiteForge 已明确只需要一个超级管理员。 + +新设计应为: + +- 平台只有一个 `super_admin` 权限模型。 +- 可允许配置一个或少量超级管理员账号,但权限完全一致,不建立角色矩阵。 +- 使用成熟密码哈希、短期访问凭证、刷新/撤销机制、MFA、登录限流和安全日志。 +- 所有高风险操作记录操作者、站点、对象、前后差异、IP、User-Agent 和时间。 + +旧认证代码只能参考接口结构,不能作为生产安全方案直接使用。 + +### 3.2 构建、发布与回滚 + +旧项目当前主要问题: + +- 构建记录保存在进程内存中。 +- API 进程直接启动构建命令。 +- 构建锁仅在单进程内有效。 +- Build Worker 目录基本还是占位。 +- 发布替换并非严格原子操作。 +- 回滚没有完整持久化的 Release 记录。 + +SiteForge 应改为: + +1. API 创建持久化 Build Job。 +2. Redis/BullMQ Worker 异步消费。 +3. 同站点使用分布式发布锁。 +4. 构建读取不可变 Site Snapshot。 +5. 产物写入版本目录或对象存储。 +6. 门禁通过后原子切换当前 Release 指针。 +7. 每次发布记录输入快照、代码版本、主题版本、产物校验和和日志。 +8. 回滚只切换到已验证 Release,不重新现场构建。 + +可继承的是构建命令、Astro 产物组织和基础门禁;发布编排需要重做。 + +### 3.3 路由与 SEO + +旧项目能生成重定向文件,但路由仍是附属设置,不足以支撑“原路径不变”的核心要求。 + +SiteForge 必须建立独立的 `route_registry`: + +- 每条公开 URL 都有唯一注册记录。 +- 保存站点、Locale、路径、资源类型、资源 ID、状态、Canonical 和历史来源。 +- 写入内容时先预占或校验路由。 +- 迁移前导入完整旧站 URL 清单。 +- 构建时从注册表生成页面和重定向。 +- 发布门禁对旧 URL 覆盖率、404、重定向环和多跳重定向进行检查。 + +旧项目的 Redirect 生成脚本可以保留,但数据源应切换到路由注册表。 + +### 3.4 媒体系统 + +旧媒体模块已有 Sharp 缩略图和来源 URL 去重,可以保留处理经验,但存在以下缺口: + +- 主要依赖本地磁盘。 +- SVG 缺少严格清理。 +- 删除时缺少完整引用检查。 +- 未形成原文件、变体、Hash、使用关系和删除状态的完整模型。 + +SiteForge 应实现: + +- S3 兼容对象存储。 +- 文件 Hash 去重和 MIME 魔数校验。 +- SVG 清理或默认禁用上传。 +- 图片尺寸、格式、焦点、Alt 和变体管理。 +- `media_usage` 引用关系。 +- 软删除、延迟物理删除和可恢复窗口。 +- WebP/AVIF 等派生资源异步生成。 + +### 3.5 表单与线索 + +旧 Lead 模块只适合作为简单 CRUD 示例,尚不等于可对公网开放的 Form API。 + +SiteForge 应补充: + +- 表单定义和字段 Schema。 +- 来源页面、UTM、Referrer、站点和 Locale。 +- 服务端校验、蜜罐、验证码、频率限制和重复提交保护。 +- 隐私同意记录和可配置保留期限。 +- 通知重试、Webhook 签名和失败队列。 +- CSV 导出安全处理。 +- 所有更新必须同时按 `site_id` 和记录 ID 定位。 + +### 3.6 站点主题与页面编辑 + +旧运行时已有 Token 和组件,但页面结构仍偏硬编码。SiteForge 应建立四层结构: + +1. **基础组件层**:Button、Container、Image、RichText 等。 +2. **业务区块层**:Hero、ProductGrid、NewsList、FAQ、CTA、ContactForm 等。 +3. **页面模板层**:首页、产品列表、产品详情、新闻列表、文章详情和普通页面。 +4. **主题层**:Token、字体、间距、装饰样式、默认区块组合和可用模板清单。 + +主题包至少包含: + +- `theme.manifest.ts` +- `tokens.ts` +- `blocks/` +- `layouts/` +- `templates/` +- `styles/` +- `migrations/` + +后台编辑的是结构化区块配置,前台由 Block Renderer 统一渲染。这样才能同时做到不同网站效果不同、组件可复用、数据可迁移和主题可升级。 + +--- + +## 4. 当前阶段不建议复用或应暂缓的部分 + +### 4.1 数据分析和客户身份体系 + +旧文档中包含事件网关、ClickHouse、Tracking Plan、客户画像和增长分析等设计。这些能力会显著增加系统复杂度,但不是 SiteForge 第一阶段完成网站迁移、发布和维护的必要条件。 + +建议: + +- V1 只保留基础访问统计接入位和必要操作日志。 +- Event Gateway、ClickHouse、统一客户身份和高级分析延后到独立阶段。 + +### 4.2 复杂 RBAC、多租户商业化和计费 + +当前需求已经明确只需超级管理员,因此暂不建设: + +- 角色与权限矩阵。 +- 团队邀请和成员管理。 +- 租户套餐、用量计费和支付。 +- 审批流。 + +数据库可保留未来扩展空间,但不应为了可能的需求增加当前实现负担。 + +### 4.3 旧项目的真实数据与运行目录 + +不得直接复制: + +- `.data` +- `storage` +- `node_modules` +- `.turbo` +- `.playwright-mcp` +- 构建产物和运行日志 +- 客户网站内容、媒体、线索和导入文件 +- `.env`、Token、密码及其他 Secret + +确需使用真实迁移样本时,应先获得授权并完成脱敏,再转换为最小测试夹具。 + +### 4.4 历史文档的权威地位 + +旧项目文档中有大量值得借鉴的设计,但部分功能只存在于文档,代码尚未实现;也有部分规则与 SiteForge 当前单超管、统一路由和冻结快照发布模型冲突。 + +因此: + +- SiteForge V3.0 方案是当前项目的权威基线。 +- 旧项目文档仅作为输入和参考。 +- 任何旧设计进入实现前,都要映射到 SiteForge 的领域模型和验收标准。 + +--- + +## 5. 复用优先级矩阵 + +| 能力 | 现状 | 复用建议 | 优先级 | +|---|---|---|---| +| pnpm/Turborepo 工程骨架 | 已成型 | 直接参考/继承 | P0 | +| Art Design Pro 后台壳 | 已成型 | 保留壳,清理演示与多角色 | P0 | +| NestJS/Fastify/Drizzle | 已成型 | 作为 API 基础 | P0 | +| 站点上下文与隔离测试 | 已有实现 | 保留并扩大覆盖 | P0 | +| WordPress REST/WXR 解析 | 已有实现和测试 | 重点继承,重做迁移流程 | P0 | +| 内容类型和版本 | 基本可用 | 扩展状态机与发布模型 | P0 | +| Astro 静态运行时 | 原型可用 | 保留构建基础,重构主题架构 | P0 | +| 主题 Token/组件契约 | 文档较完整 | 纳入新主题规范 | P0 | +| Redirect 生成 | 已有脚本 | 改用 route_registry 数据源 | P0 | +| SEO Gate | 基础版本 | 保留并增强 | P0 | +| PostgreSQL/Redis/MinIO | 已配置 | 直接沿用技术选型 | P0 | +| 导入幂等和报告 | 有基础 | 扩展为批次、回滚、差异报告 | P1 | +| 媒体缩略图处理 | 有基础 | 保留 Sharp,重构存储与安全 | P1 | +| 站点模板初始化 | 有基础 | 改造成站点蓝图/主题初始化 | P1 | +| Lead CRUD | 简单实现 | 仅参考,重做公网 Form API | P1 | +| BuildService | 原型 | 不直接复用,改为队列 Worker | P1 | +| Event Gateway | 占位/早期 | 暂缓 | P3 | +| ClickHouse/增长分析 | 超出当前范围 | 暂缓 | P3 | +| 多角色 RBAC | 与需求冲突 | 不采用 | 不做 | + +--- + +## 6. 推荐落地方式 + +### 方案 A:以旧项目代码为技术底座进行净化和重构(推荐) + +做法: + +- 保留旧项目 Git 历史或创建一条新的 SiteForge 开发分支/仓库。 +- 删除缓存、数据、演示页面和超出范围的模块。 +- 以 SiteForge V3.0 的数据模型、模块边界和实施计划逐步替换旧实现。 +- 每完成一个领域,就补齐迁移脚本、测试和验收门禁。 + +优点: + +- 最大化利用已经写好的管理后台、迁移解析器、API 和 Astro 代码。 +- 保留真实问题的修复经验和测试用例。 +- 比从空目录重建更快进入可运行状态。 + +风险: + +- 必须主动偿还旧原型留下的结构债务。 +- 不能为了短期速度保留内存发布、JSON 路由、自制 Token 等关键缺陷。 + +### 方案 B:保持 `cms-one` 为全新仓库,选择性移植源码 + +适用于希望彻底清理历史包袱的情况。 + +建议只移植: + +- 后台通用壳和基础组件。 +- WordPress/WXR 解析器与测试夹具。 +- 内容版本、幂等导入的核心逻辑。 +- Astro 通用组件、主题 Token 和门禁脚本。 +- PostgreSQL/Redis/MinIO 开发环境配置。 + +不要整目录复制。每次移植都应有对应的模块边界、测试和依赖清单。 + +综合成本与风险,推荐采用**方案 A 的代码继承方式 + 方案 B 的选择性净化原则**:把旧项目当成可运行底座,但按 SiteForge 方案逐域重构,而不是延续旧项目产品定义。 + +--- + +## 7. 第一批实际迁移任务 + +### 第 1 批:建立干净基线 + +1. 确认源码许可证和第三方资产许可证。 +2. 导出仅包含受版本控制源码的干净代码副本。 +3. 排除数据、媒体、日志、缓存、依赖和 Secret。 +4. 删除后台演示页面、多角色路由和无关分析模块。 +5. 固化 Node、pnpm、PostgreSQL、Redis 和 MinIO 版本。 +6. 跑通 lint、typecheck、unit、e2e 和静态站构建基线。 + +### 第 2 批:修正核心架构 + +1. 实现平台级单超级管理员认证。 +2. 建立 `route_registry`、`import_batches`、`build_jobs`、`releases`、`publish_locks` 等核心表。 +3. 将构建改为持久化队列 Worker。 +4. 将静态站编译输入改为冻结 Site Snapshot。 +5. 建立对象存储媒体模型和引用关系。 + +### 第 3 批:迁移与主题平台化 + +1. 把现有 WordPress REST/WXR 代码接入导入批次。 +2. 建立全量 URL 清单、映射、冲突和覆盖率报告。 +3. 将现有 Astro 组件整理为基础组件和业务区块。 +4. 实现 Theme Manifest、Block Manifest 和 Block Renderer。 +5. 完成第一个真实站点的迁移、预览、门禁和原子发布。 + +### 第 4 批:运营能力 + +1. Schema 驱动内容表单。 +2. 产品、新闻、普通页面和导航维护。 +3. 安全的公网 Form API 和线索后台。 +4. 发布历史、差异查看、一键回滚和审计日志。 +5. 备份恢复、监控告警和灾难恢复演练。 + +--- + +## 8. 需要优先修复的已发现风险 + +1. **发布记录在内存中**:服务重启会丢失构建历史和锁状态。 +2. **API 进程直接构建**:资源隔离、并发、重试和故障恢复不足。 +3. **迁移即发布**:不满足人工审核、预览和可回滚要求。 +4. **路由保存在 JSON 设置中**:无法可靠保证所有旧路径不变。 +5. **自制 Token 能力不足**:缺少完整过期、撤销、MFA 和会话管理。 +6. **本地媒体存储和直接删除**:生产可靠性和引用安全不足。 +7. **SVG 缺少清理**:存在持久化 XSS 风险。 +8. **Lead 更新条件不完整**:部分操作需同时限定 `site_id`。 +9. **页面和 Locale 存在硬编码**:无法稳定支持不同站点和语言组合。 +10. **文档数据库模型多于实际 Schema**:必须以迁移文件和运行代码确认真实能力。 +11. **正则式 HTML Gate 有边界缺陷**:需要 DOM 解析和浏览器级补充验证。 +12. **所谓原子发布仍有删除后复制窗口**:生产切换需要重新设计。 + +--- + +## 9. 最终建议 + +当前 SiteForge 项目应把 `D:\project\cms` 定位为: + +- **实现底座**:复用工程骨架、后台壳、API 基础、迁移解析和 Astro 运行时。 +- **经验库**:复用真实迁移中沉淀的测试、映射和质量门禁经验。 +- **非权威需求来源**:产品范围、权限、发布和主题架构以 SiteForge V3.0 为准。 + +预计最能节省工期的五项资产是: + +1. WordPress REST/WXR 迁移解析和测试。 +2. Art Design Pro 管理后台基础。 +3. NestJS/Fastify/Drizzle 内容 API 基础。 +4. Astro 静态站组件与 SEO Gate。 +5. 内容版本、幂等导入和站点隔离测试。 + +预计最不能直接继承的五项是: + +1. 当前认证与多角色模型。 +2. 内存式构建和发布流程。 +3. JSON 化重定向与非正式路由管理。 +4. 本地媒体删除和安全策略。 +5. 迁移完成后直接发布的工作流。 + +按这个边界执行,可以保留旧项目的大部分有效研发投入,同时避免把原型阶段的关键技术债带入 SiteForge 的正式版本。 diff --git a/SiteForge_项目实施计划_V1.0.md b/SiteForge_项目实施计划_V1.0.md new file mode 100644 index 0000000..ac98222 --- /dev/null +++ b/SiteForge_项目实施计划_V1.0.md @@ -0,0 +1,1157 @@ +# SiteForge 项目实施计划 + +> 版本:V1.0 +> 编制日期:2026-10-20 +> 方案基线:`SiteForge_完整项目计划方案_V3.0.md` +> 计划周期:目标20周,预留4周风险缓冲 +> 适用团队:约5人核心团队,设计师阶段性参与 + +--- + +## 1. 实施目标 + +在20周目标周期内,完成一套可投入生产使用的多站点迁移与静态发布平台,并通过两个真实网站验证: + +1. 一个资料完整的 WordPress 网站。 +2. 一个非 WordPress、HTML/PHP、自研 CMS 或其他不同来源的网站。 + +最终必须跑通: + +```text +多来源盘点 +→ 全量导入 +→ 标准化与字段映射 +→ URL/SEO基线 +→ 独立主题与组件化实现 +→ 差量同步 +→ 静态构建 +→ 自动验收 +→ 发布确认 +→ 原子部署 +→ 生产验证 +→ 回滚演练 +``` + +项目实施遵循以下原则: + +- 优先完成真实站点纵向闭环,不先堆积后台页面。 +- V1 只设置 `super_admin` 一个系统角色。 +- 管理后台使用 Art Design Pro(Vue 3 + TypeScript + Element Plus)。 +- 第一版只做全量构建,不提前开发复杂增量构建。 +- 先完成 WordPress 与通用网页适配,不同时扩展多个 CMS。 +- URL、SEO、内容和回滚能力优先于高级视觉编辑。 +- 每个 Sprint 必须交付可演示、可测试的结果。 + +--- + +## 2. 计划假设 + +### 2.1 团队配置 + +| 代号 | 角色 | 建议投入 | 主要责任 | +|---|---|---:|---| +| PM | 项目/产品负责人 | 50%–100% | 范围、决策、试点协调、验收 | +| BE | 后端/架构工程师 | 100% | API、数据库、任务、构建、发布、安全 | +| FE | 前端/主题工程师 | 100% | Art Design Pro、编辑器、主题、组件化 | +| DE | 迁移/数据工程师 | 100% | 扫描、WordPress、映射、URL/SEO基线 | +| QA | 测试/运维工程师 | 80%–100% | 自动测试、部署、监控、备份、回滚 | +| UI | UI/UX设计师 | 阶段性 | 两站设计、组件规范、响应式验收 | + +项目角色仅用于实施分工,不对应系统权限;系统内仍由超级管理员完成所有操作。 + +### 2.2 必要输入 + +项目第1周必须能够获得: + +- 两个试点站及其负责人。 +- WordPress SQL、WXR、uploads 和插件/主题清单。 +- Sitemap、旧服务器规则和可用访问权限。 +- 生产域名、DNS、CDN、证书和部署环境信息。 +- 重要页面、产品、文章和动态功能清单。 +- 至少一部分访问日志或 GSC/GA4 落地页数据。 +- 品牌资料及第一批页面设计方向。 + +如果关键数据无法取得,项目可以继续完成平台功能,但试点完整迁移和最终上线日期需要重新评估。 + +### 2.3 周期说明 + +- 目标实施周期:20周。 +- 风险缓冲:第21–24周,按需启用。 +- Sprint长度:2周。 +- 共10个正式Sprint。 +- 复杂 Elementor、WooCommerce、多语言、特殊URL规则可能消耗缓冲时间。 + +--- + +## 3. 总体里程碑 + +| 里程碑 | 时间 | 结果 | 发布门槛 | +|---|---:|---|---| +| M0 范围冻结 | 第2周 | 试点、技术和V1范围确定 | 样本数据可访问,风险已分级 | +| M1 平台底座 | 第4周 | 超管、站点、任务和基础设施可用 | CI通过,核心环境可启动 | +| M2 数据闭环 | 第8周 | WordPress可重复导入并建立URL/SEO基线 | 幂等、快照、差量测试通过 | +| M3 静态预览 | 第12周 | 首站可从后台生成独立主题预览 | 内容、路由、SEO进入静态产物 | +| M4 发布闭环 | 第16周 | 构建、验收、部署和回滚可用 | 生产等价环境演练通过 | +| M5 双站验证 | 第18周 | 第二来源和第二主题闭环 | 公共组件复用验证通过 | +| M6 试点上线 | 第20周 | 首站上线、第二站可交付 | 最终差量、门禁、回滚均通过 | + +--- + +## 4. 工作流划分 + +### 4.1 平台与后台工作流 + +- Art Design Pro 工程底座。 +- 超管登录、MFA、会话和恢复。 +- 站点、环境、域名和配置。 +- 任务进度、日志和系统设置。 +- 内容、页面板块、URL、SEO、构建和发布界面。 + +### 4.2 数据迁移工作流 + +- 网站探测和扫描。 +- URL多来源合并。 +- WordPress REST/WXR/SQL/uploads。 +- 原始快照和差量同步。 +- 字段映射、冲突和异常处理。 + +### 4.3 主题与组件工作流 + +- Theme Manifest、Template和Block Schema。 +- 公共数据契约、基础组件和Headless逻辑。 +- 第一套WordPress试点主题。 +- 第二套视觉差异明显的主题。 +- 静态预览和视觉回归。 + +### 4.4 构建与发布工作流 + +- 构建输入快照。 +- 隔离、可复现的Astro构建。 +- 路由编译和部署能力预检。 +- 自动验收、Release、发布锁和回滚。 +- Nginx/SSH或对象存储/CDN部署。 + +### 4.5 质量与运维工作流 + +- 单元、契约、集成和E2E。 +- URL/SEO/内容/媒体/视觉门禁。 +- 监控、告警、任务死信。 +- 备份、恢复和故障Runbook。 +- 切站彩排和稳定期监测。 + +--- + +## 5. Sprint 0:试点盘点与范围冻结(第1–2周) + +### 5.1 Sprint目标 + +确认项目能做什么、首版不做什么,并用真实数据验证关键技术路径。 + +### 5.2 工作任务 + +#### 产品与业务 + +- 确定两个试点网站。 +- 确定生产部署方式。 +- 收集产品、新闻、页面和动态功能清单。 +- 建立V1/V1.1/暂缓范围矩阵。 +- 确定超级管理员和试点验收负责人。 + +#### 迁移盘点 + +- 收集SQL、WXR、uploads、Sitemap和服务器规则。 +- 识别WordPress插件、ACF/CPT、页面构建器和SEO插件。 +- 从数据库、Sitemap、日志、GSC/GA4合并首批URL。 +- 抽取至少20个代表性页面。 +- 识别中文URL、查询参数、`.html`、`.php`、分页和媒体路径。 +- 输出动态功能处置表。 + +#### 技术预研 + +- 验证Art Design Pro工程结构。 +- 验证NestJS、PostgreSQL、Redis/BullMQ和对象存储。 +- 验证Astro动态路由和目标服务器URL行为。 +- 验证构建隔离方案。 +- 确定ORM、存储和部署适配器ADR。 + +#### 设计 + +- 明确两个试点的品牌方向。 +- 列出首页、产品、文章、列表和普通页面类型。 +- 建立第一版设计令牌和组件清单。 + +### 5.3 交付物 + +- 《两个试点站评估报告》 +- 《V1范围矩阵》 +- 《URL/SEO初始基线》 +- 《动态功能处置表》 +- 《字段映射样本》 +- 《技术ADR清单》 +- 《风险登记表》 +- 20个真实页面PoC结果 + +### 5.4 验收门槛 M0 + +- 两个试点及数据可用范围明确。 +- WordPress数据至少能读取SQL/WXR中的一种。 +- 目标部署环境能够执行URL行为验证。 +- V1范围和不做事项书面冻结。 +- P0风险都有负责人和处置方案。 + +--- + +## 6. Sprint 1:工程底座与超级管理员(第3–4周) + +### 6.1 Sprint目标 + +建立可持续开发的工程、环境和安全基础。 + +### 6.2 工作任务 + +#### 工程 + +- 建立pnpm Monorepo和统一TypeScript配置。 +- 建立admin、api、worker、builder应用。 +- 配置代码检查、类型检查、单元测试和CI。 +- 建立开发、测试和预览环境配置。 +- 锁定Node、依赖和容器镜像版本。 + +#### 管理后台 + +- 初始化Art Design Pro。 +- 删除多角色、按钮权限和成员管理功能。 +- 建立固定菜单和基础页面框架。 +- 完成登录、MFA、恢复码和会话管理页面。 +- 完成统一API错误和任务状态展示。 + +#### 后端与基础设施 + +- 建立NestJS模块骨架。 +- 建立PostgreSQL迁移机制。 +- 建立Redis/BullMQ。 +- 建立S3兼容对象存储。 +- 建立结构化日志、请求ID和审计日志。 +- 建立密钥引用模型。 + +#### 数据模型 + +- admin_user、admin_session。 +- site、domain、environment、site_setting。 +- job、job_lease、audit_log。 +- source_connection基础表。 + +### 6.3 交付物 + +- 可启动的本地开发环境。 +- 可登录的管理后台。 +- 可创建站点和环境。 +- 可提交示例异步任务并查看日志。 +- CI流水线和数据库迁移。 + +### 6.4 验收门槛 M1 + +- 全新环境可按文档一键启动。 +- 超管登录和MFA通过。 +- 同一任务重复请求不会重复创建。 +- 日志可关联用户、请求和任务。 +- CI在合并前执行类型和基础测试。 + +--- + +## 7. Sprint 2:扫描、快照与URL注册表(第5–6周) + +### 7.1 Sprint目标 + +建立从旧站发现URL、保存证据、分类和形成基线的完整链路。 + +### 7.2 工作任务 + +#### 扫描引擎 + +- 实现域名和协议白名单。 +- 实现DNS/IP/跳转后的SSRF检查。 +- 实现Sitemap和Sitemap Index解析。 +- 实现HTTP抓取、HTML解析和链接发现。 +- 接入Playwright处理JS页面和截图。 +- 支持速率、并发、深度、超时和文件大小限制。 +- 实现断点、重试、取消和任务心跳。 + +#### 快照 + +- 保存状态码、跳转、响应头、HTML和checksum。 +- 保存必要的渲染DOM和截图。 +- 建立source_snapshot和source_record。 +- 对原始数据写入对象存储。 + +#### URL注册表 + +- 建立原始路径和规范化辅助键。 +- 处理大小写、尾斜杠、Unicode和查询参数。 +- 实现URL来源合并和冲突展示。 +- 实现路由种类与验证状态。 + +#### 后台 + +- 扫描创建与进度页面。 +- URL清单、来源、状态和失败原因页面。 +- 页面类型初步分类和手工修正。 + +### 7.3 交付物 + +- 通用网页扫描器。 +- URL注册表V1。 +- URL来源合并报告。 +- 扫描任务后台界面。 +- 安全抓取配置和测试夹具。 + +### 7.4 验收条件 + +- 对测试站重复扫描不会产生重复URL。 +- 中断后可从检查点继续。 +- 内网和非法重定向请求被拒绝。 +- 中文、大小写、尾斜杠和查询参数测试通过。 +- 至少20个真实页面保存完整快照。 + +--- + +## 8. Sprint 3:WordPress导入与差量同步(第7–8周) + +### 8.1 Sprint目标 + +完成WordPress核心数据导入、标准化和可重复差量同步。 + +### 8.2 工作任务 + +#### WordPress适配器 + +- REST API探测和导入。 +- WXR解析。 +- SQL表前缀识别。 +- posts、postmeta、terms和relationships导入。 +- 页面、文章、公开CPT、分类和标签。 +- 菜单、媒体、特色图片和uploads。 +- Yoast/Rank Math常用字段。 +- Gutenberg基础块。 +- ACF未知字段保留。 + +#### 标准化 + +- content_entry和content_revision。 +- taxonomy和term。 +- media_asset和media_usage。 +- source_key、checksum和映射状态。 +- 源字段、标准字段和人工覆盖规则。 + +#### 差量同步 + +- 新增、更新、删除、未变化和冲突检测。 +- 使用modified时间和checksum。 +- 人工修改字段保护。 +- 导入批次报告。 + +#### 后台 + +- 导入任务页面。 +- 字段映射和未识别字段页面。 +- 冲突比较和人工选择。 +- 页面、文章、产品的基础查看。 + +### 8.3 交付物 + +- WordPress适配器V1。 +- 统一内容模型V1。 +- 字段映射工作台基础版。 +- 差量同步和冲突报告。 +- 首站内容数量对比报告。 + +### 8.4 验收门槛 M2 + +- 同一数据导入两次不产生重复内容。 +- 修改源内容后只产生预期更新。 +- 人工覆盖字段不会被静默覆盖。 +- 产品/文章/页面/分类/媒体数量有来源对照。 +- URL和SEO能够关联到标准内容。 + +--- + +## 9. Sprint 4:内容后台、媒体、URL与SEO(第9–10周) + +### 9.1 Sprint目标 + +让超级管理员能够维护核心内容,并形成可用于构建的URL/SEO/媒体快照。 + +### 9.2 工作任务 + +#### 内容后台 + +- 产品、新闻、普通页面编辑。 +- 分类、品牌和菜单管理。 +- 草稿、ready_to_publish、published和archived状态。 +- 内容修订、差异和恢复。 +- ETag/版本号乐观锁。 + +#### 媒体 + +- 上传、选择、预览和基础信息编辑。 +- SHA-256去重辅助。 +- 图片尺寸、MIME和安全验证。 +- 旧路径、衍生资源和使用关系。 +- PDF、SVG、字体等非图片资源。 + +#### URL/SEO + +- route_registry编辑和冲突检查。 +- redirect、gone、asset和dynamic规则。 +- SEO三套数据对比。 +- Title、Description、Canonical、Robots、OG和JSON-LD。 +- Sitemap与内部链接基础检查。 + +#### 内容引用 + +- content_reference表。 +- 板块、媒体、内容和路由引用。 +- 删除前影响报告。 +- 悬空引用检测。 + +### 9.3 交付物 + +- 内容中心V1。 +- 媒体中心V1。 +- URL和SEO中心V1。 +- 内容引用和删除影响分析。 +- 可冻结的内容/路由/SEO快照。 + +### 9.4 验收条件 + +- 管理员能新增一条产品和新闻并保存修订。 +- 多标签页冲突不会覆盖新版本。 +- 删除已引用内容会被阻止并显示影响页面。 +- URL冲突和重定向循环能够被发现。 +- SEO差异可以按P0–P3分类。 + +--- + +## 10. Sprint 5:主题、板块和第一套主题(第11–12周) + +### 10.1 Sprint目标 + +建立可复用主题体系,并将首个WordPress站生成完整静态预览。 + +### 10.2 工作任务 + +#### 主题契约 + +- theme manifest。 +- template definition。 +- block schema和UI schema。 +- slotKey、position、variant和schemaVersion。 +- 主题与公共运行时兼容规则。 + +#### 公共组件包 + +- content-contracts。 +- block-contracts。 +- theme-runtime。 +- ui-primitives。 +- content-resolvers。 +- media-components。 +- seo-components。 + +#### 首批板块 + +- Hero。 +- Rich Text。 +- Image Text。 +- Gallery。 +- Feature List。 +- Product Grid。 +- Article List。 +- Specification Table。 +- Download List。 +- FAQ。 +- CTA。 +- Statistics。 + +#### 后台板块编辑 + +- 根据schema生成表单。 +- 新增、复制、排序、隐藏和删除。 +- 媒体、产品、文章和路由选择。 +- 模板允许范围和数量限制。 +- 预览构建入口。 + +#### 第一套主题 + +- Base Layout、Header和Footer。 +- 首页。 +- 产品列表和详情。 +- 文章列表和详情。 +- 普通页面和404。 +- 桌面与移动端。 + +### 10.3 交付物 + +- Theme SDK V1。 +- 组件公共包V1。 +- 页面板块编辑器V1。 +- 第一套试点主题。 +- 首站完整静态预览。 + +### 10.4 验收门槛 M3 + +- 首站核心页面从数据库生成静态HTML。 +- 核心内容在禁用JavaScript时仍可读取。 +- 不支持板块会阻止生产构建。 +- 页面URL来自route_registry而非主题slug。 +- 主题不直接访问数据库。 +- PC/移动端典型页面通过初次视觉验收。 + +--- + +## 11. Sprint 6:可复现构建、路由编译与预览(第13–14周) + +### 11.1 Sprint目标 + +将静态预览升级为可追溯、可隔离和可重复执行的构建系统。 + +### 11.2 工作任务 + +#### 构建快照 + +- 锁定内容、路由、SEO、媒体和站点配置。 +- 记录Git commit、依赖哈希、运行时和镜像digest。 +- 固定locale、timezone和构建时间。 + +#### 构建沙箱 + +- 只读输入和代码。 +- 临时写目录。 +- CPU、内存、磁盘和超时限制。 +- 网络白名单。 +- 不挂载主数据库与控制面密钥。 + +#### 构建并发 + +- Job幂等键。 +- 站点/环境构建租约。 +- 心跳和失联回收。 +- 旧构建禁止自动发布。 +- 取消安全点。 + +#### 路由编译 + +- 统一route-manifest。 +- Nginx规则生成。 +- 目标部署能力声明。 +- `.php`、查询参数、尾斜杠和状态码预检。 + +#### 预览 + +- 不可变预览release。 +- 访问控制和noindex。 +- 真实HTTP路径检查。 + +### 11.3 交付物 + +- builder V1。 +- build-input、manifest和checksums。 +- 构建隔离环境。 +- Nginx路由编译器。 +- 预览Release和HTTP测试。 + +### 11.4 验收条件 + +- 相同输入在固定环境中输出一致哈希。 +- 构建期间修改内容不影响当前任务。 +- 两个并发构建不会互相覆盖。 +- 目标服务器真实返回预期状态码和Location。 +- 预览站无法被搜索引擎正常索引。 + +--- + +## 12. Sprint 7:自动验收、发布与回滚(第15–16周) + +### 12.1 Sprint目标 + +完成从静态预览到安全生产发布的完整链路。 + +### 12.2 工作任务 + +#### 自动验收 + +- URL覆盖、状态和跳转。 +- SEO差异。 +- 内容摘要和核心字段。 +- 媒体与内部链接。 +- 主题契约和板块schema。 +- 桌面/移动截图。 +- 性能和可访问性基线。 +- 敏感文件和安全头。 + +#### Release + +- 不可变release目录。 +- 发布状态机。 +- active_release_id。 +- environment_publish_lock。 +- 比较并交换切换。 +- 发布前版本过期检查。 + +#### 部署 + +- Nginx/SSH部署适配器。 +- 如试点需要,实现S3/OSS + CDN适配器。 +- 文件数量和哈希校验。 +- 临时入口冒烟。 +- CDN刷新状态。 + +#### 回滚 + +- 静态文件、路由、Header和配置同步回滚。 +- 回滚后二次冒烟。 +- partially_deployed补偿流程。 + +### 12.3 交付物 + +- 验收引擎和报告。 +- Release/Deployment模型。 +- 生产发布确认页面。 +- 部署适配器。 +- 回滚Runbook。 + +### 12.4 验收门槛 M4 + +- P0问题能够阻止发布。 +- 较旧构建不能覆盖较新生产版本。 +- 发布中断后状态可识别和恢复。 +- 在生产等价环境中完成发布和回滚演练。 +- 路由规则与静态文件始终属于同一release。 + +--- + +## 13. Sprint 8:第二主题、第二来源和动态能力(第17–18周) + +### 13.1 Sprint目标 + +证明平台不是单站、单主题和WordPress专用工具。 + +### 13.2 工作任务 + +#### 第二来源 + +- 为第二试点配置通用网页或专属轻量适配器。 +- 使用CSS选择器、JSON-LD或API提取结构化数据。 +- 建立字段映射和Legacy HTML兜底。 +- 输出来源能力与未知范围报告。 + +#### 第二主题 + +- 采用不同布局、导航、产品卡片和视觉语言。 +- 复用相同数据契约、SEO、媒体和Headless逻辑。 +- 只将真正通用的逻辑提取到公共包。 +- 建立两个主题的截图回归。 + +#### 动态能力 + +- 实现试点需要的Form API。 +- 来源校验、验证码、限流和幂等。 +- 邮件/CRM转发、重试和死信。 +- 隐私同意、脱敏和保留策略。 + +### 13.3 交付物 + +- 第二来源适配方案。 +- 第二套独立主题。 +- 公共组件复用报告。 +- Form API或试点必需动态服务。 +- 双站静态预览。 + +### 13.4 验收门槛 M5 + +- 两个站点数据、域名、主题和release互不影响。 +- 两套主题视觉明显不同。 +- 公共契约升级不会破坏两套主题测试。 +- 第二来源未支持内容进入明确异常清单。 +- 表单能够处理成功、失败、重试和重复提交。 + +--- + +## 14. Sprint 9:上线准备、切换与稳定期(第19–20周) + +### 14.1 Sprint目标 + +完成首站正式切换,并使第二站达到可交付状态。 + +### 14.2 工作任务 + +#### 运维完善 + +- 生产监控、关键URL探测和告警。 +- 队列、Worker、存储和数据库监控。 +- PostgreSQL和对象存储备份。 +- 密钥和配置恢复材料。 +- 完整恢复演练。 + +#### 上线彩排 + +- 模拟内容冻结。 +- 最终差量导入。 +- URL/SEO最终重扫。 +- 构建、验收和发布。 +- DNS/CDN切换。 +- 回滚演练。 + +#### 正式上线 + +- 执行T-7天至T时刻Runbook。 +- 超级管理员确认发布。 +- 关键URL、SEO、表单和日志检查。 +- 保留旧站环境。 +- 建立问题响应和回滚窗口。 + +#### 项目收尾 + +- 完成操作、开发和运维文档。 +- 完成试点迁移报告。 +- 整理V1.1待办。 +- 复盘估算后续每站成本。 + +### 14.3 交付物 + +- 生产监控和告警。 +- 备份恢复报告。 +- 上线与回滚Runbook。 +- 首站生产发布。 +- 第二站可交付release。 +- 项目验收报告。 + +### 14.4 验收门槛 M6 + +- 最终差量同步完成,无未解释内容丢失。 +- URL和SEO P0为0,P1已处理或记录例外。 +- 关键页面、媒体和动态功能通过。 +- 首站可安全回滚到上一个release。 +- 生产站不依赖SiteForge实时在线。 +- 旧站保留期、监测负责人和后续计划明确。 + +--- + +## 15. 第21–24周风险缓冲 + +缓冲期不是默认增加功能,只处理以下事项: + +- Elementor/WPBakery复杂页面结构化。 +- WooCommerce变体和特殊字段。 +- 多语言历史URL。 +- 大量异常媒体或编码路径。 +- CDN/对象存储路由能力限制。 +- 试点业务验收返工。 +- 正式上线后的高优先级问题。 + +缓冲期不得用于临时加入低代码、更多CMS、复杂权限或非试点功能,除非项目范围正式变更。 + +--- + +## 16. Epic与任务分解 + +| Epic | 名称 | 主要Sprint | 负责人 | 完成定义 | +|---|---|---:|---|---| +| E01 | 工程与环境 | 1 | BE/QA | 开发、测试、CI可重复启动 | +| E02 | 超管认证 | 1 | BE/FE | MFA、恢复、会话、审计通过 | +| E03 | 站点与环境 | 1–2 | BE/FE | 两站隔离,环境配置可管理 | +| E04 | 任务平台 | 1–9 | BE/QA | 租约、重试、死信、监控完整 | +| E05 | 扫描与URL | 2 | DE/BE | 多来源URL与快照可审计 | +| E06 | WordPress适配 | 3 | DE | REST/WXR/SQL/uploads闭环 | +| E07 | 内容与映射 | 3–4 | BE/FE/DE | 内容修订、映射、冲突可用 | +| E08 | 媒体 | 3–4 | BE/FE | 原件、旧路径、引用可管理 | +| E09 | URL/SEO | 2–7 | DE/BE | 差异、冲突、门禁完整 | +| E10 | 主题与板块 | 5 | FE/UI | 第一主题与板块编辑可用 | +| E11 | 公共组件 | 5–8 | FE | 两主题复用并通过回归 | +| E12 | 构建 | 6 | BE/FE | 快照、隔离、可复现 | +| E13 | 验收 | 6–7 | QA/DE | 报告和P0门禁可用 | +| E14 | 发布与回滚 | 7 | BE/QA | 原子切换和回滚演练通过 | +| E15 | 第二来源/主题 | 8 | DE/FE/UI | 双站双主题闭环 | +| E16 | 动态服务 | 8 | BE/QA | 试点动态功能验收通过 | +| E17 | 运维与备份 | 1–9 | QA/BE | 监控、告警、恢复演练通过 | +| E18 | 切站与稳定期 | 9 | 全员 | 首站上线和试点验收 | + +--- + +## 17. 关键依赖与关键路径 + +### 17.1 关键路径 + +```text +试点数据到位 +→ 数据模型与快照 +→ WordPress导入 +→ URL/SEO注册表 +→ 主题/板块 +→ 静态构建 +→ 自动验收 +→ 发布/回滚 +→ 最终差量 +→ 生产切换 +``` + +任何关键路径任务延迟会直接影响上线日期。 + +### 17.2 可并行任务 + +- 设计师可在扫描期间完成首站设计系统。 +- FE可在后端模型稳定后使用fixture开发页面板块。 +- QA可从Sprint 1开始建设测试夹具和CI。 +- 第二主题可在首套主题SDK稳定后并行开发。 +- 运维可在构建功能开发时并行准备部署环境。 + +### 17.3 决策截止时间 + +| 决策 | 最晚时间 | 未决影响 | +|---|---:|---| +| 两个试点站 | 第1周 | 无法建立真实模型 | +| ORM与对象存储 | 第2周 | 数据层和环境延迟 | +| 生产部署目标 | 第2周 | 路由编译和发布延迟 | +| 第一主题设计方向 | 第4周 | Sprint 5无法开始 | +| 动态功能方案 | 第6周 | Form API范围不确定 | +| 第二试点来源 | 第8周 | Sprint 8延迟 | +| DNS/CDN切站权限 | 第14周 | 上线彩排无法完成 | + +--- + +## 18. 测试实施计划 + +### 18.1 每个Sprint持续执行 + +- 代码检查和类型检查。 +- 单元测试。 +- 数据库迁移测试。 +- API集成测试。 +- 安全静态检查。 + +### 18.2 从Sprint 2开始 + +- URL编码和路径fixture。 +- 爬虫限流、断点和SSRF测试。 +- 快照和幂等测试。 + +### 18.3 从Sprint 3开始 + +- WordPress适配器契约测试。 +- 导入计数、差量和冲突测试。 +- SEO字段交叉验证。 + +### 18.4 从Sprint 5开始 + +- 主题manifest和block schema契约测试。 +- 页面静态HTML测试。 +- 桌面与移动截图。 +- 可访问性基础测试。 + +### 18.5 从Sprint 6开始 + +- 构建可复现测试。 +- 真实HTTP路由测试。 +- 目标部署能力测试。 +- 敏感文件和依赖扫描。 + +### 18.6 从Sprint 7开始 + +- 发布并发和失败注入。 +- CDN刷新失败。 +- Worker失联和任务恢复。 +- 部分部署补偿。 +- 完整回滚。 + +--- + +## 19. Definition of Ready + +任务进入Sprint前必须满足: + +- 业务目标和范围明确。 +- 输入数据或fixture可用。 +- API/Schema依赖已确定。 +- 验收条件可以测试。 +- 不存在未解决的P0设计问题。 +- 负责人和评审人明确。 + +不满足Ready条件的任务不能为了填满Sprint而强行开始。 + +--- + +## 20. Definition of Done + +功能完成必须同时满足: + +- 代码实现完成并通过Review。 +- 类型检查、单元和相关集成测试通过。 +- 数据库迁移可执行且有回退说明。 +- 错误、日志和任务状态可观察。 +- 安全和站点隔离检查通过。 +- 管理后台包含加载、空、失败和重试状态。 +- 用户文档或开发文档已更新。 +- 使用真实试点数据演示通过。 +- 不产生新的P0/P1未登记问题。 + +仅完成页面外观或接口代码不算Done。 + +--- + +## 21. 变更控制 + +### 21.1 变更分类 + +- P0:不处理会导致数据丢失、安全风险、无法发布或无法回滚。 +- P1:V1承诺范围或试点关键需求。 +- P2:可进入V1.1的增强。 +- P3:长期优化建议。 + +### 21.2 变更规则 + +Sprint开始后新增需求必须回答: + +1. 是否阻塞两个试点闭环。 +2. 是否可以进入V1.1。 +3. 增加多少开发和测试成本。 +4. 替换掉当前Sprint的哪项工作。 +5. 是否改变上线日期。 + +不允许只增加需求而不调整范围或工期。 + +### 21.3 明确禁止临时加入 + +- 通用低代码。 +- 复杂多角色权限。 +- 第三个CMS深度适配。 +- 复杂电商交易。 +- Kubernetes和多区域架构。 +- 未经试点证明需要的真正增量构建。 + +--- + +## 22. 项目沟通与跟踪 + +### 22.1 会议节奏 + +- 每日:15分钟开发同步。 +- 每周:风险、范围和关键数据检查。 +- Sprint中期:技术和设计走查。 +- Sprint结束:真实环境演示、验收和下Sprint计划。 +- 里程碑:Go/No-Go评审。 + +### 22.2 每周报告 + +固定报告: + +- 本周完成。 +- 下周目标。 +- 里程碑状态。 +- P0/P1问题。 +- 外部依赖和待决策。 +- 实际投入与计划偏差。 +- 试点数据覆盖率。 +- 测试和缺陷趋势。 + +### 22.3 看板状态 + +```text +Backlog +→ Ready +→ In Progress +→ Review +→ QA +→ Accepted +→ Released +``` + +阻塞任务必须标记阻塞原因、负责人和下一检查时间。 + +--- + +## 23. 风险登记与触发条件 + +| 风险 | 触发条件 | 责任人 | 处理 | +|---|---|---|---| +| 试点数据迟到 | 第1周末仍无SQL/WXR | PM | 调整试点或延期M0 | +| URL总量异常 | 日志URL显著高于Sitemap | DE | 扩展基线和扫描预算 | +| 页面构建器复杂 | 代表页面无法结构化 | FE/DE | Legacy兜底并单独排期 | +| 主题设计迟到 | 第4周无核心页面设计 | PM/UI | 使用线框先完成数据闭环 | +| 构建性能差 | 全量构建超目标窗口 | BE | 分析瓶颈,暂不直接上复杂增量 | +| 部署不兼容 | 关键URL无法由目标平台实现 | BE/QA | Edge规则或更换目标 | +| SEO差异过大 | P0/P1持续无法收敛 | DE/PM | 暂停上线并逐类修复 | +| 范围膨胀 | 新功能影响关键路径 | PM | 执行变更控制 | +| 生产故障 | 关键URL或表单失败 | QA/BE | 按Runbook回滚 | + +--- + +## 24. 质量指标 + +| 指标 | 目标 | +|---|---| +| 已确认URL处置率 | 100%或有明确例外 | +| SEO P0 | 发布前为0 | +| SEO P1 | 发布前修复或有记录例外 | +| 核心内部死链 | 0 | +| 关键媒体缺失 | 0 | +| 生产发布可回滚 | 100% | +| 构建版本可追溯 | 100% | +| 未知板块静默丢失 | 0 | +| 任务副作用重复执行 | 0个已知问题 | +| 备份恢复演练 | 上线前通过 | +| 关键URL上线冒烟 | 全部通过 | + +性能指标不使用所有站点统一分数,由两个试点分别设定基线和目标。 + +--- + +## 25. 上线执行清单 + +### T-7天 + +- 完成一次全流程彩排。 +- 验证回滚。 +- 冻结非必要平台变更。 +- 确认生产凭据和权限。 + +### T-3天 + +- 缩短DNS TTL。 +- 完成旧站完整备份。 +- 确认最新URL、SEO和动态功能报告。 +- 通知内容更新冻结时间。 + +### T-1天 + +- 执行倒数第二次差量同步。 +- 修复剩余P0/P1。 +- 确认最终release候选。 + +### T-2小时 + +- 冻结旧站写入。 +- 执行最终差量同步。 +- 重扫URL和SEO。 + +### T-90分钟 + +- 锁定内容、路由、SEO和主题快照。 +- 执行最终构建和自动验收。 + +### T-30分钟 + +- 超级管理员确认发布。 +- 临时入口执行关键URL和表单冒烟。 +- 确认回滚release。 + +### T时刻 + +- 原子切换。 +- 刷新必要缓存。 +- 验证首页、核心产品、文章、Sitemap、Robots和表单。 + +### T+2小时 + +- 高频监控4xx/5xx、跳转、SEO头和表单。 +- 达到回滚条件时立即回滚。 + +### T+1至7天 + +- 监控抓取、索引、自然流量和错误日志。 +- 处理非阻塞问题。 +- 保留旧站环境。 + +--- + +## 26. 最终项目验收 + +### 26.1 平台验收 + +- 超管安全登录和全部后台功能可用。 +- 两站数据和环境隔离。 +- 扫描、导入、差量和冲突可执行。 +- 内容、媒体、URL、SEO和板块可维护。 +- 构建可追溯、可隔离、可重复。 +- 发布有锁、有门禁、有回滚。 +- 监控、告警、备份和恢复通过。 + +### 26.2 试点验收 + +- 一个WordPress站完整迁移并上线。 +- 第二来源完成可交付静态release。 +- 两套主题视觉明显不同。 +- 相同公共组件和数据契约得到复用。 +- 所有未支持内容有明确异常记录。 +- 切站和回滚Runbook经过实际验证。 + +### 26.3 文档验收 + +- 架构和ADR。 +- 数据库与API。 +- 适配器SDK。 +- 主题/板块/组件规范。 +- URL/SEO验收规范。 +- 部署、监控、备份和恢复手册。 +- 上线和回滚Runbook。 +- 两站迁移报告。 + +--- + +## 27. 立即开始的第一周任务 + +### PM + +- 确定两个试点。 +- 发出资料收集清单。 +- 建立范围、风险和决策台账。 +- 确定每个试点的业务确认人。 + +### BE + +- 评估当前基础设施和部署目标。 +- 创建Monorepo技术PoC。 +- 验证PostgreSQL、Redis、对象存储和构建容器。 + +### FE + +- 验证Art Design Pro版本和工程结构。 +- 清点需要保留与删除的底座功能。 +- 建立管理后台页面地图。 + +### DE + +- 获取WordPress样本。 +- 导出数据库内容数量和URL样本。 +- 合并Sitemap、数据库和日志URL。 +- 识别SEO插件与页面构建器。 + +### QA + +- 建立测试环境清单。 +- 建立URL、SEO和WordPress fixture计划。 +- 定义缺陷等级和验收报告格式。 + +### UI + +- 收集两个站点品牌资料。 +- 输出第一版页面类型和组件清单。 + +第一周结束时必须能够回答:两个站点是什么、数据能否取得、URL有多复杂、动态功能有哪些、部署到哪里、首版明确不做什么。 + +--- + +## 28. 结论 + +本实施计划把V3架构方案拆成10个双周Sprint。真正的关键路径不是后台页面数量,而是: + +```text +真实数据 +→ 可重复导入 +→ URL/SEO可信基线 +→ 独立主题静态生成 +→ 目标环境真实验收 +→ 最终差量同步 +→ 安全发布与回滚 +``` + +按此顺序推进,可以在第12周形成首站完整静态预览,在第16周完成发布闭环,在第18周完成双站验证,并以第20周作为首站上线目标。第21–24周只作为复杂旧站数据和上线问题的风险缓冲,不作为扩展功能窗口。 diff --git a/cms现状与SiteForge差距分析_V1.0.md b/cms现状与SiteForge差距分析_V1.0.md new file mode 100644 index 0000000..6f1e2a6 --- /dev/null +++ b/cms现状与SiteForge差距分析_V1.0.md @@ -0,0 +1,127 @@ +# cms 代码库现状 vs SiteForge V3.0 差距分析与改造清单 + +> ⚠️ **本文档已作废(2026-10-20)**:被 `cms现状与SiteForge差距分析_V2.0.md` 取代。V2.0 修正了本文多处评级(隔离残留、非原子发布、SVG/媒体安全、迁移自动发布等,均以代码证据为准)。本文仅作历史参考,请勿据此决策。 + +> 版本:V1.0|日期:2026-10-20 +> 方法:SiteForge V3.0 §2.1 的 17 项必须交付能力为标尺,逐条对照 `D:\project\cms` 的**实际代码**(非文档声称),证据来自代码探索 + 迁移台账 + 契约文档。 +> 结论用途:走「C 路线」——以 cms 为基座继续演进,把 V3.0 当架构检查清单逐项吸收。 + +--- + +## 1. 总评 + +**17 项能力:已有 4 项、部分 9 项、缺失 4 项。** + +cms 已经用真实数据(两站:hesupipe.com ✅ 完成、magicbridgeauto.com ⏸ 暂停)验证了最难的「迁移 → 静态构建 → 门禁 → 回滚」主干链路,这与 V3.0 的核心路径完全同构。缺口集中在:**部署上线(阻塞)、主题系统(平台化核心)、迁移质量增强(差量/冲突/URL 注册表)、账号与运维硬化**。 + +一句话:**V3.0 里"值钱的架构思想"cms 已吸收了一半(不可变修订、版本化产物、门禁、幂等),另一半(输入快照、URL 注册表、主题协议、部署器)就是改造清单的主线。** + +--- + +## 2. 十七项能力逐条对照 + +图例:✅ 已有(实战验证)|🟡 部分(能跑但有明显缺口)|❌ 缺失 + +| # | V3.0 必须交付 | 评级 | cms 实际现状(代码证据) | 关键差距 | +|---|---|---|---|---| +| 1 | 多站点与环境管理 | 🟡 | sites/域名/设置齐全;站点隔离已修复并有 e2e(`isolation.e2e.test.ts`,文档里的"X-Site-Id 未生效"是过时信息) | 无 staging/production 环境抽象;构建历史存内存(重启即丢) | +| 2 | 单一超级管理员(MFA/恢复/会话撤销) | 🟡 | 登录 + bcrypt + 审计日志可用;单账号种子 | 自研 HMAC token **无过期、无撤销**;无 MFA/恢复码/登录限流;**登录页预填了默认账号密码** | +| 3 | WordPress REST/WXR/SQL/uploads 导入 | ✅ | REST + WXR 双通道 + zip 媒体 sourceUrl 预入库 + externalRef 幂等 + WAF 退避;两站实战(33MB WXR 也解析了) | 缺 SQL 直连通道(第三通道);ACF 字段发现未做 | +| 4 | Sitemap/HTML/Playwright 扫描 | ❌ | 仅拉取老站 sitemap.xml(1 级 index 递归) | 无 HTML 链接发现爬虫、无 Playwright;V3.0 的十来源 URL 全集完全没有 | +| 5 | 原始快照与差量同步 | 🟡 | WXR 原件留档 storage/wxr;重跑幂等更新 | **无冲突队列、无人工编辑保护**(重跑无条件整条覆盖 data)、无新增/更新/删除/冲突的差量分类报告 | +| 6 | 统一内容与内容修订 | ✅ | content_revisions 不可变(插入式)、公开端点只读 published 修订、5 种内容类型带 Schema | 缺乐观锁(last-write-wins,多标签页会互相覆盖);archived 状态无入口 | +| 7 | URL 注册表与路由编译 | 🟡 | 301 存 site_settings.redirects(JSONB);三格式产物(_redirects/nginx conf/csv);三色报告 🔴missing=0 实战达标 | 无独立路由注册表(normalized key/route_kind/indexable);无 410/查询参数路由;无部署能力预检 | +| 8 | SEO 快照与差异报告 | 🟡 | 出站 SEO 全套(title/desc/canonical/hreflang/og/twitter/noindex)+ Yoast 随迁 + 门禁查 title/H1/canonical + sitemap 一致性 | 无"旧站真实 HTML vs 新站"三套数据对比;无 P0–P3 分级差异报告 | +| 9 | 媒体迁移与旧路径保持 | ✅ | 全量转存 + sourceUrl 幂等去重 + alt + 多尺寸;两站 5494 张实战、替换零残留 | 老站已被外链引用的媒体旧 URL 是否 301 未处理(对齐 V3.0"旧路径保持") | +| 10 | 主题/模板/板块协议 | ❌ | templates 表存在但**空表无种子**;主题 Tab 能编辑 token 但**运行时没人消费(死线)**;后台表单全部硬编码;建站只有 1 个硬编码模板选项 | **最大缺口**(平台化文档自己标注)。ERD 里的 block_instances/template_slots/component_versions 设计未落地 | +| 11 | 组件化公共包 | 🟡 | astro runtime 内共享数据源 + base 组件 + 183 个设计 token(契约测试保护);domain-contracts 类型包 | 无四层复用分层、无多主题目录结构(themes/)、无跨主题复用验证 | +| 12 | Astro 全量静态构建 | ✅ | 版本化产物(.artifacts/,KEEP=10)+ 4 阶段原子发布 + 门禁 + 回滚(可再滚回) | **缺构建输入快照**:构建时实时拉 API,失败时**静默回落 seed 演示数据**(高危!) | +| 13 | 预览、验收、发布、回滚 | 🟡 | 验收(gate.mjs)/发布/回滚完整且实战 | **草稿预览缺失**(只能发布后看);无生产冒烟 | +| 14 | Nginx/SSH 发布 | ❌ | 产物只落本地目录;全库 grep 无 rsync/sftp/ssh/部署代码 | **两站上线都阻塞在这**(台账:"部署阿里云(等凭据)"——凭据之外还缺整个部署器) | +| 15 | S3/OSS + CDN 发布(与 14 二选一) | ❌ | MinIO 容器起了但无任何代码使用 | 同上 | +| 16 | 表单基础服务 | 🟡 | leads 提交 + zod 校验 + 状态流转 + 审计 | 无垃圾防护/验证码/限流;**邮件通知是 TODO 注释**(设置里有"接收邮箱"字段但不发);无 CRM 转发 | +| 17 | 备份、监控和操作日志 | 🟡 | audit_logs 覆盖全部变更端点(actor/before/after/requestId) | **无任何备份脚本**(94MB PG + 1.3GB 媒体全在开发机一块盘上);无监控告警;Fastify logger 关闭;ClickHouse/Redis/MinIO 容器闲置 | + +--- + +## 3. cms 超出 V3.0 预期的地方(不要在改造中丢掉) + +1. **WXR 正则解析器**(universal-row.ts):无 XML 库依赖,处理了 `_thumbnail_id`、`_product_image_gallery`、`wppop_sections` PHP 反序列化、Yoast 主分类——这些实战细节 V3.0 只写了方向。 +2. **WAF/验证码对抗**:REST 通道 202 挑战页快速失败 + 指数退避(30/90/180s)+ 全局节流——SiteGround 拦截是真实踩坑沉淀。 +3. **三色报告闭环**:externalRef ∪ sitemap 双源对照,🔴missing=0 作为发布关卡已在两站达标。 +4. **契约测试纪律**:18 事件目录冻结、183 token 全量校验、组件零颜色字面量、WP 文本清洗规则——V3.0 §24 要求的契约测试已有雏形。 +5. **多语言位**(entry_locales + hreflang 渲染):V3.0 把多语言放到 V1.1,cms 已有编辑位和渲染。 + +--- + +## 4. 上线前必须处理的五个高危问题(按危险程度排序) + +| # | 问题 | 危险场景 | 修法(对应 V3.0 条目) | +|---|---|---|---| +| 1 | **构建 seed 兜底**:API 拉取失败时静默用演示数据构建 | control-api 抖动 → 演示内容被构建、过门禁、发布上线 → 线上变成假站 | 构建改为**先冻结输入快照**(拉全量数据 → 落盘 → 校验 → 再构建);失败即中止(V3.0 §13.1) | +| 2 | **零备份**:数据库、媒体、产物全在开发机 D 盘 | 磁盘坏 = 两站迁移成果 + 平台数据全灭 | pg_dump 定时 + storage/ 与 .artifacts/ 同步到第二存储;先手动后自动(V3.0 §20) | +| 3 | **认证弱**:token 无过期无撤销 + 登录页预填默认凭据 + 无限流 | 部署到公网后管理后台即刻成为攻击面 | token 加过期+撤销表;删除预填凭据并改密;登录限流;MFA 可后置(V3.0 §19.1) | +| 4 | **无部署器**:产物出不去本地 | 两站永远"差最后一步"上线 | 实现 rsync/SSH 部署器(先)+ OSS/CDN(后);附带上线检查表(V3.0 附录 A) | +| 5 | **重跑覆盖人工编辑**:迁移重跑无条件覆盖 data | 旧站同步时把后台手工修好的内容冲掉 | override 标记 + 冲突队列(V3.0 §8.4) | + +--- + +## 5. 改造路线图(C 路线:四梯队) + +### 第一梯队 · 解锁上线与数据安全(立即,1–2 周) +1. **部署器 v1**:rsync/SSH 到阿里云 ECS + nginx conf 应用 + 部署记录 + 产物哈希校验 → 把 hesupipe 真正发上线(对齐 V3.0 #14) +2. **备份**:每日 pg_dump + storage 增量同步 + 恢复演练一次(对齐 V3.0 #17、§20) +3. **构建输入冻结**:移除 seed 兜底;构建前物化站点数据快照;快照哈希进产物元数据(对齐 V3.0 #12、§13.1) +4. **认证加固**:token 过期/撤销、清默认凭据、登录限流(对齐 V3.0 #2) + +### 第二梯队 · 平台化核心(3–6 周,magicbridge 复工的前置) +5. **主题系统落地**(V3.0 #10/#11,对应 cms 平台化 P2–P4): + - templates 表种子 + corporate-pro 主题物化(把现在写死的布局抽成第一套主题) + - **打通 token 死线**:让主题 Tab 的编辑真正影响构建产物 + - Schema 驱动表单(字段类型注册表 → 动态渲染),下线硬编码表单 + - themes/ 多主题目录 + 按 templateKey 构建(为 magicbridge 汽车站主题做准备) +6. **草稿预览**:预览构建目录 + 访问控制 + noindex(V3.0 #13) + +### 第三梯队 · 迁移质量增强(按站需要,穿插进行) +7. **差量同步 + 冲突保护**:override 标记、差量分类报告(新增/更新/删除/冲突)、人工修改不被静默覆盖(V3.0 #5)——旧站仍在更新时必需 +8. **URL 注册表**:redirects 从 settings JSONB 升级为独立表(ERD 本来就这么设计的),补 route_kind/410/查询参数(V3.0 #7) +9. **SEO 差异报告**:老站 HTML Head 抓取 vs 新站预览对比,P0–P3 分级接入门禁(V3.0 #8) +10. **HTML 爬虫**:链接发现补全 URL 全集(sitemap+WXR+爬虫三源);Playwright 仅按需(V3.0 #4) + +### 第四梯队 · 运营与规模(上线后迭代) +11. 表单强化:垃圾防护、邮件通知(消灭 TODO)、CRM 转发(V3.0 #16) +12. 监控告警 + 结构化日志 + 构建历史持久化(V3.0 #17) +13. WP SQL 第三通道、ACF 字段发现(V3.0 #3 补全) +14. event-gateway/ClickHouse 分析栈:**单独决策**——它与建站平台正交,要么砍掉容器要么立项,别挂着 + +--- + +## 6. 明确不照搬 V3.0 的部分(单人 + AI 模式的取舍) + +| V3.0 设计 | 取舍 | 理由 | +|---|---|---| +| MFA + 恢复码完整体系 | 后置 | 单运营者;先用强密码 + token 过期 + 限流 + IP 白名单顶住,公网暴露后再上 | +| 构建沙箱容器化(断网/限额/无密钥) | 暂缓 | 单人开发无第三方适配器代码风险;**先移除 seed 兜底**(真实风险排序相反) | +| CAS 发布锁 / 环境锁 / 租约心跳 | 暂缓 | 单运营者无并发发布冲突;构建单站串行已足够 | +| 十来源 URL 全集 | 渐进 | sitemap + WXR + 日志三源已覆盖大半;GSC/GA4 等按站补 | +| NestJS + BullMQ 任务队列全家桶 | 观察 | 现状"control-api spawn pnpm"土但能跑;队列在任务变多(定时备份/批量迁移)后再上 | +| 5 人团队 20 周排期 | 不适用 | 1 人 + AI 串行;按梯队推进,每梯队以"真实站点闭环"为验收 | + +--- + +## 7. 文档与现实偏差清单(建议顺手修正) + +1. `平台化总体设计与实施计划.md` §3:"X-Site-Id 未生效(已知缺陷)"——**已过时**,代码已修复且有 e2e 测试。 +2. ERD-V1(45 张表、ClickHouse 4 表)是**设计蓝图不是实现**:实际 ORM 是 Drizzle(非 Prisma),redirects 是 settings JSONB(非独立表),site_snapshots/publish_manifests/artifacts/releases 等 ERD 表均未建。 +3. `services/build-worker`、`services/event-gateway` 是 README 空壳;真实构建在 control-api + astro runtime 脚本里。 +4. 登录页(admin-web)预填了 `admin@hesupipe.com / hesu-admin-2026`——上线前必须清除。 +5. docker-compose 的 ClickHouse/Redis/MinIO 无代码消费——要么用起来要么先摘掉,避免"看起来有"的假象。 + +--- + +## 8. 下一步建议(本周可做) + +1. 部署器 v1 动工前,先向用户/托管方确认:目标形态是阿里云 ECS(nginx)还是 OSS+CDN——决定先写 rsync 还是 OSS 上传。 +2. 手动做一次全量备份(pg_dump + storage 拷贝到第二块盘/网盘),不等脚本。 +3. 删除构建 seed 兜底(一行开关级改动,风险最高、成本最低)。 +4. 把 magicbridge 的主题设计输入(HTML 稿/参考站)排上日程——第二梯队一完成它就能复工。 diff --git a/cms现状与SiteForge差距分析_V2.0.md b/cms现状与SiteForge差距分析_V2.0.md new file mode 100644 index 0000000..b2685d1 --- /dev/null +++ b/cms现状与SiteForge差距分析_V2.0.md @@ -0,0 +1,1011 @@ +# cms 代码库现状与 SiteForge V3.0 差距分析 V2.0 + +> 评估对象:`D:\project\cms` +> 目标基线:`D:\project\cms-one\SiteForge_完整项目计划方案_V3.0.md` +> 版本:V2.0 +> 日期:2026-10-20 +> 用途:确定旧 CMS 的真实成熟度、可复用资产、生产风险及 SiteForge 改造顺序。 +> 说明:本报告基于源码、Schema、测试代码、脚本和现有项目文档的静态核查;本轮没有重新安装依赖、启动全部服务或执行完整测试,因此“存在测试”不等于“本轮已经验证通过”。 + +--- + +## 1. 执行结论 + +`D:\project\cms` 已经不是空项目,也不是单纯的技术样例。它具备以下可运行主干: + +- Vue 3 + TypeScript + Element Plus + Art Design Pro 管理后台。 +- NestJS + Fastify + Drizzle + PostgreSQL 控制 API。 +- WordPress REST/WXR 迁移、媒体抓取和基础幂等导入。 +- 内容类型、工作副本、不可变修订和发布修订。 +- Astro 静态网站运行时、基础 SEO 输出和本地质量门禁。 +- 本地版本化产物、基础回滚、站点隔离测试和迁移测试。 +- PostgreSQL、Redis、MinIO、ClickHouse 的开发环境配置。 + +因此,SiteForge 不应从零重建。推荐采用: + +> **以 cms 源码为实现底座,以 SiteForge V3.0 为产品和架构基线,按领域净化、补强和替换。** + +但 cms 目前仍然是“单站 MVP 向平台化演进”的原型,尚不具备安全生产上线所需的完整能力。主要阻塞点不是页面能否构建,而是: + +1. 构建输入不冻结,API 失败时可能用 Seed 演示数据生成正式产物。 +2. 所谓“原子发布”实际是删除旧目录后复制新目录,并非原子切换。 +3. 构建历史、状态和锁只存在进程内存中。 +4. 认证、CORS、默认凭据、SSRF、SVG、富文本等安全边界不足。 +5. 迁移会自动发布,缺少审核、冲突保护和批次回滚。 +6. 没有正式 URL 注册表,普通页面可能错误跳转首页。 +7. 没有完整部署适配器、生产 HTTP 验证和真正可逆的 Release 回滚。 +8. 没有系统备份、恢复演练、监控和告警。 +9. 主题 Token 和模板表已预留,但主题协议、板块协议和 Schema 驱动后台没有真正落地。 + +按 SiteForge V3.0 的严格口径,17 项能力现状建议重新评为: + +| 状态 | 数量 | 说明 | +|---|---:|---| +| ✅ 基本达到 | 1 | Astro 全量静态构建;仍需生产化加固 | +| 🟡 部分具备 | 12 | 已有代码或局部闭环,但未达到 V3.0 验收条件 | +| ❌ 缺失 | 4 | 扫描系统、主题协议以及两类部署适配器 | + +其中 Nginx/SSH 与 S3/OSS+CDN 是目标部署方式二选一,不要求同时完成;当前两者均未实现。 + +--- + +## 2. 评估方法与成熟度定义 + +### 2.1 评估依据 + +本报告交叉核对以下证据: + +- 实际 TypeScript/Vue/Astro 源码。 +- Drizzle Schema 和 Seed。 +- 单元、契约和 E2E 测试代码。 +- Build、Gate、Redirect 和 Release 脚本。 +- Docker Compose 与 CI 配置。 +- 迁移台账、ADR、组件契约、主题 Token 契约和导入模板文档。 +- SiteForge V3.0 的 V1 必须交付能力和安全要求。 + +不采用“README 声称存在即可视为完成”的判断方式。文档中的未来设计、空目录、TODO、未被调用的容器和表结构草案均不算已实现能力。 + +### 2.2 成熟度等级 + +为避免再次把“代码存在”误判成“生产可用”,后续所有能力统一使用五级成熟度: + +| 等级 | 定义 | 是否可视为完成 | +|---|---|---:| +| L0 设计 | 仅有文档、接口设想或空目录 | 否 | +| L1 实现 | 有代码,但缺关键测试或未形成闭环 | 否 | +| L2 自动验证 | 有自动测试并在固定环境通过 | 否 | +| L3 真实数据验证 | 使用真实站点数据完成本地/预发布验证 | 部分 | +| L4 生产验证 | 完成真实部署、HTTP 验收、监控和回滚演练 | 是 | + +本报告的“✅ 基本达到”至少要求核心验收目标达到 L3;正式上线验收必须达到 L4。 + +### 2.3 评级符号 + +- ✅ 基本达到:核心功能存在,接近目标验收,但仍可能有生产加固项。 +- 🟡 部分具备:已有可复用实现,但缺少目标流程、数据模型、安全或验收闭环。 +- ❌ 缺失:没有实际实现,或只有文档/空壳。 + +--- + +## 3. cms 实际代码资产盘点 + +### 3.1 已存在并可运行演进的代码 + +| 领域 | 目录 | 实际状态 | +|---|---|---| +| 管理后台 | `apps/admin-web` | Art Design Pro 基础完整,包含站点、内容、媒体、迁移、导航、设置、线索页面;夹杂大量演示代码 | +| 控制 API | `services/control-api` | NestJS/Fastify/Drizzle;认证、站点、内容、媒体、迁移、线索、构建模块已存在 | +| 静态运行时 | `runtimes/astro-site-runtime` | Astro 页面、公共组件、SEO 输出、Sitemap、Redirect 和 Gate 已存在 | +| 领域契约 | `packages/domain-contracts` | 当前主要是 ID 和事件类型,范围有限 | +| 构建 Worker | `services/build-worker` | 基本为空壳,实际构建仍由 control-api 启动子进程 | +| 事件网关 | `services/event-gateway` | 基本为空壳,不应计入现有能力 | +| 基础设施 | `infrastructure` | PostgreSQL/Redis/MinIO/ClickHouse 容器配置;Redis/MinIO/ClickHouse 尚未形成完整业务闭环 | +| 测试 | `tests`、`services/control-api/test` | 有契约测试、隔离测试、内容测试和迁移测试,但本轮未重新执行 | + +### 3.2 实际数据库范围 + +实际 Drizzle Schema 主要包含: + +- `sites` +- `site_locales` +- `users` +- `content_type_definitions` +- `content_entries` +- `entry_locales` +- `content_revisions` +- `content_relations` +- `audit_logs` +- `site_settings` +- `site_nav_items` +- `templates` +- `leads` +- `media_assets` + +旧 ERD 文档中的 Route、Snapshot、Import Batch、Build Job、Release、Artifact、Form Version、Consent、身份分析等大量表尚未进入实际 Schema。后续必须以数据库迁移文件和运行代码为准,不能把 ERD 蓝图当成现状。 + +### 3.3 已有真实价值资产 + +最值得保留的资产包括: + +1. WordPress REST/WXR 解析和真实兼容经验。 +2. `UniversalRow` 中间数据结构。 +3. `externalRef`、Slug 和 `sourceUrl` 的幂等思路。 +4. 内容工作副本和不可变修订。 +5. 显式站点上下文和已有隔离测试。 +6. Astro 静态站页面、组件和 SEO 输出基础。 +7. 主题 Token、组件契约和导入契约文档。 +8. Gate、Redirect、迁移 E2E 等测试资产。 +9. Art Design Pro 后台工程壳。 + +--- + +## 4. SiteForge V1 十七项能力严格对照 + +### 4.1 总表 + +| # | V3.0 必须交付能力 | 现状 | 成熟度 | 主要证据 | 核心差距 | +|---:|---|---|---|---|---| +| 1 | 多站点与环境管理 | 🟡 | L2 | sites、站点上下文、隔离 E2E | 无 environment 模型;部分查询仍缺 site 条件;构建状态仅内存 | +| 2 | 单一超级管理员 | 🟡 | L1 | 登录、bcrypt、基础审计 | 当前仍是站点级用户和 role 字段;Token 无过期/撤销;无 MFA/恢复;默认凭据和默认 Secret | +| 3 | WordPress REST/WXR/SQL/uploads 导入 | 🟡 | L3 子集 | REST、WXR、媒体远程抓取、单文件 sourceUrl 预入库、迁移 E2E | 无 SQL;无真正 uploads ZIP 解包;ACF 仅局部特例;导入后自动发布 | +| 4 | Sitemap/HTML/Playwright 扫描 | ❌ | L1 子集 | 仅 Sitemap 拉取 | 无 HTML 爬虫、浏览器渲染补扫、robots、日志/GSC 导入、扫描任务与审计清单 | +| 5 | 原始快照与差量同步 | 🟡 | L1 | WXR 文件按 Hash 落盘、重跑更新 | WXR 未绑定正式快照记录;REST 无原始快照;无新增/更新/删除/冲突分类;无人工编辑保护 | +| 6 | 统一内容与内容修订 | 🟡 | L2 | 5 类内容、工作副本、draft/published 修订 | 无修订恢复;无乐观锁;无删除/归档入口;Locale 硬编码 en/es;后台部分表单硬编码 | +| 7 | URL 注册表与路由编译 | 🟡 | L2 子集 | Redirect JSON、三种规则产物、基础报告 | 无 route_registry;无唯一占用、410、参数规则、环检测、部署能力预检;普通页面可能跳首页 | +| 8 | SEO 快照与差异报告 | 🟡 | L2 子集 | SEO Head、Yoast 部分字段、Gate | 无旧 HTML/导入值/新 HTML 三方快照;无 P0–P3 差异;无真实 HTTP 门禁 | +| 9 | 媒体迁移与旧路径保持 | 🟡 | L3 子集 | 全量抓取、sourceUrl 去重、alt、多尺寸 | 旧媒体 URL 未完整重定向;本地盘;无 Hash/MIME 魔数/SVG 清理/引用保护 | +| 10 | 主题/模板/板块协议 | ❌ | L0–L1 | templates 表、主题编辑 Tab | 模板无完整注册和版本;Token 未稳定驱动运行时;无 Block Manifest、Slot、Renderer、升级迁移 | +| 11 | 组件化公共包 | 🟡 | L2 子集 | Astro 公共组件、Token 契约测试、domain-contracts | 无四层分层、公共渲染包、多主题复用验证和组件版本策略 | +| 12 | Astro 全量静态构建 | ✅ | L3 | Astro 全量构建、独立 dist、基础 Gate | 构建实时访问 API且会回退 Seed;依赖/环境不可完全复现;需冻结快照和产物 Manifest | +| 13 | 预览、验收、发布、回滚 | 🟡 | L1–L2 | 本地 Gate、本地产物归档、本地回滚 | 无草稿预览、访问控制、持久化 Release、真正原子切换、生产冒烟和生产等价回滚演练 | +| 14 | Nginx/SSH 发布 | ❌ | L0 | 可生成 nginx redirect 片段 | 无 SSH/SFTP/rsync 部署器、凭据管理、临时版本目录、远端校验和切换 | +| 15 | S3/OSS + CDN 发布 | ❌ | L0 | MinIO 容器配置 | 无对象存储适配器、版本前缀、入口指针、CDN 刷新和回滚;与 #14 二选一 | +| 16 | 表单基础服务 | 🟡 | L1 | Lead 提交、Zod、后台状态更新 | 无限流、反垃圾、隐私同意、通知重试、Webhook、保留策略;存在更新隔离缺陷 | +| 17 | 备份、监控和操作日志 | 🟡 | L1 | audit_logs 和部分 writeAudit | 无自动备份/恢复演练/监控/告警;Fastify logger 关闭;审计覆盖不完整 | + +### 4.2 对评级影响最大的事实修正 + +#### WordPress 导入不是完整的三通道 + +代码实现了 REST 和 WXR。媒体接口支持单个文件携带 `sourceUrl` 入库,但后台 ZIP 选择目前只读取文件信息和估算数量,没有完整的 ZIP 上传、解包、目录匹配、安全扫描和批次报告。因此不能把它等同于完整的 `wp-content/uploads` 导入。 + +#### 内容修订不等于内容回滚 + +当前系统可以创建和列出 draft/published 修订,但缺少读取指定修订全文并恢复为工作副本的正式接口。SiteForge V3.0 要求“可编辑和回滚”,因此只能评为部分具备。 + +#### 当前发布不是原子发布 + +`release.mjs` 的关键步骤是: + +```text +删除 dist/ +复制 candidate 到 dist/ +删除 candidate +``` + +删除与复制之间存在不可用和半成品窗口。真正的文件系统发布应使用同文件系统版本目录加符号链接/目录重命名切换;对象存储应使用版本前缀加入口指针。 + +#### 当前回滚不是完整可逆回滚 + +回滚逻辑会删除更新版本的 Artifact,再复制上一版本。这样无法可靠地恢复回滚前版本,也没有同步恢复路由、响应头、动态配置和 CDN 状态。 + +#### 站点隔离尚未完全修复 + +主要端点已经接入站点上下文,但仍发现: + +- Lead 状态更新和回读只按 ID,不同时限定 `site_id`。 +- 内容修订列表只按 `entry_id`,没有传入和校验 `site_id`。 +- 部分更新在完成前置检查后只按对象 ID 执行,仍需统一 Repository 约束和测试覆盖。 + +所以应表述为“主路径已有隔离基础,尚未完成系统性隔离审计”。 + +--- + +## 5. 当前已验证的优势与保留原则 + +### 5.1 WordPress 迁移兼容经验 + +现有 WXR 解析处理了 `_thumbnail_id`、产品图库、部分主题私有字段、Yoast 主分类和 PHP 序列化数据。这些属于真实迁移经验,应保留为适配器测试夹具和转换规则。 + +但“使用正则而无需 XML 库”不是架构优势本身。对更大 WXR、CDATA 边界、实体、命名空间和异常 XML,需要增加: + +- 流式或受控 XML 解析。 +- 文件大小、节点数和处理时限。 +- 恶意 XML/压缩炸弹测试。 +- 解析错误定位和可重试批次。 + +### 5.2 WAF 处理经验 + +REST 客户端已有全局节流和 403/429 退避,媒体抓取会识别 HTML 挑战页并快速失败。这些逻辑应保留,但需要统一到可配置的采集策略中,并增加: + +- 域名并发上限。 +- 全任务请求预算。 +- 可恢复重试状态。 +- SSRF 验证。 +- 失败资产清单和补传流程。 + +### 5.3 URL 对照报告 + +`externalRef + Sitemap + Redirect` 的 kept/redirected/missing 报告很有价值,适合作为 `route_registry` 和 URL 基线报告的原型。 + +需要注意:`missing=0` 只说明当前输入集合都找到了去处,不代表: + +- 输入集合覆盖了全部旧 URL。 +- Redirect 目标语义正确。 +- 没有重定向链和重定向环。 +- 目标页面返回 200。 +- Canonical、Locale 和索引状态正确。 +- 普通页面没有被错误跳转首页。 + +### 5.4 契约测试 + +事件目录、Token、组件样式和 WordPress 文本清理的契约测试应保留。SiteForge 后续应将契约测试扩展到: + +- Theme Manifest。 +- Block Manifest。 +- Source Adapter。 +- Deploy Adapter。 +- Route Compiler。 +- Build Input Snapshot。 +- Release Manifest。 +- Form Definition。 + +### 5.5 多语言基础 + +现有 `entry_locales`、hreflang 和多语言 UI 可以作为基础,但当前代码大量硬编码 `en/es`,导入中其他 Locale 甚至会被静默归为 `en`。因此它是“多语言预留”,不是完整的通用多语言能力。 + +--- + +## 6. 上线前必须处理的 P0 风险 + +### P0-1 构建可能发布 Seed 演示数据 + +产品、新闻、案例和站点配置在 API 不可达或无数据时会回退到内置默认数据。该策略适合本地 Demo,不适合生产构建。 + +风险: + +- API 短暂异常时,构建仍返回成功。 +- Gate 只能检查 HTML 结构,无法判断内容是否属于正确站点。 +- 演示内容可能被正式部署并被搜索引擎收录。 + +整改: + +- 生产构建禁止任何 Seed fallback。 +- 构建开始先生成不可变 `build_input_snapshot`。 +- 校验站点、Locale、内容数、路由数、媒体数和快照 Hash。 +- 快照不完整立即失败,不进入 Astro 构建。 + +### P0-2 发布切换和回滚不安全 + +风险: + +- 删除旧目录后复制失败导致站点不可用。 +- 并发构建可能覆盖较新的产物。 +- 回滚会删除新版,不能可靠前滚。 +- 路由规则和 HTML 不是同一事务切换。 + +整改: + +- 建立持久化 `build_jobs`、`releases`、`artifacts` 和 `publish_locks`。 +- 每个 Release 使用不可变版本目录。 +- 文件系统通过 rename/symlink 指针切换;对象存储使用版本前缀和入口指针。 +- 使用 `active_release_id` 比较并交换,防止旧任务覆盖新版本。 +- 回滚只切换到已验证 Release,不删除其他 Release。 + +### P0-3 认证与公网暴露风险 + +已发现: + +- 自制 HMAC Token 无过期、无刷新、无撤销。 +- Token 默认 Secret 为开发值。 +- 登录页预填默认账号密码。 +- CORS 使用任意 Origin 反射。 +- 无 MFA、恢复码、登录限流和异常提醒。 +- 当前用户模型仍是站点级并保留 role 字段,不符合平台级单超管模型。 + +整改: + +- 平台级 `super_admin`,不实现复杂 RBAC。 +- 使用成熟会话/JWT 库和强密码哈希。 +- 短期会话、HttpOnly/Secure/SameSite Cookie、CSRF 防护。 +- MFA、恢复码、会话列表与撤销。 +- 删除默认凭据和默认 Secret;启动时缺 Secret 直接失败。 +- 收紧 CORS,后台如暂未完成 MFA,只能放在 VPN/零信任/IP 白名单后。 + +### P0-4 SSRF 与不受控下载 + +WordPress URL、Sitemap URL 和媒体 URL 会触发服务端 Fetch。目前缺少完整的地址安全控制。 + +风险包括访问: + +- localhost、内网服务。 +- 云主机元数据地址。 +- DNS 重绑定目标。 +- 重定向后的受限地址。 +- 超大响应或长期连接。 + +整改: + +- 仅允许 HTTP/HTTPS 和批准端口。 +- DNS 解析后拒绝回环、内网、链路本地、保留地址和元数据地址。 +- 每次重定向重新校验。 +- 设置连接、响应、文件、批次和总任务预算。 +- 采集任务使用受限网络出口,不携带控制面密钥。 + +### P0-5 SVG、MIME 和富文本安全 + +媒体上传允许 SVG,但没有净化;文件类型主要相信 multipart/远端 MIME;WordPress HTML 也没有形成明确的白名单清理层。 + +整改: + +- 检查文件魔数和实际解码结果。 +- SVG 默认禁用,或使用可靠净化器并以安全响应头提供。 +- 对 HTML 使用明确的元素、属性、协议、iframe 域名白名单。 +- 删除 script、事件属性、危险 URL 和不受信任嵌入。 +- 发布产物增加 CSP 和敏感信息扫描。 + +### P0-6 迁移自动发布和人工内容覆盖 + +当前迁移批次导入后会逐条调用发布;重跑还会覆盖工作副本,没有字段级或条目级人工修改保护。 + +整改: + +```text +上传/采集 +→ 原始快照 +→ 解析 +→ 映射 +→ 校验 +→ 导入草稿 +→ 冲突处理 +→ 人工审核 +→ 预览 +→ 发布 +``` + +必须建立: + +- `import_batches` 和 `import_items`。 +- Source Fingerprint 和 Mapping Version。 +- 新增、更新、删除、无变化、冲突分类。 +- `manual_override` 或字段来源元数据。 +- 批次撤销和差异报告。 + +### P0-7 站点隔离缺口 + +已发现 Lead 状态更新、修订读取等查询没有完整带上 `site_id`。 + +整改: + +- 所有 Repository 方法必须显式接收 `siteId`。 +- 所有业务读写必须使用 `site_id + object_id`。 +- 建立跨站读取、更新、删除、枚举和缓存污染测试。 +- 对关键表考虑 PostgreSQL RLS 作为纵深防御。 + +### P0-8 无备份与恢复闭环 + +当前数据库、WXR、媒体和 Artifact 主要位于本地开发环境,没有可验证的恢复链路。 + +整改: + +- PostgreSQL 定时备份和关键迁移/发布前备份。 +- WXR、媒体、快照、Release、报告和路由规则复制到第二存储。 +- 备份加密、校验、保留策略和访问控制。 +- 在空环境完成至少一次恢复演练并记录 RPO/RTO。 + +### P0-9 路由错误可能造成 SEO 损失 + +当前路由来源是 `site_settings.redirects` JSON。非产品/案例/新闻类型可能被自动指向 `/en/`,容易形成 Soft 404。 + +整改: + +- 建立 `route_registry`。 +- 路由唯一占用和规范化。 +- 对每条旧 URL 明确选择保留、301、410 或人工处理。 +- 禁止无法映射的页面默认跳首页。 +- 检查环、链、跨 Locale、Canonical 和最终 HTTP 状态。 + +--- + +## 7. P1 生产化与平台化差距 + +### 7.1 缺少正式环境模型 + +`sites` 有站点和域名,但没有开发、预览、预发布、生产等 Environment 实体。域名、部署目标、当前 Release、凭据引用和发布锁应属于 Environment,而不是散落在站点设置或进程变量中。 + +建议实体: + +- `site_environments` +- `deployment_targets` +- `environment_domains` +- `environment_publish_locks` +- `releases` +- `release_artifacts` + +### 7.2 缺少持久化任务系统 + +当前 BuildService 直接 `spawn pnpm`,历史保存在内存中。即使暂不采用 BullMQ,也必须先解决: + +- Job 持久化。 +- 幂等键。 +- 重启恢复。 +- 超时和取消。 +- 日志存储。 +- 失败重试和死信状态。 +- 同站点同环境串行。 + +推荐 Redis + BullMQ;如果先用数据库任务表,也要满足同样的状态和恢复语义。 + +### 7.3 主题系统尚未真正成立 + +当前存在模板表、Theme Tab 和 Token,但未形成可版本化的主题契约。 + +SiteForge 应采用四层组件结构: + +1. 基础 UI:Container、Button、Image、RichText、FormControl。 +2. 业务区块:Hero、ProductGrid、NewsList、FAQ、CTA、ContactForm。 +3. 页面模板:首页、列表页、详情页、普通页面、落地页。 +4. 主题:Token、字体、布局、装饰、默认区块组合和可用模板集合。 + +主题包建议结构: + +```text +themes// + theme.manifest.ts + tokens.ts + blocks/ + layouts/ + templates/ + styles/ + migrations/ +``` + +每个 Block Manifest 应声明: + +- 版本。 +- 字段 Schema。 +- 默认值。 +- 允许的 Slot 和父子关系。 +- SEO 和可访问性行为。 +- 媒体字段。 +- 数据依赖。 +- 兼容主题版本。 + +### 7.4 后台尚未完全 Schema 驱动 + +虽然内容类型表保存了字段定义,但后台产品、新闻、案例等页面仍存在大量硬编码逻辑,站点管理页面体积过大。 + +需要拆分: + +- Schema Form Renderer。 +- Field Registry。 +- Validation Adapter。 +- Media/Reference/Repeatable 等复杂字段组件。 +- 内容列表配置。 +- 内容编辑器 Shell。 +- 预览和发布面板。 + +### 7.5 SEO Gate 仍是基础版 + +现有 Gate 能检查部分 Title、Description、Canonical、H1、内部链接、图片和 Sitemap,但主要依赖正则和本地产物。 + +还需要: + +- DOM 解析。 +- 重复 Title/Description。 +- Canonical 唯一性和目标状态。 +- hreflang 双向性。 +- JSON-LD 合法性。 +- robots/noindex 冲突。 +- Redirect 环和多跳。 +- 孤儿页面。 +- 旧 URL 覆盖率。 +- 真实部署后的 HTTP 状态、响应头和内容抽样。 +- Lighthouse/性能预算和基础可访问性。 + +### 7.6 媒体系统仍是本地文件原型 + +应从本地文件升级为: + +- S3 兼容对象存储。 +- 内容 Hash 去重。 +- 原文件与派生变体分离。 +- AVIF/WebP 异步处理。 +- `media_usage` 引用关系。 +- 软删除和延迟物理删除。 +- Alt、焦点、尺寸、版权和来源元数据。 +- 对象存储生命周期与备份。 + +### 7.7 Form API 不完整 + +当前 Lead 模块只能视为最小提交接口,需要补充: + +- 表单定义和版本。 +- 蜜罐、验证码、限流和重复提交保护。 +- 来源页面、UTM、Referrer 和 Locale。 +- 隐私同意版本和时间。 +- 邮件/Webhook/CRM 通知队列与重试。 +- 数据保留、导出和删除策略。 +- CSV 公式注入防护。 + +--- + +## 8. 可直接复用、改造复用和暂缓内容 + +### 8.1 高价值直接继承 + +| 资产 | 处理方式 | +|---|---| +| pnpm Workspace/Turborepo 骨架 | 保留,升级 CI 和锁文件策略 | +| Art Design Pro 后台壳 | 保留布局、请求、状态、表格表单组件 | +| NestJS/Fastify/Drizzle 基础 | 作为模块化单体控制面起点 | +| WordPress REST/WXR 解析 | 保留解析规则并增加正式 Adapter 接口 | +| UniversalRow | 演进为标准化 Source Record | +| 内容修订 | 保留不可变修订思想,补恢复和乐观锁 | +| Astro 运行时 | 保留构建基础和可复用页面组件 | +| Gate/Redirect 脚本 | 作为新质量门禁和路由编译器的起点 | +| 主题 Token/组件契约 | 合并进 SiteForge Theme/Block 契约 | +| 迁移和隔离测试 | 保留并扩大覆盖范围 | +| PostgreSQL/Redis/MinIO | 沿用技术选型,固定版本和生产配置 | + +### 8.2 必须重构后使用 + +| 领域 | 不能原样使用的原因 | +|---|---| +| Auth | 自制 Token、默认 Secret、站点级用户、多角色遗留 | +| BuildService | 进程内状态、直接 spawn、无持久化恢复 | +| release.mjs | 非原子替换、无远端发布事务 | +| rollback | 删除新版、不能完整恢复路由/配置/CDN | +| MigrationService | 迁移即发布、Locale 硬编码、无冲突队列 | +| Redirect JSON | 无正式路由所有权、唯一性和状态模型 | +| MediaService | 本地盘、MIME/SVG 风险、无引用保护 | +| LeadService | 隔离缺陷、无反垃圾/隐私/通知可靠性 | +| Theme Tab | Token 到运行时链路不完整 | +| 管理后台业务页面 | 硬编码、演示代码多、单页过大 | + +### 8.3 当前阶段暂缓 + +- ClickHouse 行为分析。 +- Event Gateway。 +- 客户画像和身份合并。 +- 高级增长分析。 +- 多租户计费。 +- 复杂 RBAC。 +- 工作流审批。 +- 增量静态构建;V1 先按站全量构建。 + +### 8.4 禁止直接复制 + +- `.data` +- `storage` +- `node_modules` +- `.turbo` +- `.playwright-mcp` +- `.env` 和任何凭据 +- 构建缓存和日志 +- 未授权的客户内容、媒体、线索和导入文件 + +真实数据如需转为测试夹具,必须获得授权、脱敏并缩减为最小必要样本。 + +--- + +## 9. 推荐目标架构 + +### 9.1 控制面 + +```text +Vue 3 / Art Design Pro + ↓ +NestJS 模块化单体 + ├─ Auth + ├─ Sites / Environments + ├─ Content / Revisions + ├─ Routes / SEO + ├─ Media + ├─ Migration / Import Batches + ├─ Themes / Blocks + ├─ Forms / Leads + ├─ Build / Release + └─ Audit / Operations + ↓ +PostgreSQL + Redis + Object Storage +``` + +### 9.2 生产面 + +```text +Frozen Site Snapshot + ↓ +Isolated Build Worker + ↓ +Astro Static Compiler + ↓ +SEO / Route / Asset / Security Gates + ↓ +Immutable Release + ↓ +Nginx/SSH 或 OSS/CDN Deploy Adapter + ↓ +Production HTTP Smoke Test +``` + +### 9.3 四个冻结发布输入 + +每次发布必须绑定: + +1. 内容快照。 +2. 路由与 SEO 快照。 +3. 媒体 Manifest。 +4. 主题与站点配置版本。 + +构建过程中不得读取变化中的在线业务数据,也不得静默使用 Seed。 + +--- + +## 10. 改造路线图 + +以下周期按“单开发者 + AI 辅助、复用现有代码、需求不大幅变化”估算,只用于排序,不作为固定交付承诺。 + +### 阶段 A:证据基线与紧急保护(约 1 周) + +任务: + +1. 固定源码 Commit、Node、pnpm、数据库和依赖版本。 +2. 建立干净开发环境并执行现有 lint/typecheck/unit/e2e/build。 +3. 输出失败测试和真实能力基线。 +4. 完成 PostgreSQL、媒体、WXR、Artifact 全量备份。 +5. 在隔离环境完成一次恢复演练。 +6. 删除前端默认凭据和后端默认 Secret。 +7. 收紧 CORS,并暂时限制后台访问来源。 + +完成标准: + +- 可从空环境恢复并运行。 +- 测试结果可审计。 +- 不再携带默认生产凭据。 + +### 阶段 B:安全和数据一致性(约 2–3 周) + +任务: + +1. 平台级单 `super_admin`。 +2. 会话过期、撤销、MFA、恢复码和登录限流。 +3. 全接口 `site_id` 审计和隔离测试。 +4. SSRF 防护、下载预算和受限出口。 +5. SVG、MIME、图片和 HTML 安全处理。 +6. 媒体软删除和引用检查。 +7. 禁止迁移自动发布。 + +完成标准: + +- 安全测试通过。 +- 后台具备最小公网安全条件;否则继续只允许内网/VPN。 +- 所有跨站读写测试通过。 + +### 阶段 C:冻结快照与正式 Release(约 2–4 周) + +任务: + +1. 建立 `build_jobs`、`build_input_snapshots`、`releases`、`artifacts`、`publish_locks`。 +2. 移除生产构建 Seed fallback。 +3. 建立 Worker 和持久化 Job 状态。 +4. 生成 Build/Route/Asset/Validation Manifest 和 Checksums。 +5. 实现版本目录和真正原子切换。 +6. 实现不删除历史版本的回滚。 +7. 增加预览 Release、访问控制和 `noindex`。 + +完成标准: + +- 相同快照可重复构建。 +- API 中断不会生成错误成功产物。 +- 服务重启后 Job 状态可恢复。 +- 完成生产等价环境回滚演练。 + +### 阶段 D:URL、迁移和 SEO 闭环(约 2–4 周) + +任务: + +1. 建立 `source_snapshots`、`import_batches`、`import_items`。 +2. 建立 `route_registry` 和路由编译器。 +3. 完成 Sitemap + HTML 爬虫;Playwright 用于 JS/异常页面补扫。 +4. 实现增量分类、冲突队列和人工覆盖保护。 +5. 旧 HTML、导入 SEO、新预览 HTML 三方差异。 +6. P0/P1 SEO 门禁、Redirect 环/链和 HTTP 检查。 +7. 处理旧媒体 URL 和普通页面映射。 + +完成标准: + +- 旧 URL 基线可审计。 +- 所有 URL 有明确处置状态。 +- P0/P1 差异为零或有正式豁免。 +- 最终增量不会覆盖人工修改。 + +### 阶段 E:主题和组件平台化(约 3–5 周) + +任务: + +1. 把当前 Astro 页面抽成第一套正式主题。 +2. 建立 Theme Manifest、Block Manifest、Slot 和 Renderer。 +3. 打通后台 Token 到静态运行时。 +4. 建立 Schema Form Renderer。 +5. 清理后台演示页、注册/找回密码和多角色代码。 +6. 实现第二套视觉差异明显的主题。 + +完成标准: + +- 两套主题使用同一内容、SEO、媒体和交互逻辑。 +- 无需复制整套页面代码即可新建差异化网站。 +- 主题版本升级可迁移、可回退。 + +### 阶段 F:部署与正式试点(约 1–3 周) + +任务: + +1. 根据目标环境选择 Nginx/SSH 或 OSS/CDN Adapter。 +2. 凭据进入 Secret 管理,只保存引用。 +3. 上传不可变版本并校验文件数量、大小和 Hash。 +4. 临时入口真实 HTTP 验收。 +5. 获取发布锁后原子切换。 +6. 生产冒烟、监控、告警和回滚。 +7. 切站前最终增量和 DNS/CDN 计划。 + +完成标准: + +- 完成一次真实发布和一次回滚演练。 +- 旧路径、SEO、表单和关键媒体通过生产 HTTP 验收。 +- 恢复和告警演练通过。 + +--- + +## 11. 第一试点上线阻断门槛 + +以下任一条件不满足,不允许正式切站: + +### 安全 + +- 默认账号、密码和 Secret 已清除。 +- MFA、会话撤销和登录限流有效,或后台完全位于受控私网且有书面临时豁免。 +- SSRF、SVG/MIME 和富文本安全测试通过。 +- CORS、CSRF、CSP 和必要安全响应头正确。 +- 部署和数据源凭据未进入源码、日志或产物。 + +### 数据 + +- 完成切站前最终增量。 +- 导入结果、冲突和失败条目全部可审计。 +- 备份成功且已完成恢复演练。 +- 媒体引用完整,没有未处理关键资源。 + +### URL 与 SEO + +- 旧 URL 基线来源、数量和扫描时间明确。 +- 每条旧 URL 已标记保留、301、410 或批准例外。 +- 无 Redirect 环,重要路径无多跳。 +- P0/P1 SEO 差异清零或有签字豁免。 +- Canonical、hreflang、robots、Sitemap 和结构化数据通过。 + +### 构建与发布 + +- 构建输入已冻结并有 Hash。 +- Release 和产物不可变。 +- 发布切换原子且持久化。 +- 发布锁和旧任务防覆盖有效。 +- 临时入口和生产入口均完成 HTTP 冒烟。 +- 回滚不重新构建,且已演练成功。 + +### 动态功能 + +- 表单具备限流、反垃圾和隐私记录。 +- 通知失败可重试并可观察。 +- Lead 站点隔离测试通过。 + +--- + +## 12. 风险登记 + +| 风险 | 概率 | 影响 | 等级 | 处置 | +|---|---:|---:|---:|---| +| Seed 数据被误发布 | 中 | 极高 | P0 | 冻结快照、失败即中止 | +| 非原子替换导致站点中断 | 中 | 极高 | P0 | 版本目录和原子指针切换 | +| Token/默认凭据泄露 | 中 | 极高 | P0 | 新会话体系、清默认值、MFA | +| SSRF 访问内网或元数据 | 中 | 极高 | P0 | DNS/IP/重定向校验和受限出口 | +| 跨站数据读写 | 中 | 高 | P0 | Repository 强制 siteId、RLS、隔离测试 | +| 迁移重跑覆盖人工内容 | 高 | 高 | P0 | 冲突队列和人工覆盖保护 | +| 普通页面跳首页造成 Soft 404 | 高 | 高 | P0 | route_registry、人工处理 | +| 无备份导致迁移成果丢失 | 中 | 极高 | P0 | 第二存储和恢复演练 | +| SVG/富文本持久化 XSS | 中 | 高 | P0 | 白名单净化、CSP | +| Build 进程重启后状态丢失 | 高 | 中高 | P1 | 持久化 Job 和 Worker | +| 主题抽象过度拖慢首站 | 中 | 中 | P1 | 先从已有站抽第一主题,再用第二主题验证协议 | +| WXR 正则解析遇到边界文件 | 中 | 中高 | P1 | 流式解析、异常夹具、资源限制 | +| 依赖或许可证不适用 | 低中 | 高 | P1 | SBOM、许可证和漏洞扫描 | +| 多语言硬编码造成数据误归类 | 中 | 中 | P1 | Locale 配置化,拒绝未知 Locale | +| 第三方 WAF 导致迁移不完整 | 高 | 中高 | P1 | WXR/SQL/uploads 备用通道、失败清单 | + +--- + +## 13. 单人 + AI 模式下的合理取舍 + +可以简化: + +- 只保留一个 `super_admin` 权限模型。 +- V1 只做一个目标部署适配器。 +- V1 按站全量构建,不做复杂增量构建。 +- Playwright 作为异常页面和 JS 页补扫,不必替代普通 HTML 爬虫。 +- 第一阶段不建设 ClickHouse、客户画像和复杂增长分析。 +- 不做 SaaS 计费和复杂审批。 + +不能因为单人运营而省略: + +- 数据备份和恢复演练。 +- 认证过期、撤销和公网 MFA。 +- 站点隔离。 +- SSRF、SVG和富文本安全。 +- URL 基线和旧路径覆盖率。 +- 构建输入冻结。 +- 持久化 Build/Release 记录。 +- 最小发布锁和旧任务防覆盖。 +- 真正可逆的回滚。 +- 生产 HTTP 验收。 + +BullMQ、容器沙箱等具体实现可以分阶段,但它们承载的可靠性和安全目标不能被取消。 + +--- + +## 14. 文档治理建议 + +### 14.1 当前权威关系 + +建议明确: + +1. `SiteForge_完整项目计划方案_V3.0.md`:产品和总体架构唯一基线。 +2. `SiteForge_项目实施计划_V1.0.md`:目标实施节奏,后续需要结合本报告重新校准。 +3. 本报告:旧 cms 代码现状、差距和改造优先级依据。 +4. `SiteForge_现有CMS项目复用评估_V1.0.md`:复用边界参考。 +5. 旧 cms 内部文档:历史设计和经验输入,不具有当前项目最高权威。 + +### 14.2 需要修正的旧文档表述 + +- 不再使用“已经原子发布”,改为“本地候选构建、门禁和非原子目录替换”。 +- 不再使用“站点隔离已全部修复”,改为“主要路径已有隔离基础,仍需全量审计”。 +- 不再把 ERD 里的 45 张表描述为已实现。 +- 不再把 Build Worker/Event Gateway 空壳计入完成能力。 +- 不再把单文件 sourceUrl 上传描述为完整 ZIP uploads 导入。 +- 不再把修订历史描述为内容回滚。 +- 区分本地真实数据验证与生产发布验证。 + +### 14.3 每次评估必须记录 + +- Git Commit SHA。 +- 数据库迁移版本。 +- Node/pnpm 和容器版本。 +- 测试命令、结果、时间和环境。 +- 使用的脱敏数据集版本。 +- 已知失败和豁免。 +- 生产验证证据。 + +--- + +## 15. 建议立即执行的首周任务 + +### 第 1–2 天:建立可信基线 + +1. 创建干净代码分支或新 SiteForge 仓库基线。 +2. 排除数据、缓存、构建产物和 Secret。 +3. 安装冻结依赖并执行 typecheck、unit、contract、e2e、build。 +4. 形成实际失败清单,不以旧测试报告代替当前结果。 + +### 第 2–3 天:保护现有成果 + +1. 备份 PostgreSQL、media、WXR、Artifact 和配置。 +2. 校验备份 Hash。 +3. 在独立目录/实例完成恢复演练。 + +### 第 3–4 天:封堵最直接安全问题 + +1. 删除登录页默认账号密码。 +2. 默认 Secret 改为缺失即拒绝启动。 +3. CORS 改为明确后台来源。 +4. 修复 Lead 更新和修订读取的 siteId 条件。 +5. 暂停 SVG 上传或加入净化。 +6. 为采集 URL 增加基础 SSRF 拒绝规则。 + +### 第 4–5 天:阻止错误发布 + +1. 生产构建禁止 Seed fallback。 +2. 迁移不再自动发布,只创建草稿。 +3. 普通页面不再自动 Redirect 到首页。 +4. 为 Build/Release/Route/Import 核心表编写第一版迁移。 +5. 确定第一试点部署方式:Nginx/SSH 或 OSS/CDN。 + +首周完成后再开始部署器开发;在此之前,不建议把当前后台和 API 直接暴露公网。 + +--- + +## 16. 最终判断 + +### 16.1 是否值得继续使用 cms + +值得。旧项目已积累了大量可复用实现和真实迁移经验,尤其是: + +- WordPress REST/WXR。 +- 媒体抓取和去重。 +- 内容修订。 +- Astro 页面与组件。 +- SEO 基础输出和 Gate。 +- 管理后台工程壳。 +- 迁移与隔离测试。 + +这些资产可以明显降低 SiteForge 的初始研发成本。 + +### 16.2 是否可以直接上线 + +不可以。当前只适合视为内部原型和代码底座。认证、隔离、采集安全、构建输入、发布一致性、路由、备份和监控均存在上线阻塞问题。 + +### 16.3 最合理的总体路线 + +```text +保留旧代码资产 +→ 建立测试和备份基线 +→ 修复 P0 安全与数据一致性 +→ 冻结构建输入 +→ 建立持久化 Release 和原子发布 +→ 建立 URL/SEO/迁移闭环 +→ 落地主题与 Block 协议 +→ 实现一个部署适配器 +→ 完成真实试点发布与回滚 +``` + +### 16.4 项目定位 + +`D:\project\cms` 应被定位为: + +- SiteForge 的实现底座。 +- WordPress 迁移经验库。 +- 测试夹具和兼容规则来源。 + +它不应被定位为: + +- 已完成的生产平台。 +- 当前产品范围的权威文档。 +- 可以整体原样复制上线的系统。 + +SiteForge V3.0 继续作为产品和架构基线;本报告作为从 cms 演进到 SiteForge 的差距与改造依据。 + +--- + +## 附录 A:关键代码证据索引 + +| 结论 | 证据路径 | +|---|---| +| Build 状态仅存内存 | `services/control-api/src/modules/build/build.service.ts` | +| API 进程直接 spawn 构建 | `services/control-api/src/modules/build/build.service.ts` | +| 非原子删除后复制 | `runtimes/astro-site-runtime/scripts/release.mjs` | +| Token 无过期且有默认 Secret | `services/control-api/src/common/token.ts` | +| CORS origin=true、logger=false | `services/control-api/src/main.ts` | +| 迁移后逐条自动发布 | `services/control-api/src/modules/migration/migration.service.ts` | +| Redirect 存 settings JSON | `services/control-api/src/modules/migration/migration.service.ts` | +| 普通页面可能跳 `/en/` | `services/control-api/src/modules/migration/migration.service.ts` | +| Sitemap 仅基础递归 | `services/control-api/src/modules/migration/migration.service.ts` | +| Lead 更新缺 siteId 条件 | `services/control-api/src/modules/lead/lead.service.ts` | +| 修订查询缺 siteId 条件 | `services/control-api/src/modules/content/content.service.ts` | +| SVG 可直接上传与公开返回 | `services/control-api/src/modules/media/media.service.ts` | +| 媒体直接物理删除 | `services/control-api/src/modules/media/media.service.ts` | +| 表单邮件通知仍为 TODO | `services/control-api/src/modules/lead/lead.controller.ts` | +| 内容导入 Locale 硬编码 en/es | `services/control-api/src/modules/content/import.service.ts` | +| API 失败回退 Seed | `runtimes/astro-site-runtime/src/content/*.ts` | +| ZIP UI 未形成真实解包导入 | `apps/admin-web/src/views/site/manage.vue` | +| Build Worker 为空壳 | `services/build-worker` | +| Event Gateway 为空壳 | `services/event-gateway` | + +## 附录 B:进入开发前待确认事项 + +1. 第一试点正式部署目标是 Nginx/SSH 还是 OSS/CDN。 +2. 后台是否必须公网访问;如果不是,先采用 VPN/零信任/IP 白名单。 +3. 旧站能否提供 SQL、uploads、服务器日志和 Search Console 数据。 +4. 第一试点需要支持哪些 WordPress 插件、CPT、短代码和页面构建器。 +5. 需要保留哪些 Locale,URL 是否含语言前缀。 +6. 现有客户数据是否允许复制到开发/测试环境,如何脱敏。 +7. Art Design Pro 和第三方图片、字体、图标的许可证是否满足商用与再分发。 +8. 备份目标、RPO、RTO 和保留期。 +9. 正式域名、DNS、证书、CDN 和缓存控制权归属。 +10. 哪个真实网站作为第一个正式验收试点。 diff --git a/docs/superpowers/specs/2026-10-20-siteforge-vertical-slice-design.md b/docs/superpowers/specs/2026-10-20-siteforge-vertical-slice-design.md new file mode 100644 index 0000000..b3c04a3 --- /dev/null +++ b/docs/superpowers/specs/2026-10-20-siteforge-vertical-slice-design.md @@ -0,0 +1,249 @@ +# SiteForge 最小纵向切片 · 设计文档 + +> 日期:2026-10-20|状态:待评审 +> 上位文档:`SiteForge_完整项目计划方案_V3.0.md`(执行基线) +> 姊妹文档:`cms现状与SiteForge差距分析_V1.0.md`(D:\project\cms 的教训清单) +> 本文决策已经用户逐项确认(建设顺序、切片范围、数据、路线、九项修正)。 + +--- + +## 1. 背景与定位 + +SiteForge 是多站点静态迁移与发布平台(V3.0 定义 17 项必须交付能力)。本切片是整个平台的**第一个里程碑**:用真实试点数据(hesupipe.com 的 WordPress WXR 导出 + 图片包副本)打通最险的核心链路一次: + +```text +WXR 导入 → 统一内容模型 → URL 注册表 → 极简主题 → 静态构建 → 门禁 → 本地预览 +``` + +三条前提约束: + +1. **所有代码是正式资产**:数据模型、契约、目录结构按 V3.0 设计,后续能力在此之上加厚,不推倒重写。 +2. **不改动 D:\project\cms,但白名单资产可移植**(路线 C,2026-10-20 确认):cms 冻结为只读源;试点数据以只读复制方式进入本仓库 `storage/`。**可移植资产(白名单)**:WXR 解析规则与测试夹具(重写到流式 XML 解析器之上)、Astro 页面模板(作为 pilot-minimal 主题起点——其产品 Tabs/相册/表格刚对齐过 hesupipe 老站)、门禁脚本逻辑、docker-compose/CI 配置。**不继承、按 V3.0 重写**:认证、BuildService、release/rollback 脚本、MigrationService 编排(迁移即发布)、settings JSONB 路由、Lead 服务、后台业务页面。 +3. **完整性由清单驱动**:每完成一个阶段对照 17 项能力清单打钩,全绿才是项目完成;本切片覆盖其中 4 项的骨架(WordPress 导入、统一内容与修订、URL 注册表、Astro 静态构建)。 + +**文档权威关系**:`SiteForge_完整项目计划方案_V3.0.md` 是唯一产品与架构基线;`cms现状与SiteForge差距分析_V2.0.md` 是 cms 现状与改造优先级依据(**V1.0 差距分析已作废**);`SiteForge_现有CMS项目复用评估_V1.0.md` 是复用边界参考。 + +## 2. 目标与非目标 + +### 2.1 目标(本切片交付) + +| # | 交付 | 验收口径 | +|---|---|---| +| G1 | WXR 全量导入管道(幂等,导入不发布) | hesupipe 全量导入成功(全部为 draft);显式 `publish` 后转 published;重复导入第二次产生 0 条新修订 | +| G2 | 统一内容模型 | 产品/新闻/页面落库,不可变修订 + externalRef 幂等键 + checksum | +| G3 | URL 注册表与路由策略 | 路径级保真 + 分类/归档/标签处置;URL 对照报告 🔴=0 | +| G4 | 极简主题静态构建 | 全站页面 + sitemap.xml + robots.txt + 媒体旧路径输出 | +| G5 | 门禁 | 死链=0、sitemap 一致、每页 title/canonical/唯一 H1、产物大小写冲突=0 | +| G6 | 本地预览服务器 | 按 route_registry 真实响应(html/301/404),noindex 头 | + +### 2.2 非目标(明确不做,后续阶段做) + +后台管理 UI、部署器(rsync/OSS)、差量同步与冲突队列(本切片只预留 `override` 字段)、SEO 三套数据 diff(P0–P3)、爬虫/Playwright、多语言(en 单语)、表单服务、MFA/认证体系(本地脚本无 HTTP 暴露)、Redis/BullMQ(任务先进程内)。 + +## 3. 技术选型与决策记录 + +| 决策 | 选择 | 理由(ADR 摘要,正式 ADR 实施时落 docs/adr/) | +|---|---|---| +| D1 ORM | Drizzle + PostgreSQL 16 | cms 实战验证;迁移即 SQL 可审查;SQL 控制力强(ADR-001) | +| D2 任务执行 | 进程内 JobRunner,接口抽象 | 切片无长任务并发需求;接口按 job 语义设计,BullMQ 后置替换不死代码(ADR-002) | +| D3 媒体存储 | 本地磁盘 `storage/`,产物保持旧路径 | cms 教训:MinIO 容器起了没人用;对象存储后置(ADR-003) | +| D4 URL 策略 | 路径级保真优先,301 兜底 | V3.0 §6/§7 要求;详见 §5(ADR-004) | +| D5 服务形态 | NestJS 模块化单体 + CLI 脚本复用服务层 | 架构与 V3.0 一致;切片不启动 HTTP 监听,脚本以 standalone app context 调用模块服务 | +| D6 契约范围 | packages/contracts 只含 UniversalRow + 内容/路由 DTO | YAGNI:无队列即无事件目录 | +| D7 WXR 解析 | 流式 XML 解析器(saxes 类)+ 资源限额 | cms 的正则解析在 33MB 级 WXR、CDATA/实体/命名空间边界有风险(V2.0 §5.1);限额:文件大小、节点数、处理时限;恶意 XML 防护(ADR-005) | +| D8 媒体安全底线 | 登记时魔数校验 + SVG 隔离 | 不信扩展名与声明 MIME;SVG 默认不进产物、单列报告(V2.0 P0-5)(ADR-006) | + +运行环境:Node 22 LTS、pnpm workspace、TypeScript strict、vitest。开发机为 Windows(大小写陷阱见 §7 G5)。 + +## 4. 仓库结构(切片实际创建的部分) + +```text +cms-one/ + apps/api/ # NestJS:sites/content/routes/media/import/build/audit 模块 + packages/contracts/ # UniversalRow、内容 DTO、路由 DTO(冻结+契约测试) + packages/adapter-wordpress/ # WXR 解析器 + WP REST 客户端(REST 通道切片内可选) + themes/pilot-minimal/ # 极简 Astro 主题 + scripts/ # CLI:import.ts / build.ts / gate.ts / preview.ts + storage/wxr/ storage/media/ # 试点数据副本(git 忽略) + infra/docker-compose.yml # 仅 PostgreSQL + tests/fixtures/ # WXR/媒体夹具 + docs/ + plans/ # 根目录现有 4 份规划文档移入(实施第一步) + adr/ specs/ superpowers/ + .gitignore # 仓库第一个 commit:node_modules/dist/artifacts/storage//.env/coverage +``` + +不预建空包(cms README 纪律);V3.0 §22.2 的其余包在对应阶段创建。 + +## 5. URL 与路由策略(本切片的核心正确性) + +### 5.1 目标路径规则(按优先级) + +| 旧 URL 形态 | 处置 | route_kind | +|---|---|---| +| 内容页 permalink(含 `.html`/`.php` 后缀、任意目录深度) | **产物按原路径原样输出**(路径级保真,非仅 slug) | html | +| 首页 `/` | 首页 | html | +| `product-category/{slug}`(产品分类) | 生成分类列表页,路径原样 | html | +| `category/{slug}`(文章分类) | 生成文章分类列表页 | html | +| 列表分页 `/page/N/`(含分类下分页) | 列表页分页输出 | html | +| `tag/{slug}`、`product_tag/{slug}`、日期归档、作者页 | 301 → 对应主列表页(/products/ 或 /news/) | redirect | +| 附件/媒体 `wp-content/uploads/...` | 媒体文件按**原路径**进产物 | asset | +| 无法保真的个别内容路径 | 301 → 新路径 | redirect | +| WP `?p=123` 短链 | 记录为已知限制,对照报告单列(不算 🔴,见 §8) | — | + +### 5.2 route_registry(独立表,禁止塞 settings JSONB——cms 教训) + +切片字段子集(V3.0 §6.4):`site_id / original_path / normalized_lookup_key / route_kind / target_content_id / target_file / redirect_location / indexable / source_status / source_snapshot_id`。 + +规范化键规则(仅作查重与对照,原始路径永不改写):percent-decode → Unicode NFC → 小写 → 去尾部斜杠。查重命中仅大小写/尾斜杠差异时**报告冲突**,不静默合并(V3.0 §6.3)。 + +### 5.3 URL 对照报告(门禁输入) + +老 URL 全集 = WXR 可推导 URL(内容 permalink ∪ 术语归档 ∪ 分页推导)∪ 老站 sitemap.xml(若可拉取;被挑战页拦截则记说明)。三色口径与 cms 一致:🟢 产物存在同路径页面|🔵 route_registry 有 redirect|🔴 无去处(必须为 0)。 + +### 5.4 媒体旧路径保持 + +- `media_assets.source_url` 存旧完整 URL,`storage_path` 指向本地副本文件,`public_path` = 旧 URL 路径部分(`/wp-content/uploads/...`)。 +- 构建时媒体复制到产物的 `public_path` 位置;正文 ``、封面、相册引用全部重写为根相对 `public_path`。 +- 未匹配到本地副本的媒体:列入导入报告(引用它的页面数、URL 清单),不阻塞导入;若被已发布页面引用则门禁降级为 🔴 由用户决定补图或改链。 +- 登记时校验文件魔数与声明 MIME 一致,不一致入报告;**SVG 一律隔离**(不复制进产物、预览不可达),报告中单列清单。 + +## 6. 管道命令与数据流 + +### 6.1 `scripts/import.ts`(导入) + +```text +读 storage/wxr/*.xml → adapter-wordpress 解析为 UniversalRow[] +→ 类型映射(post→news_article;product CPT→product;page→basic_page) +→ locale 取站点配置;未知 locale 记错误并跳过该条(禁止静默归 en——cms 实际踩坑) +→ 每条计算 normalized checksum: + 与最新 content_revision.checksum 相同 → skip(不产生新修订) + 不同或不存在 → 写入新 content_revision(kind=draft,不可变,source=import) + ※ 导入不发布:发布是独立显式动作(见 6.2,V2.0 P0-6) +→ 媒体登记:按 WXR attachment 的 source_url 与本地副本文件名匹配; + 全角/编码损坏文件名按规范化通配匹配(cms 踩坑),匹配结果写报告 +→ 生成/更新 route_registry(§5.1 规则)与 301 规则 +→ 未知 WP 字段保留进 data.extras(不丢弃) +→ 输出导入报告:条目数对照、skip/update/create 计数、媒体匹配率、 + URL 冲突清单、行级错误定位 +``` + +幂等键:`(site_id, source_connection_id, source_type, source_id, locale)`,与 externalRef(旧 permalink)双保险。 + +### 6.2 `scripts/publish.ts`(显式发布) + +导入只产生 draft;发布是独立、显式、可审计的动作(V2.0 P0-6:禁止"迁移即发布"): + +- 按批次/类型/条目批量将 draft 修订置为 published(更新 entry_locales.published_revision_id 指针)。 +- 每次发布动作写 audit_logs(actor、对象、前后状态、时间)。 +- 构建只消费 published 修订集合——与 cms「导入后逐条自动发布」的行为刻意相反。 + +### 6.3 `scripts/build.ts`(构建) + +```text +物化 build_input_snapshot: + 内容(published 修订集合)+ 路由清单 + 媒体清单 + 站点配置 + → 冻结为 artifacts//input/ 下带哈希的 JSON 文件 +Astro 构建(themes/pilot-minimal): + 只读输入快照文件,禁止实时查库,禁止任何 seed/演示兜底数据 + (输入不完整 → 构建立即失败;此行为写回归测试) + SITE_URL 取站点配置的生产域名(hesupipe.com)→ canonical/og/sitemap 正确 +产物:HTML 页面 + sitemap.xml(只含 route_kind=html 且 indexable)+ robots.txt + + 媒体(旧路径)+ _redirects / nginx-redirects.conf(从 route_registry 编译,验证路由模型) + + build-manifest.json(输入快照哈希、页面数、checksums) +落 artifacts//,build_jobs 表记录 +``` + +### 6.4 `scripts/gate.ts`(门禁) + +| 检查 | 通过条件 | +|---|---| +| URL 对照(§5.3) | 🔴 = 0 | +| 内部死链 | 产物内 href/src/srcset 指向的内部目标全部存在(html/asset 命中 route_registry) | +| sitemap 一致 | sitemap 条目 ⊆ 实际页面;indexable 页面 ⊆ sitemap | +| 页面 SEO 基线 | 每页有 title、canonical;H1 至多 1 个 | +| 大小写冲突 | 产物相对路径 lowercase 后无重复(Windows 开发盘不敏感、Linux 部署敏感——V3.0 §6.5) | +| 重定向图 | route_registry 的 redirect 关系无环;关键路径多跳(≥3 跳)告警(V2.0 §5.3:🔴=0 不代表无环) | +| 兜底数据回归 | 输入损坏时构建必须失败(负向测试) | + +### 6.5 `scripts/preview.ts`(预览) + +自研 Node 静态服务器(不引入 nginx 依赖): + +- 按 route_registry 响应:html → 伺服产物文件;redirect → 301 + Location;无匹配 → 产物 404 页。 +- 所有响应加 `X-Robots-Tag: noindex`;禁用目录列表。 +- 用途:在本地验证"真实 URL 行为"(V3.0 §7.4 精神),并支撑 §8 的人工抽检。 + +## 7. 数据模型(切片子集,V3.0 §9 对齐) + +| 表 | 关键字段与约束 | +|---|---| +| sites | site_id PK、name、default_locale、production_domain | +| source_connections | 类型=wxr、文件路径 + sha256、adapter 版本 | +| import_jobs / source_records | 批次状态机;源记录存原始条目位置 + checksum + 解析状态 | +| content_entries | (site_id, type_key, external_ref) 唯一;status: draft/published/archived | +| entry_locales | (site_id, locale, slug) 唯一;current/published_revision_id 指针 | +| content_revisions | **不可变**(插入式,禁 UPDATE);data jsonb、checksum、source=import、import_batch_id;预留 `overridden_fields`(下阶段冲突队列用) | +| route_registry | §5.2 字段;独立表 | +| media_assets | (site_id, source_url) 唯一幂等;sha256、public_path(旧路径)、alt、尺寸 | +| build_jobs / artifacts | 构建记录 + 产物目录 + 输入快照哈希 | +| audit_logs | 追加式;actor(切片为 system/importer)、action、对象、前后值 | + +多语言位:模型带 locale,切片只写 en。 + +## 8. 错误处理 + +- **行级容错**:单条解析/映射失败记录行号与原因后继续;整批结构错误(文件损坏、站点不存在)才中断。 +- **未知字段**:一律进 `data.extras` 保留,报告中汇总清单。 +- **构建 fail-fast**:输入快照不完整(内容缺失、路由空、媒体引用悬空)立即失败,无任何降级/兜底路径。 +- **已知限制**:`?p=` 短链、WXR 外的老站 URL(日志/GSC 来源)不在本切片对照范围,报告中单列"未覆盖来源"节——不算 🔴,进入下阶段 SEO diff。 +- **重跑语义**:无变化 skip / 有变化新修订 / 人工改动保护(override 标记)下阶段实现,本切片在修订上预留字段。 + +## 9. 测试策略(vitest) + +| 层 | 内容 | +|---|---| +| 单元:WXR 解析 | 夹具必须覆盖:`_thumbnail_id`、`_product_image_gallery`、`wppop_sections`(PHP serialize 的 Tab 数据)、Yoast `_yoast_wpseo_title/metadesc`、全角/编码损坏文件名、分页与术语 URL 推导、`.html` 后缀 permalink(全部来自 cms 实际踩坑清单) | +| 单元:路由规则 | §5.1 每行规则一个用例;大小写/尾斜杠冲突报告 | +| 单元:解析器限额 | 超大/畸形 XML(节点数、大小、时限超限)→ 明确失败不崩溃;CDATA、实体、命名空间边界夹具 | +| 单元:媒体安全 | 魔数与扩展名不符 → 报告;SVG → 进隔离清单 | +| 单元:重定向图 | 环 → 🔴;多跳 → 告警 | +| 集成:导入 | 真实 WXR 小切片夹具 → 落库 → 断言修订/checksum/幂等(第二次 0 新修订) | +| 集成:构建 | 快照物化 → Astro 构建 → 产物结构断言(sitemap/robots/媒体旧路径/_redirects) | +| 负向 | 输入损坏 → 构建失败(兜底禁令);route_registry 缺目标 → 门禁 🔴 | +| 契约 | UniversalRow/DTO 字段冻结(packages/contracts) | +| 验收 | §2.1 G1–G6 全部可执行复验(真实 hesupipe 数据 + 抽检 20 个 URL:10 内容页 + 5 分类页 + 3 redirect + 2 404) | + +## 10. 实施注意(从 cms 教训直接落地的防线) + +0. **动工第零步**:手动备份 cms 数据(pg_dump + storage/ 拷贝至第二存储,约半小时——V2.0 阶段 A 要求)。 +1. `.gitignore` 是仓库第一个 commit(storage/、artifacts/、node_modules、.env)。 +2. 构建输入快照先于一切(seed 兜底事故的根治)。 +3. redirects 走独立表(不进 settings JSONB)。 +4. WXR 原件 + sha256 留档 source_connections。 +5. 未知字段不丢弃(extras)。 +6. 门禁 🔴=0 才算过。 +7. Windows 长路径:副本拷贝与构建脚本启用长路径处理(全角文件名目录)。 + +## 11. 验收标准(切片完成的定义) + +> 口径采用 V2.0 §2.2 成熟度分级:本切片验收 = **L3(真实数据本地验证)**;L4(生产部署、HTTP 验收、回滚演练)属后续部署阶段。 + +1. `import` 两连跑:第一次全量入库为 draft(条目数与 WXR 基数对照一致),`publish` 后转 published,第二次 import 0 新修订。 +2. `build` 产出全站产物,`gate` 七项全绿。 +3. `preview` 启动后按 §9 抽检 20 URL 行为正确(含 301 跳转与 404)。 +4. `pnpm test` 全绿(含负向与契约)。 +5. 导入报告与 URL 对照报告可读、可复查(含媒体匹配率与未覆盖来源说明)。 + +## 12. 切片之后的路(指引后续子项目,不在本切片内) + +```text +SP0' 后台 UI(Art Design Pro + 认证/MFA) +SP1' 差量同步与冲突队列(override 字段启用) +SP2' SEO 三套数据 diff(P0–P3)+ 爬虫扩充 URL 全集 +SP3' 主题/板块协议(Block Schema/模板约束/第二主题) +SP4' 部署器(rsync/SSH → OSS/CDN)+ 发布锁/回滚 +SP5' 表单服务 + 备份监控 +``` + +每阶段对照 `cms现状与SiteForge差距分析_V1.0.md` 的 17 项清单打钩。