upgrade: adopt V8.12.0-dev.1 (V8.11 unified professional UI + V8.12 workflow usability)

- Overlay 26 changed files from SiteForge_Enterprise_V8_12 (UI layer only:
  professional-ui.js/css, workspace/factory-v2/operations/editor templates,
  +2 test files, compose/ci/scripts/docs)
- Re-apply v8_workflows type-mapping fix (类型/分类) lost in upgrade
- Pin compose project name to siteforge-v8-10 so existing data volumes
  (hesupipe site 483295c29ea0, 193 entries) keep attached
- Drop stray .s10_* state files; ignore .s10_*/.sf_*/.s87_* patterns
- Plan/spec revisions per plan-review round 1 (icons are new design,
  real test assertions, recorded deviations)

Tests: 226 passed / 1 env-only failure (test needs node binary in PATH,
absent in python:3.12-slim container; host node v24 --check all 9 JS OK)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-22 17:02:45 +08:00
parent 19e865b889
commit 5c7643fcf2
31 changed files with 598 additions and 81 deletions
+57
View File
@@ -0,0 +1,57 @@
# SiteForge Enterprise V8.11 — 专业后台统一化验收
版本:`8.12.0-dev.1`。以 V8.10 完整项目为基线,**保留所有已有业务 API、数据库与构建 Worker**,仅重构统一界面层及选站导航。
## 1. 核心问题与对应处理
| 旧体验 | 新实现 | 代码位置 |
|---|---|---|
| 5 个专业页面各自导航,反复跳转找不到入口 | 共享顶部导航、面包屑、当前任务说明、返回业务工作台入口 | `app/static/professional-ui.js`, `professional-ui.css` |
| 当前网站在不同工具间失效或被重置 | 使用同域 `siteforge:selected-site` 偏好记录,**再次经过 API 可见网站列表校验**;旧控件联动 | `professional-ui.js`, `workspace.js`, `factory-v2.js`, `operations.js` |
| 编辑器按钮密集,草稿、构建、发布混在一起 | 操作区域分组,草稿和正式发布文案清楚区分 | `professional-ui.js`, `professional-ui.css` |
| 手机后台打不开属性/结构面板 | 结构、预览、属性三种移动/平板面板切换 | `professional-ui.js`, `professional-ui.css` |
| 任务中心 CMS、构建、发布全部长列表堆在一页 | 三个任务阶段切换,不删除已有控件或修改业务逻辑 | `professional-ui.js`, `professional-ui.css` |
| 高级建站中心重复侧边栏 | 压缩为水平业务选项卡,共享站点导航 | `professional-ui.css` |
| 表单视觉、按钮焦点不统一 | 统一输入焦点、主次操作、危险色与必填校验可见状态 | `professional-ui.css`, `professional-ui.js` |
| 用户不知道复杂工具做什么 | 每页一行任务提示,可展开查看完整操作顺序和下一步 | `professional-ui.js` |
## 2. 页面覆盖
- `/` 默认简洁工作台(原入口保留,支持 `?view=...&site=...` 深链接)。
- `/editor/{site}/{entry}` 可视化页面编辑器。
- `/theme-gallery` 主题版本与设备预览。
- `/factory-studio` 高级网站设计与数据映射。
- `/production-v8` WordPress / Excel / XML / API / MySQL / 整站模板。
- `/operations` 迁移复核、Worker 任务、审批发布。
- `/classic` 旧式后台保留,不作为默认入口。
## 3. UX 规则
1. 顶层统一入口按照业务目标:工作台、内容管理、外观设计、导入迁移、构建交付。
2. 每个高级页面只显示当前任务的主要内容,原有专业功能通过局部 Tab 展示。
3. 按钮样式统一:蓝色主操作、白色次操作、危险操作文字红色。**危险操作仍使用既有权限校验与业务确认,不依赖 CSS。**
4. 页面选择网站必须校验 `GET /api/sites` 返回的可见 ID;编辑器跨网站切换时跳到目标站点的设计入口,而不拼接旧页面 ID。
5. 新增表单有效性提示使用浏览器原生校验,继续使用既有 `X-SiteForge-CSRF`。
6. 不把设计草稿误显示为网站正式已发布版本。
## 4. 自动化验证
- `python -m pytest -q --disable-warnings` 验证全套回归:**218 项通过**。
- `tests/test_professional_ui_v811.py` 为 8 项专项测试,覆盖受保护页面、资源、选站联动、表单、编辑器、任务分步和旧业务 API。
- `node --check app/static/professional-ui.js` 及既有 JS 文件语法检查。
- `python scripts/verify_release.py` 校验版本标识,CI/Compose 使用 `8.12.0-dev.1`。
## 5. 本轮边界
- 本轮统一的是 **SiteForge 原生管理后台**,不是已经编译完成的 Art Design Pro 官方工程。
- 流程界面优化不代表 CMS 深度迁移、SFTP/S3、公网发布、PostgreSQL/Redis 高可用已经完成。
- 当前执行环境没有完成真实 Docker Engine 和浏览器跨设备 E2E,因此不声称生产视觉验收通过。
- `SiteForge_V8_11_统一专业后台_交互预览.html` 为离线演示,包含模拟数据,**不连接真实 API**。以部署后的后台为实际行为依据。
## 6. 浏览器人工验收要点
- 登录 → 工作台选择站 A → 进入编辑器/主题预览/数据工具/任务中心,当前网站保持为 A;切换 B 后各工具使用 B 的记录。
- 在编辑器检查草稿、预览与发布按钮的分组;移动 390px / 360px 宽度下可切换结构、预览、属性并继续编辑。
- 任务中心切换“迁移 → 构建 → 审批发布”,原有按钮按权限可操作,错误及危险操作有明确反馈。
- 检查页面键盘焦点、必填校验、主次按钮色、系统 401 登录过期回退。
- Docker Compose 部署、升级/回滚后健康接口版本与后台版本一致。
+44
View File
@@ -0,0 +1,44 @@
# SiteForge Enterprise V8.12 — 工作台流程与任务可恢复性
## 本轮目标
在 V8.11 专业页面统一导航之后,继续修复普通用户实际操作中的断点。**本版不声称完成 Art Design Pro 官方前端或 P5 企业级远程发布**,数据库 schema、主题和已有构建引擎未作破坏性变更。
## 真实代码改动
| 旧问题 | 新功能 | 实现位置 |
|---|---|---|
| 刷新后回到首页,丢失当前站点 | 优先解析 URL 中 site/view,之后参考上次网站偏好;**都要先校验 /api/sites 可访问列表** | `app/static/workspace.js` |
| 无法前进/后退或分享指定页面 | 用 `history.pushState` 和 `popstate` 管理站点+菜单状态,避免浏览器刷新;异步选站采用序号避免慢响应覆盖当前站 | `workspace.js` |
| 工作台“完善设计”永远显示未完成 | 设计标为持续优化项,按已有内容与构建确定建议的下一步,不杜撰人工验收结果 | `workspace.js` |
| 关闭/刷新构建页后看不到运行中的任务 | 查询 `/api/enterprise/sites/{id}/jobs` 和已有构建版本;进入构建页自动刷新;有活跃任务时定期刷新并禁止重复点击 | `workspace.js` |
| 任务取消入口不直观 | 在构建页直观显示 Worker 状态与取消按钮,仍调用受权限保护的原 API | `workspace.js` |
| 构建未完成也显示预览/下载入口 | 仅完成状态提供预览、质量报告和 ZIP 下载 | `workspace.js` |
| “快速导入”默认直接写入且不可批次回滚 | 默认进入既有可暂存、预演、确认、回滚的专业导入工作台;快速直写保留在显式展开的高级区并要求确认 | `workspace.js` |
| 难以分清构建与正式发布 | 增加“交付前检查”按钮,调用既有 `/api/factory/sites/{id}/migration/readiness`,展示阻断及待审事项,不将构建完成误称为上线 | `workspace.js` |
## 验证与已知限制
- 后端使用现有 CSRF 与 RBAC,不引入第二套任务队列。
- 离线预览文件使用模拟 API 和示例数据,不连接真实后台,不能用于证明真实浏览器 E2E。
- 正式站点需要实测多网站切换、长耗时 Worker、真实数据导入和 SEO 审核;生产发布仍需 P5 完整实施。
- V8.12 没有声称已经完成 Elementor/WooCommerce 任意站点无损迁移、PostgreSQL/Redis 多实例生产验收或官方 Art Design Pro 编译。
## 推荐人工验收步骤
1. 登录,选择网站 A,进入内容管理;复制浏览器 URL 并刷新,仍在 A 内容页面。
2. 切换 B,使用浏览器返回/前进,正确恢复 A/B 且没有旧站 API 响应覆盖当前站。
3. 提交构建,跳到其他菜单再回来;Worker 运行时界面可恢复;取消按钮有确认。
4. 构建未完成时不提供下载;成功后出现预览、检查及 ZIP。
5. 导入页面的主要操作进入“安全导入”,直写只在高级折叠区。
6. 运行交付前检查,能识别阻断和待审核事项;检查通过也不会显示已上线。
7. 360px 与 390px 下侧边栏、任务列表、操作按钮可触达。
## 运行
```powershell
docker run --rm -v "${PWD}:/project" -w /project python:3.12-slim python scripts/init_config.py
docker compose up -d --build
```
**部署建议:** 在新测试卷启动,不直接覆盖原 V8.11 数据卷。检查 `/api/health` 版本为 `8.12.0-dev.1` 后再进行测试。
@@ -20,13 +20,9 @@
## Phase 1+2:平台适配与骨架跑通(Task 1-8)
### Task 1: Git 基线
### Task 1: Git 基线 —— ✅ 已完成(2026-10-22,幂等跳过)
**Files:** 无新文件(初始化仓库)
- [ ] **Step 1:** `cd $ROOT && git init && git add -A && git status --short | head -20`
- [ ] **Step 2:** 确认 `.env`、`storage/`、`hesupipe_clean2.xml` 未被跟踪(.gitignore 已含 `.env`、`storage/`;`git check-ignore .env` 应有输出;`hesupipe_clean2.xml` 加入 .gitignore 一行)
- [ ] **Step 3:** `git commit -m "chore: baseline V8.10.0-dev.1 with v8_workflows type-mapping fix and trade-pro spec"`(含 Co-Authored-By 行,下同)
已执行并有扩展:仓库初始化、基线提交、远程 `http://219.157.255.213:25311/xinyouhe/cms-SiteForge.git` 配置并推送(main + feat/trade-pro-theme),远程原有 V5 基线历史经 `-s ours` 无损合并,`docs/COMPLETION_PLAN.md` 带入当前树;`.env`/密码确认未入库。随后追加 **V8_12 原地升级**(26 文件覆盖 + bug 修复重放 + compose 项目名钉回 `siteforge-v8-10` 保护数据卷)。执行者无需重跑本任务。
### Task 2: 主题发现单一源(F1)
@@ -40,15 +36,18 @@
```python
"""Theme discovery must be a single source of truth."""
import json
from pathlib import Path
from app import core, theme_pro, theme_store
ROOT = Path(core.__file__).resolve().parent.parent
def test_discover_returns_builtin_themes_with_manifests():
ids = core.discover_themes()
for tid in ('automotive', 'industrial', 'corporate', 'minimal'):
assert tid in ids
import json
for tid in ids:
manifest = json.loads((core.ROOT / 'themes' / tid / 'manifest.json').read_text(encoding='utf-8'))
manifest = json.loads((ROOT / 'themes' / tid / 'manifest.json').read_text(encoding='utf-8'))
assert manifest.get('id') == tid
def test_three_whitelists_agree():
@@ -56,8 +55,6 @@ def test_three_whitelists_agree():
assert isinstance(core.THEMES, tuple)
```
注:`core.ROOT` 若不存在,测试里用 `pathlib.Path(app.__file__).parent.parent`。
- [ ] **Step 2:** `python -m pytest tests/test_theme_registry.py -q` → 预期 FAIL(`discover_themes` 不存在)
- [ ] **Step 3: 实现**——`app/core.py:12` 替换为:
@@ -208,13 +205,19 @@ def test_trade_pro_registered_and_compatible():
assert result['valid'], result['errors']
assert not result['errors']
def test_trade_pro_builds_real_site():
# 集成冒烟:真实构建函数对演示站点渲染 home 不抛异常(复用现有测试夹具方式,
# 参考 tests/test_theme_pro_v3.py 中的最小站点夹具)
...
def test_trade_pro_builds_real_site(tmp_path):
# 复用 tests/test_theme_pro_v3.py 中"建站→切主题→构建→断言预览页"的既有写法
# (夹具工厂在 tests/test_factory_v2.py:15-30),theme 用 'trade-pro'。
# 真实断言(不允许空壳):
# 1. 构建成功且生成 index.html
# 2. 输出包含 lang="en"
# 3. 不包含平台中文默认导航文案"首页"
html = (tmp_path / 'index.html').read_text(encoding='utf-8') # 按夹具实际构建目录
assert 'lang="en"' in html
assert '>首页<' not in html
```
(第二个测试复用 test_theme_pro_v3.py 已有的最小站点构建夹具写法,theme 传 'trade-pro'。)
(执行时先读 test_theme_pro_v3.py 的相邻测试,逐行复制其夹具调用方式,仅替换 theme 参数与断言;禁止保留 `...` 空壳。)
- [ ] **Step 2:** 跑 → FAIL
- [ ] **Step 3: 创建文件**
@@ -230,7 +233,7 @@ def test_trade_pro_builds_real_site():
"style": "international-b2b",
"entry": "pro.html",
"styles": ["theme.css", "blocks.css"],
"page_templates": ["home","about","contact","listing","product","article","case","standard","category"],
"page_templates": ["home","about","contact","listing","category","product","article","brand","case","service","faq","standard","notfound"],
"blocks": ["hero","richtext","features","stats","collection","image_text","gallery","faq","cta","attributes","spacer","layout","carousel","video","tabs","pricing","map","form_link"],
"responsive": true,
"auto_binding": true,
@@ -240,7 +243,9 @@ def test_trade_pro_builds_real_site():
}
```
`site.html`:以 `themes/industrial/site.html` 为底,改 `lang="zh-CN"` → `lang="en"`,其余变量占位不动(它只包 {{content}})。
`site.html`:以 `themes/industrial/site.html` 为底(它是 4.4KB 的完整独立模板,自带 header/footer 结构,**不引用共享宏库**),改 `lang="zh-CN"` → `lang="en"`。注意:pro 主题的正式渲染走 pro.html,site.html 主要服务非 pro 路径/兜底。
**已知新行为(评审发现,记录不阻断)**:Task 2 后 trade-pro 进入 BUILTIN,上传主题 ZIP 可声明 `layout_family:'trade-pro'`(theme_store.install 会拷贝 trade-pro 的 site/pro.html),而 ZIP 包渲染走共享宏回落——与依赖自有宏库的 trade-pro 存在潜在错配。本轮接受(上传包本就以声明式为主),后续如出问题在 install() 校验 layout_family 白名单。
`_professional_components.html`:先做**透传骨架**(从共享库复制 card/cover 等宏,Task 10 起逐个换成 cms 设计 + SVG 图标)。
@@ -289,9 +294,11 @@ def test_frontend_entries_include_trade_pro():
]:
assert needle in (base / rel).read_text(encoding='utf-8'), rel
def test_theme_color_map_covers_trade_pro():
# theme_pro.make_context 的 theme_color 字典含 trade-pro(渲染 smoke 断言 meta theme-color)
...
def test_theme_color_map_covers_trade_pro(tmp_path):
# 真实断言:trade-pro 构建出的首页含 meta theme-color #0b3d91
# (复用 Task 5 的构建夹具写法)
html = (tmp_path / 'index.html').read_text(encoding='utf-8')
assert '<meta name="theme-color" content="#0b3d91"' in html
```
- [ ] **Step 2:** 跑 → FAIL
@@ -328,11 +335,13 @@ def test_theme_color_map_covers_trade_pro():
- [ ] 验收断言:`themes/trade-pro/theme.css` 覆盖 tokens 全集(颜色/字体/圆角/间距);构建产物 `assets/theme.css` 含 `--sf-tp-` 变量;平台 custom.css 的 `.btn{...}` 与主题按钮类无交集(grep 断言)
- [ ] pytest(现有快照不受影响)+ commit
### Task 9: 图标宏库(替代箭头)
### Task 9: 图标宏库(新增设计——不是 cms 移植)
- 源:cms 组件与 dist HTML 中的内联 SVG(`grep -o '<svg[^>]*>' dist/hesupipe/en/index.html` 起逐个提取;参考 `src/components/*.astro` 里的图标用法)
- [ ] `themes/trade-pro/_professional_components.html` 定义 `icon(name)` 宏:内联 SVG 集合(≥8 个:arrow-right/check/phone/mail/location/whatsapp/download/quote 等,从 cms 实际用到的集合提取)
- [ ] 验收:home/product 页渲染输出含 `<svg` 且无裸文本箭头 `→` 作为唯一图标(对照 dist)
> 评审修正(2026-10-22):cms 源码与 dist 实测 **0 个 SVG**,其图标实为文本箭头 `→`(index 15 处、product 17 处)。用户需求"图标需要优化、现在很多都是箭头"意味着图标是**超出 cms 源的新增设计**,不与 dist 对照。
- [ ] `themes/trade-pro/_professional_components.html` 定义 `icon(name)` 宏:自设计内联 SVG 集合,线条风格与 `--sf-tp-*` 令牌一致,≥8 个:arrow-right / check / phone / mail / location / download / search / quote
- [ ] 尺寸/描边随 CSS 变量(`currentColor`、`1.5px` stroke),跟随深浅文字色
- [ ] 验收:home/product 渲染中**交互元素的图标均为 SVG**,不再以裸 `→` 作为唯一图标(对照对象是本主题自身,非 dist);`aria-hidden="true"` 保证可访问性
- [ ] commit
### Task 10: 九种独立布局逐个移植(每布局一个 commit)
@@ -361,6 +370,14 @@ def test_theme_color_map_covers_trade_pro():
- [ ] 实战验收:站点 483295c29ea0 最终构建 ≥203 页零错误;视觉对照两层标准(spec §6)逐页记录
- [ ] 更新 spec 附录验收记录;commit
## 与 spec 的已记录偏差(评审裁定可接受)
1. **发现函数放 core 而非 spec 4.2.1 写的 theme_store**:等价实现。core 已被全部引用方(builder/main/theme_pro)导入,放 core 消除反向耦合;theme_store.BUILTIN 经 import 别名保持一致。
2. **builder.ENV 保持单目录**(spec 4.2.4 提到两处构造点):已验证 site.html 是不引用共享宏的独立模板,且带主题前缀的路径加载在单目录下安全;仅 theme_pro.LOADER 改为 per-theme env_for。
3. **spec §6 "渲染快照"以 E2E 页面断言实现**(构建后逐页 200 + 结构选择器 + 文案断言),不另建 Jinja 快照测试文件。
4. **/api/themes(main.py:267)经 core.THEMES 动态化自动生效**,不设专项测试(catalog 由既有测试覆盖)。
5. **前端入口 option 文案**:三个 HTML 下拉用"Trade Pro · 外贸 B2B(英文)"中文风格与各文件现状一致(theme-gallery 用英文)。
## 风险与回退
- 每个 Task 独立 commit,出问题 `git revert` 单点回退
@@ -5,7 +5,7 @@
## 1. 背景与目标
把 cms 项目(D:\project\cms)Astro 主题的视觉设计移植为 SiteForge 第 5 套内置主题 `trade-pro`,首要服务 hesupipe.com 重建(英文外贸 B2B),长期服务后续外贸类客户站。附带解决:默认语言英文(现四套主题模板硬编码 `lang="zh-CN"` + 中文文案)、图标体系(现主题大量箭头符号,cms 主题有内联 SVG 图标集)。
把 cms 项目(D:\project\cms)Astro 主题的视觉设计移植为 SiteForge 第 5 套内置主题 `trade-pro`,首要服务 hesupipe.com 重建(英文外贸 B2B),长期服务后续外贸类客户站。附带解决:默认语言英文(现四套主题模板硬编码 `lang="zh-CN"` + 中文文案)。**图标更正(R3.1)**:cms 源码实测 0 个 SVG、图标亦为文本箭头,故"替换箭头为 SVG 图标集"属**新增设计项**(用户明确要求优化图标),不是 cms 移植内容,不与 dist 对照。
### 范围外
@@ -88,7 +88,7 @@ themes/trade-pro/
- `lang="en"`,主题内全部 UI 文案/面包屑/分页/日期英文;英文 chrome 兜底见 4.2.5
- tokens.css 变量 `--sf-tp-*` 桥接 SiteForge 设计令牌(V8.7 全站设计草稿可调),优先级规则见 4.2.6
- 图标:cms 内联 SVG 集合进主题宏库(替代箭头)
- 图标:自设计内联 SVG 集合进主题宏库(替代箭头;**新增设计**,cms 源无 SVG,见 §1 更正)
- 素材规范:主题包仅含中性演示素材;hesupipe 真实图片留在站点数据侧
### 4.6 数据映射与导入通道