diff --git a/SITEFORGE_V7_2_IMPLEMENTATION_PLAN.md b/SITEFORGE_V7_2_IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..84cdd57 --- /dev/null +++ b/SITEFORGE_V7_2_IMPLEMENTATION_PLAN.md @@ -0,0 +1,250 @@ +# SiteForge Factory V7.2 项目差距审计与下一步实施计划 + +> 审计对象:`C:\Users\30997\Downloads\SiteForge_Factory_V5_Web_Docker\SiteForge_Factory_V7_2` +> 审计日期:2026-10-22 +> 目标:把当前“可控试点版”推进为需求文档所描述的可迁移、可搭建、可发布、可运维的网站工厂。 + +## 1. 执行结论 + +当前项目已经形成可运行的产品骨架,具备:站点管理、内容模型、区块编辑器、主题安装与版本固定、静态构建、构建队列、基础质量检查、备份接口、团队角色、审计记录、PostgreSQL/Redis 部署骨架和 HTTPS/HMAC 远程发布代理。 + +但它还不能被定义为“完整需求已实现”或“生产就绪”。更准确的定位是: + +- 单机/小团队、受控数据量下可演示和试点; +- 主要快乐路径已有自动化测试; +- 真实迁移、批量数据、跨平台恢复、多语言、企业身份、生产可观测性仍不完整; +- PostgreSQL、远程发布和备份链路目前属于“有骨架,尚未完成生产证明”。 + +建议不要继续堆叠零散页面或按钮,而是先关闭平台正确性,再按“迁移闭环 → 数据工厂 → 编辑/模板 → 发布/多语言 → 生产治理”推进。 + +## 2. 本次验证事实 + +### 2.1 自动化与静态验证 + +- Python 测试共发现 86 项。 +- Windows 默认编码环境:80 通过、6 失败。 +- `PYTHONUTF8=1` 环境:85 通过、1 失败。 +- 5 项失败来自测试使用 `Path.read_text()` 却未显式指定 UTF-8,属于跨平台测试可靠性问题。 +- 剩余 1 项是真实缺陷:SQLite 在线备份后临时数据库文件句柄在 Windows 未及时释放,`TemporaryDirectory` 清理时报 `WinError 32`。 +- 39 个 Python 文件通过 AST 解析。 +- 7 个 JavaScript 文件通过语法检查。 +- 默认、Enterprise、Release Agent 三套 Compose 配置解析通过。 + +### 2.2 尚未完成的环境验证 + +以下项目不能用“Compose 配置能解析”替代,仍需在真实 Docker Engine/目标服务器验证: + +- 镜像完整构建及冷启动; +- Web/Worker 心跳、异常重启和任务续租; +- PostgreSQL + Redis 全量测试; +- 浏览器端端到端、响应式、可访问性和视觉回归; +- 备份恢复演练; +- Release Agent 的 TLS、真实传输、切换、回滚和发布后探测。 + +## 3. 需求覆盖矩阵 + +| 能力域 | 当前状态 | 主要缺口 | 结论 | +|---|---|---|---| +| 站点/内容基础 | 已有 | 站点环境、默认语言、发布策略、蓝图不是一等模型 | 部分完成 | +| 迁移工厂 | 有 WXR、WordPress REST、CSV/JSON/XLSX、有限抓取 | 无持久化迁移会话、断点续传、媒体盘点、冲突队列、回滚和真实大型样本证明 | 试点级 | +| 数据工厂 | 有映射、dry-run、提交 | 无通用 XML、认证 API、只读 MySQL、分批暂存、可逆导入、人工覆盖保护、5 万行证明 | 明显缺失 | +| 内容模型 | 基础字段可用 | 缺 enum/relation/array/media、唯一性、索引、跨字段校验、完整工作流 | 部分完成 | +| 页面编辑器 | 12 类区块、嵌套布局、响应式属性、撤销/重做、复用组件 | 缺审批/锁定/冲突合并、更多业务区块、视觉回归、完整无障碍保证 | 部分完成 | +| 主题/模板 | 主题包、版本固定、兼容检查、预览 | “模板”仍主要是主题+首页预设,不是可复用多页面站点蓝图;升级差异/回滚验证不足 | 部分完成 | +| 构建系统 | 静态构建、版本目录、质量报告 | 构建读取实时数据库而非冻结快照;无内容哈希、依赖图、增量构建和产物保留策略 | 高风险缺口 | +| 作业系统 | 幂等、租约、取消、重试、容量限制 | 仅正式支持 build;无统一进度、死信、诊断日志;未覆盖迁移/导入/媒体/发布 | 部分完成 | +| 发布系统 | 本地发布、HMAC Release Agent、版本切换/回滚 | 缺完整 TLS 部署证明、重放防护、发布后外部探测、CDN 清理、SFTP/S3/Git 等目标 | 试点级 | +| 多语言 | 文档有设计 | 无 locale、翻译组、canonical/hreflang、多语言 sitemap 全链路实现 | 未实现 | +| PostgreSQL/Redis | 有兼容桥和 Compose | DDL 迁移不完整;全局 advisory lock 串行化;无连接池/按站点锁;Redis 仅唤醒 | 非生产级 | +| 安全/权限 | 登录、CSRF、Origin 检查、角色、审计 | 缺 CSP/Permissions-Policy/TrustedHost;代理信任过宽;无 OIDC/MFA/会话撤销/密钥生命周期 | 部分完成 | +| 备份恢复 | SQLite 在线备份和部分目录打包 | Windows 句柄缺陷;遗漏主题包/发布数据等;无统一清单、校验和、外部副本与定期恢复证明 | 阻断生产 | +| 可观测性 | Request ID、基础日志、健康接口 | 无 metrics/tracing/告警/SLO/作业看板 | 未完成 | +| 供应链/CI | Python/JS/Compose/PG 基础 CI | 锁文件无哈希;无依赖审计、镜像扫描、SBOM、签名;CI 允许 commit=`unknown` | 不完整 | +| 商业验收 | 有 readiness/report 概念 | 架构要求的四类真实试点没有签字验收证据 | 未闭环 | + +## 4. 当前必须先修的缺陷 + +### P0:发布阻断 + +1. **修复 Windows SQLite 备份句柄泄漏** + 显式关闭在线备份使用的源/目标连接,再退出临时目录;增加 Windows 与 Linux 的备份→恢复→内容/媒体校验测试。 + +2. **统一 UTF-8 测试和文件协议** + 所有文本读写显式 `encoding="utf-8"`;CI 增加 Windows runner,避免用 `PYTHONUTF8=1` 掩盖代码问题。 + +3. **让版本证据真实可信** + CI 构建必须注入真实 Git SHA;健康检查拒绝 `unknown`;镜像 OCI revision、API commit、部署清单三者必须一致。 + +4. **建立一次真实容器验收** + 默认 SQLite 和 Enterprise PostgreSQL 两种拓扑都执行冷启动、建站、导入、编辑、构建、预览、发布、备份恢复。 + +5. **补安全基线** + 增加 CSP、Permissions-Policy、TrustedHost;把受信代理网段做成显式配置,避免无条件 `forwarded-allow-ips=*`;核对 Cookie、上传、登录限速和错误回显。 + +6. **同步文档与事实** + README 当前测试数量与实际 86 项不一致;V6 运维文档的版本返回示例也需要更新。所有“已完成”声明都必须绑定自动化或验收报告。 + +### P1:平台正确性 + +1. 把所有历史 `CREATE TABLE IF NOT EXISTS` 收敛到有序、校验和固定、可回滚/可恢复的 schema migration;SQLite 和 PostgreSQL 使用同一版本账本。 +2. PostgreSQL 从 SQL 翻译桥升级为明确支持的持久层:连接池、事务语义、唯一约束错误、按站点 advisory lock、并发测试。 +3. 作业模型推广到 `build/import/crawl/media/publish/migration`,增加进度、阶段、结构化日志、死信、重放和保留清理。 +4. 每个构建先生成不可变输入快照:`site_blueprint + theme@version + content_snapshot + asset_manifest + route_registry + seo_policy`;Worker 只读取快照。 +5. 为构建输入、产物和报告记录 SHA-256,保证相同输入可复现,并能证明审批后内容没有漂移。 +6. 扩大备份范围到数据库、media、theme_packages、构建/发布元数据、配置引用;生成 manifest 和校验和;备份自动复制到独立存储。 +7. 为 secrets 增加版本、轮换、撤销和使用审计;环境变量/文件引用保留为开发模式,生产对接 Secret Manager/Vault 类接口。 + +## 5. 分阶段实施路线图 + +### M0 — V7.2.1 稳定基线(3–5 人日) + +交付: + +- 关闭上述 P0 缺陷; +- Windows/Linux、Python 3.12/3.13 全绿; +- 两套 Compose 最小端到端 smoke; +- 一份可重复执行的备份恢复报告; +- CI 中真实 SHA、镜像摘要和版本清单可追踪。 + +退出门槛:86/86 测试通过;不依赖环境编码;备份恢复后数据库记录、媒体哈希和构建记录一致;health commit 不为 `unknown`。 + +### M1 — 平台内核完成(7–12 人日) + +交付: + +- 全量 schema migration; +- 不可变构建快照及内容哈希; +- 通用作业状态机与结构化任务日志; +- 产物/日志/失败任务保留策略; +- PostgreSQL 并发和事务测试; +- metrics、基础告警和运维面板。 + +退出门槛:排队后修改内容不会改变已提交构建;Worker 崩溃后任务可续租或明确进入死信;两个站点并发构建不会被单一全局锁无谓串行。 + +### M2 — 迁移工厂闭环(8–12 人日) + +交付: + +- `migration_sessions` 持久化状态机; +- 探测→抓取→解析→路由/模板识别→媒体盘点→映射→预览→提交→对比报告; +- WordPress REST/WXR、Sitemap、受控 crawl 统一为可恢复任务; +- 冲突/警告队列、人工确认、断点续传; +- 旧 URL→新 URL、SEO 字段、媒体、页面数量对账。 + +退出门槛:用一份获得授权的真实 WordPress 网站完成两次可重复迁移;中途杀死 Worker 后可续传;报告能解释所有缺失、冲突和重定向。 + +### M3 — 数据工厂闭环(10–15 人日) + +交付: + +- CSV/JSON/XLSX/XML、认证 HTTP API、只读 MySQL 连接器; +- 数据源 profile 与加密 secret reference; +- 分页/游标、限速、超时、重试、断点续传; +- staging rows、字段映射、验证、去重、错误下载; +- import batch、原始来源标识、人工覆盖优先级、可逆提交。 + +退出门槛:5,000 行交互验收和 50,000 行压力验收;故障注入后无半提交;回滚只撤销本批变更,不覆盖后续人工编辑。 + +### M4 — 编辑器、内容模型与站点模板(10–15 人日) + +交付: + +- locale/environment/publish policy/site blueprint 成为一等模型; +- 内容字段增加 enum、relation、array、media、唯一性、搜索/筛选和跨字段校验; +- draft→review→published→archived 工作流和审批审计; +- carousel/video/tabs/pricing/form-link/map/timeline/testimonials/team 等高频区块; +- 多页面站点模板,实例化时不复制私有业务内容; +- 主题升级差异预览、兼容检查和一键回滚。 + +退出门槛:从模板新建站点后能独立升级内容;键盘操作、焦点、语义、对比度和三档响应式视觉回归通过;多人编辑冲突不会静默覆盖。 + +### M5 — 发布与多语言(12–20 人日) + +交付: + +- 先加固现有 Release Agent:TLS、nonce/replay cache、最小权限、审计、外部健康探测、失败自动回滚; +- 再按业务优先级增加 SFTP、S3/CDN 或 Git CI 目标,不同时铺开所有连接器; +- `site_locales`、translation groups、locale route registry; +- canonical、双向 hreflang、多语言 sitemap 和语言切换; +- 灰度/预发布、缓存失效、发布后链接抽检。 + +退出门槛:一次失败发布可自动回到上个健康版本;重复签名请求不能重放;双语言站点不存在孤立翻译或错误 hreflang。 + +### M6 — 生产与企业治理(15–30 人日) + +交付: + +- OIDC/SSO、可选 MFA、会话撤销、权限回归测试; +- 审计日志外送/不可变保留; +- Prometheus/OpenTelemetry 或等价指标与追踪、SLO 和告警手册; +- 依赖审计、镜像扫描、SBOM、镜像签名和许可证清单; +- 容量、峰值、混沌、灾备演练; +- RPO/RTO 与保留策略经业务签字。 + +退出门槛:达到约定 SLO;恢复演练达到 RPO/RTO;高危漏洞为零或有经批准的限时豁免;值班人员仅凭 Runbook 能完成恢复。 + +## 6. 推荐的下一迭代(两周) + +两周内只做一条平台纵切,不开启大规模 UI 扩展: + +### 第 1 周 + +1. 修复备份句柄和 5 个 UTF-8 测试。 +2. CI 增加 Windows,校正测试计数,注入并校验真实 SHA。 +3. 增加安全响应头、TrustedHost 和可信代理配置。 +4. 建立 SQLite/PG 两套 Docker smoke 脚本。 +5. 定义 build snapshot、job event、artifact manifest 三个数据契约。 + +### 第 2 周 + +1. 实现不可变 build snapshot,改 Worker 只消费 snapshot id。 +2. 给作业增加 progress/stage/events/dead-letter。 +3. 迁移第一批遗留表到 schema registry,并验证空库升级和旧库升级。 +4. 完成备份 manifest、SHA-256 校验和独立恢复命令。 +5. 在 CI 执行一次“建站→构建→备份→清空测试部署→恢复→重新构建”的闭环。 + +迭代结束演示必须证明:提交构建后再修改页面,原任务仍生成提交时版本;Worker 被终止后任务不会丢;备份能在空白环境恢复;所有测试跨平台通过。 + +## 7. 架构优化原则 + +1. **数据库是业务事实源,队列不是。** Redis 只做通知;任务状态、幂等键和租约落数据库。 +2. **构建输入必须不可变。** 审批、构建、发布都引用 snapshot/hash,不读取“现在的站点”。 +3. **外部输入先暂存再提交。** 爬取、API、数据库和文件导入必须进入 staging,校验/映射/人工确认后再原子提交。 +4. **路由是一等数据。** 使用 route registry 管理 locale、来源、行为和冲突,不从标题临时推断最终 URL。 +5. **人工编辑优先级显式化。** 每个字段记录 source、source key、同步时间和 manual override,增量同步不得静默覆盖。 +6. **大任务统一进入作业系统。** 请求线程只创建任务;迁移、抓取、媒体处理、构建、发布都可恢复、可观测、可取消。 +7. **每个“完成”都有证据。** 单元测试证明代码分支,E2E 证明用户流程,恢复演练证明可恢复,试点签字证明商业可用。 + +## 8. 四个最终业务验收场景 + +项目不能仅以“测试全绿”宣告完整,还需完成架构文档要求的四类试点: + +1. **A:WordPress 汽车网站迁移** — 页面、文章、产品、媒体、SEO 和重定向全量对账。 +2. **B:工业企业新站搭建** — 从模板到内容录入、响应式编辑、构建、预发布和正式发布。 +3. **C:增量数据更新** — 再次同步时更新源数据,但保留人工修改并提供冲突报告。 +4. **D:模板复用** — 从已验收站点提炼多页面模板,新建站点不携带客户私有内容。 + +每个试点必须保存:输入清单、映射版本、构建 snapshot/hash、质量报告、发布记录、回滚记录、遗留问题和业务负责人签字。 + +## 9. 预计投入与排期建议 + +- M0–M1:10–17 人日,先串行完成,建立稳定地基。 +- M2–M5:40–62 人日,可由两条工作流并行,但共享 schema/job/snapshot 契约。 +- M6:15–30 人日,需结合真实部署和企业要求。 +- 总计:65–109 人日;若由 2 名熟悉 Python/FastAPI、前端和 Docker 的工程师执行,合理日历周期约 9–14 周,另加真实试点反馈时间。 + +估算不包含大规模视觉设计、客户数据清洗、第三方服务采购和等保/渗透测试认证。若首个商业目标只需要 WordPress 迁移 + 静态发布,应把 SFTP/S3、多语言、SSO 分阶段开启,避免范围同时膨胀。 + +## 10. “完整项目”定义(Definition of Done) + +只有同时满足以下条件,才能将版本标记为完整: + +- 需求覆盖矩阵无未解释的缺口,所有延期项有明确版本和责任人; +- Windows/Linux 支持矩阵全绿,真实浏览器 E2E 和可访问性门禁通过; +- SQLite 和 PostgreSQL 的升级、备份、恢复、并发和故障测试通过; +- 迁移/导入/构建/发布均可中断恢复、审计和回滚; +- 构建产物可由不可变输入重现,发布可追踪到 commit、snapshot、theme 和 artifact hash; +- 四个业务试点完成并签字; +- 安全、供应链、监控、告警、Runbook、RPO/RTO 均有证据; +- 文档内容与当前代码、版本、测试数量和部署方式一致。 + diff --git a/apps/api/src/modules/build/pipeline.ts b/apps/api/src/modules/build/pipeline.ts index 847dabf..1c0b777 100644 --- a/apps/api/src/modules/build/pipeline.ts +++ b/apps/api/src/modules/build/pipeline.ts @@ -137,7 +137,10 @@ function killProcessTree(child: ChildProcess): void { } if (process.platform === 'win32') { // taskkill.exe(System32,PATH 内 .exe 无需 shell);/T 递归子树 /F 强杀 - spawn('taskkill', ['/pid', String(pid), '/T', '/F'], { stdio: 'ignore' }) + // taskkill 启动失败(概率≈0)时回退单杀——不让未处理 error 事件崩宿主 + spawn('taskkill', ['/pid', String(pid), '/T', '/F'], { stdio: 'ignore' }).on('error', () => { + child.kill('SIGKILL') + }) } else { try { process.kill(-pid, 'SIGKILL') diff --git a/docs/superpowers/plans/2026-10-21-slice-build-preview-phase4.md b/docs/superpowers/plans/2026-10-21-slice-build-preview-phase4.md index b288982..16d1f40 100644 --- a/docs/superpowers/plans/2026-10-21-slice-build-preview-phase4.md +++ b/docs/superpowers/plans/2026-10-21-slice-build-preview-phase4.md @@ -86,6 +86,7 @@ scripts/sf.ts # + content:publish / build:create / preview:star - [ ] 失败测试(夹具产物注入错误逐项触发):① 内部死链:dist 内 a[href]/img[src] 内部目标全命中(页面或 assets)——注入坏链 → fail;② sitemap 一致:sitemap 条目=实际 indexable html 集;③ SEO 基线:每 html 有 title/meta description/canonical(指向 origin+自身路径)/恰一 H1;④ 大小写冲突:dist 路径 lowercase 无重复;⑤ 产物完整性:route-manifest 的 target_file 全存在。全过 → validation_runs 行 PASS - [ ] 实现:门禁引擎(纯函数读 dist+manifests → issues 按 P0/P2 分级——P0 阻断 P2 报告;**HTML 解析用 parser 复用清洗管线,禁纯正则** spec §13.4);build 状态机补 validating→succeeded/failed;**报告落盘 HTML 先写**(Plan 3 窄窗口顺手修) +- [ ] **Task 5 审查移交**:① 测试套件 spawn 缩减——build-snapshot 7 处成功路径改 materializeRenderSnapshot 直调或复用单次 job(spawn 降到 1-2,五禁覆盖留 build-pipeline);Task 8 开工前完成 ② CLI 与测试**禁止同时构建**(themeDistDir 结构性共享暂存)③ Task 8 时间预算:全链分钟级(astro 5.3s+媒体 IO+门禁+1746 回环+Playwright),300s spawn 超时余量充足 - [ ] 绿 → commit `feat(build): 最小门禁与状态机闭环` ### Task 7: Preview Server