openxiangda-skill-kit 2.0.0-alpha.24 → 2.0.0-alpha.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/architecture/admin-shell-v2.md +3 -1
- package/docs/architecture/ant-design-pro-v6-admin-foundation.md +320 -0
- package/docs/architecture/environment-configuration-kernel-v2.md +2 -0
- package/docs/architecture/implementation-roadmap.md +12 -14
- package/docs/architecture/local-development-v2.md +3 -1
- package/docs/architecture/on-demand-production-environment-v2.md +79 -0
- package/docs/architecture/repository-and-release.md +2 -1
- package/docs/architecture/stable-field-protocol-adoption.md +174 -0
- package/docs/design/admin/README.md +124 -0
- package/docs/design/admin/data-management-v1.png +0 -0
- package/docs/design/admin/workbench-v1.png +0 -0
- package/docs/design/admin/workflow-detail-v1.png +0 -0
- package/docs/design/admin-pro-v6/README.md +24 -0
- package/docs/design/admin-pro-v6/data-management.png +0 -0
- package/docs/design/admin-pro-v6/workbench.png +0 -0
- package/docs/design/admin-pro-v6/workflow-submit-modal.png +0 -0
- package/docs/design/admin-v2/README.md +3 -2
- package/docs/frontend.md +58 -48
- package/docs/getting-started.md +2 -2
- package/docs/index.md +1 -1
- package/package.json +3 -2
- package/skills/openxiangda-v2-architecture/SKILL.md +3 -2
- package/skills/openxiangda-v2-frontend/SKILL.md +36 -66
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
# OpenXiangda Admin Shell v2
|
|
1
|
+
# OpenXiangda Admin Shell v2 历史设计(已被 Pro v6 决策取代)
|
|
2
2
|
|
|
3
3
|
状态:方案已确认并进入分阶段实现;2026-08-14 已完成平台 Native A1 有界 RoleSession context 及真实 PostgreSQL 验收
|
|
4
4
|
|
|
5
|
+
> 2026-08-16 架构修订:Admin 表现层和工具链已决定[全量切换到 Ant Design Pro v6](./ant-design-pro-v6-admin-foundation.md)。本文关于“不引入 ProComponents/Umi”“继续使用 Vite/自研 Shell”“流程提交常驻双栏预览”的结论全部废止;本文保留的现状审计以及 RoleSession、route manifest、权限、标签/保活、脏状态、Data/Workflow 合同继续作为迁移不变量,不再作为 UI 技术选型依据。
|
|
6
|
+
|
|
5
7
|
适用范围:OpenXiangda 2.0 新应用,不兼容 1.x 运行时
|
|
6
8
|
|
|
7
9
|
决策对象:`openxiangda-admin`、官方应用模板、参考应用,以及必要的平台身份协议
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Ant Design Pro v6 Admin 全量切换决策
|
|
2
|
+
|
|
3
|
+
状态:2026-08-16 已确认,进入实现;这是 OpenXiangda 2.0 的替换型架构决策
|
|
4
|
+
|
|
5
|
+
适用范围:`openxiangda-admin`、`create-openxiangda` 官方模板、2.0 CLI/生成器/MCP/Skills、2.0 参考应用与前端验收。OpenXiangda 1.x 不在范围内。
|
|
6
|
+
|
|
7
|
+
## 1. 决策
|
|
8
|
+
|
|
9
|
+
OpenXiangda 2.0 的默认 Admin 基础彻底切换到官方 Ant Design Pro v6 Simple 模板体系:React 19、Ant Design 6、Umi Max 4、ProComponents 3,以及 Pro v6 采用的样式与构建方案。`openxiangda-admin` 只保留新的包名与职责边界,`src`、测试和样式从空目录重建;旧实现不作为迁移源,也不复制其组件、路由器、缓存器、页面结构或 CSS。新包是平台集成层和经过约束的标准业务组件集合,不再自行实现一套与 Ant Design Pro 竞争的布局、路由承载、搜索表格、表单和详情框架。
|
|
10
|
+
|
|
11
|
+
这是直接替换,不建立双框架、双路由、运行时开关或 2.0 兼容适配层。当前 2.0 只有内部测试应用,可以重新生成或废弃;正式的 2.0 包只在旧实现删除、完整验收通过后发布。
|
|
12
|
+
|
|
13
|
+
采用以下官方能力作为默认实现:
|
|
14
|
+
|
|
15
|
+
- `ProLayout` 与 Umi 路由承担 Admin 桌面布局、导航和面包屑;
|
|
16
|
+
- `PageContainer`、`ProCard`、`StatisticCard` 承担标准页面和工作台骨架;
|
|
17
|
+
- `ProTable` 承担搜索、服务端列表、列配置、排序和分页交互;
|
|
18
|
+
- `ProForm` 承担标准业务表单和操作表单;
|
|
19
|
+
- `ProDescriptions` 承担标准详情信息展示;
|
|
20
|
+
- ECharts React 适配层承担受限聚合图表,不把完整业务数据下载到浏览器聚合。
|
|
21
|
+
|
|
22
|
+
实施基线固定为 Ant Design Pro `v6.0.2`(commit `2b453c67b535b76f5f95d6542397a4b987b61de2`)。依赖精确锁定为 `@umijs/max@4.6.51`、`@ant-design/pro-components@3.1.12-0`、`antd@6.4.3`;React 保持当前仓库已经验证的 `19.2.8`。安装结果由 `pnpm-lock.yaml` 固定,不使用浮动 `latest`,也不把 Ant Design Pro 作为 Git submodule。任何版本升级都必须作为新的架构主题重新完成 API、构建与浏览器验收。
|
|
23
|
+
|
|
24
|
+
实现只复用官方源码的公开包、配置结构与页面范式,不复制官方示例登录、Mock 用户、演示 API 或业务页面。上游 tag/commit、精确依赖和本仓库 lockfile 三者共同构成可复现基线。
|
|
25
|
+
|
|
26
|
+
参考:
|
|
27
|
+
|
|
28
|
+
- [Ant Design Pro](https://github.com/ant-design/ant-design-pro)
|
|
29
|
+
- [Ant Design Pro v6 发布说明](https://github.com/ant-design/ant-design-pro/releases)
|
|
30
|
+
- [ProComponents](https://github.com/ant-design/pro-components)
|
|
31
|
+
|
|
32
|
+
## 2. 为什么替换
|
|
33
|
+
|
|
34
|
+
### 2.1 问题证据
|
|
35
|
+
|
|
36
|
+
当前自研 Admin 已经实现了身份、路由、标签、数据页、表单、工作流页面等大量能力,但产品层仍出现以下问题:
|
|
37
|
+
|
|
38
|
+
- 默认页面视觉和交互粗糙,内部编码、协议字段和错误容易直接暴露;
|
|
39
|
+
- 布局、表格、表单、详情、工作台都由平台重复实现,成熟度和一致性不足;
|
|
40
|
+
- 页面基础能力与平台业务协议耦合,单点修复容易影响壳层、查询或生命周期;
|
|
41
|
+
- 当前方案建立在旧的 ProComponents 兼容性判断上,而 ProComponents 3 已进入 Ant Design 6 技术栈;
|
|
42
|
+
- 流程提交把审批预览长期放在页面中,偏离普通用户“填写并提交”的主任务。
|
|
43
|
+
|
|
44
|
+
因此继续修补当前表现层会延长自研框架维护成本。2.0 没有稳定外部应用包袱,适合在公开发布前一次性换到底层成熟框架,同时保留已经验证的平台协议和业务内核。
|
|
45
|
+
|
|
46
|
+
### 2.2 能力所有者
|
|
47
|
+
|
|
48
|
+
| 能力 | 唯一所有者 |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| 布局、导航承载、基础页面交互 | Ant Design Pro v6 / Umi Max / ProComponents |
|
|
51
|
+
| 用户端桌面/移动页面表现 | 应用仓库的 Desktop Renderer 与 Mobile Renderer;共享 OpenXiangda 2.0 页面协议 |
|
|
52
|
+
| 表单字段、附件与业务值渲染 | OpenXiangda 2.0 Field Kit;平台合同是唯一数据语义来源 |
|
|
53
|
+
| OAuth2、Principal、RoleSession、角色切换 | OpenXiangda Platform |
|
|
54
|
+
| capability、数据范围与最终授权 | OpenXiangda Platform;浏览器只消费投影 |
|
|
55
|
+
| 路由与菜单业务声明 | 应用仓库 route manifest,经 OpenXiangda 确定性生成 |
|
|
56
|
+
| Data API/App API 查询、事务与业务数据 | OpenXiangda Platform / 应用 NestJS 后端 |
|
|
57
|
+
| Workflow 状态机、Surface、允许操作和字段策略 | Workflow Kernel v2 |
|
|
58
|
+
| 标签边界、保活、脏状态和身份失效 | `openxiangda-admin` 平台集成层 |
|
|
59
|
+
| 环境、AppVersion、构建和发布状态 | OpenXiangda Platform 与 2.0 CLI |
|
|
60
|
+
|
|
61
|
+
Ant Design Pro 的 `access` 只能作为 capability 结果的 UI 投影,不能成为授权事实源。Umi `initialState`、浏览器缓存和模板 Mock 都不能成为身份、权限、业务数据或平台运行状态的第二存储。
|
|
62
|
+
|
|
63
|
+
## 3. 稳定不变量
|
|
64
|
+
|
|
65
|
+
1. 一个应用版本仍由前端、NestJS 后端、配置合同、生成类型和构建摘要共同构成不可变 AppVersion。
|
|
66
|
+
2. 远程环境仍只有 `preproduction` 与按需创建的 `production`;本地是运行模式,不是第三个远程环境。
|
|
67
|
+
3. 服务端始终是身份、授权、数据、流程动作与部署状态的最终裁决者。
|
|
68
|
+
4. 业务字段始终由 Data API/App API 保存;Workflow Kernel 只保存流程状态、参与者、动作、字段策略和不可变审计。
|
|
69
|
+
5. 当前角色是稳定、显式的 RoleSession;同一用户的多个角色不隐式合并。应用管理员保留明确的最高授权声明。
|
|
70
|
+
6. 路由、菜单和直接 URL 访问使用同一份应用 route manifest 与同一 capability 结果。
|
|
71
|
+
7. 标签持久化、组件保活、数据查询和业务草稿仍是四类不同状态;身份 epoch 改变时旧请求、实例和选择必须失效。
|
|
72
|
+
8. 1.x 应用、流程、自动化、View 和发布工具不引用本决策中的包或运行时。
|
|
73
|
+
9. Admin 是桌面 B 端产品,默认验收宽度为 1280px 及以上,不为手机端维护抽屉导航、压缩表格或触摸版后台交互。
|
|
74
|
+
10. 用户端共享数据、表单、校验和流程合同,但 Desktop UI 与 Mobile UI 是两个独立 renderer;设备只在应用入口判定一次,不在同一组件树中堆叠响应式分支。
|
|
75
|
+
|
|
76
|
+
## 4. 前端合同
|
|
77
|
+
|
|
78
|
+
### 4.1 工程与路由
|
|
79
|
+
|
|
80
|
+
官方模板的 `apps/web` 从 Vite/手写 React Router 切换为 Umi Max。应用继续声明 OpenXiangda route manifest;`openxiangda generate` 将其确定性编译成 Umi 路由和 ProLayout 菜单元数据。生成结果必须可重复,人工维护的第二份路由树、菜单树或权限树视为构建错误。
|
|
81
|
+
|
|
82
|
+
Pro 模板自带的登录页、Mock 用户、示例 API、演示菜单和无用页面全部删除。身份启动只调用平台 RoleSession bootstrap;失败时显示可恢复的壳层错误界面,不能白屏,也不能回退到模板假用户。
|
|
83
|
+
|
|
84
|
+
应用业务路由按模块 lazy load。标签和保活由新的 `openxiangda-admin` 对 Umi 生命周期做薄封装:默认最多 12 个标签、6 个保活实例,按身份和 manifest fingerprint 隔离;动态详情、任务和编辑页默认不持久化、不保活。这里只保留产品不变量,不保留旧标签或保活实现代码。
|
|
85
|
+
|
|
86
|
+
### 4.2 标准数据管理
|
|
87
|
+
|
|
88
|
+
`DataListPage` 使用 ProTable,但只允许通过 OpenXiangda request adapter 访问类型化 Data API/App API。adapter 把 ProTable 参数转换成现有 DataQuery 的服务端分页、排序和有界筛选;不增加第二套查询 DSL,不在浏览器下载全量数据后过滤。
|
|
89
|
+
|
|
90
|
+
列显隐、密度、页大小与搜索展开状态可以按 `tenant + app + environment + roleSubject + resource + configVersion` 保存为 UI 偏好。Token、权限判定、行数据、查询结果、选择结果和业务字段不得持久化。字段策略决定列表、搜索、导入、导出、查看和编辑是否可见或可写。
|
|
91
|
+
|
|
92
|
+
### 4.3 标准表单与详情
|
|
93
|
+
|
|
94
|
+
`DataFormPage` 使用 ProForm,由 DataResource、字段策略和应用的业务标签生成控件。创建和修改经类型化客户端提交,revision 冲突、幂等失败、服务端字段错误和脏状态由标准适配层处理。
|
|
95
|
+
|
|
96
|
+
`DataRecordPage` 使用 PageContainer、ProDescriptions、附件和业务审计时间线。普通用户只看到业务标签和值;resource code、workflow code、node id、revision 和原始 JSON 只在开发/诊断边界按权限展示。
|
|
97
|
+
|
|
98
|
+
### 4.4 流程页面
|
|
99
|
+
|
|
100
|
+
流程提交页的正常状态只展示业务表单和一个主按钮“提交”。用户点击后按以下顺序执行:
|
|
101
|
+
|
|
102
|
+
1. 校验并通过 Data API/App API 保存业务数据,取得 `businessKey` 与 revision-bound `dataRef`;
|
|
103
|
+
2. 调用 Workflow prepare;
|
|
104
|
+
3. 在 Modal 中展示真实审批路径、条件分支、审批人,并仅在必要时收集主部门或未解析审批人;
|
|
105
|
+
4. 用户确认后以稳定幂等键发起流程。
|
|
106
|
+
|
|
107
|
+
审批预览不常驻页面,不把“预览流程”“保存并生成预览”“发起”暴露成三个主要步骤。业务字段、主部门或审批人答案变化后旧 preparation token 立即失效。保存草稿可以作为应用显式贡献,但不是所有流程页的第二主操作。
|
|
108
|
+
|
|
109
|
+
任务和流程详情使用 PageContainer、ProDescriptions、Timeline 与标准 Action Surface。允许按钮、字段读写、操作表单和下一处理人只消费后端 Surface;同意、拒绝、转交、回退、加签和代理不在浏览器复制状态机规则。
|
|
110
|
+
|
|
111
|
+
### 4.5 工作台与个人中心
|
|
112
|
+
|
|
113
|
+
默认工作台使用 ProCard/StatisticCard 组织指标、趋势、待办、快捷入口和最近访问。统计只来自带 RoleSession 和数据范围的服务端受限聚合;无真实数据时展示空态,不伪造数字。
|
|
114
|
+
|
|
115
|
+
个人中心统一展示资料、当前环境、稳定角色、数据范围、退出和角色切换。流程代理作为 Workflow 的可选贡献,不让 Core 静态依赖 Workflow。切换角色后更新 identity epoch,取消或丢弃旧请求,并恢复该角色自己的有界 UI 偏好。
|
|
116
|
+
|
|
117
|
+
### 4.6 用户端双 UI 与 Field Kit
|
|
118
|
+
|
|
119
|
+
Admin 与用户端是两个产品入口。Admin 只提供桌面管理体验;用户端由应用声明同一份页面、字段、动作和流程协议,再分别交给 Desktop Renderer 与 Mobile Renderer。两个 renderer 共享请求状态机、表单值、校验规则、字段策略、幂等键和错误模型,但不共享页面布局组件。平台在入口根据设备能力和用户显式偏好选择 renderer;切换 renderer 不改变 URL 业务语义、RoleSession 或业务草稿标识。
|
|
120
|
+
|
|
121
|
+
移动端不是桌面页缩放:表单采用单列、触摸目标、移动日期/选择器、底部安全区动作栏、图片拍摄/选择和适合小屏的分步反馈;桌面用户端可以使用栅格、侧栏详情和批量能力。需要同时支持两端的应用页面必须提供两套 view composition;纯管理页面无需生成移动版本。
|
|
122
|
+
|
|
123
|
+
新增独立的 OpenXiangda 2.0 Field Kit,按[稳定字段数据协议采用与声明分层决策](./stable-field-protocol-adoption.md)提供桌面与移动 renderer。物理存储、值形状、查询和索引协议不重新设计;V1 低代码组件名和展示 Schema 不作为 2.0 数据合同,新的可选 Surface Definition 只负责默认 UI。允许移植 1.x 中已经验证的平台能力控制器和测试,但禁止把 1.x Admin、页面壳、发布生命周期或样式运行时带入 2.0。
|
|
124
|
+
|
|
125
|
+
移动端的强制平台组件边界覆盖全部已支持的标准持久化字段,而不是只覆盖有独立后台接口的复杂类型。文本、数值、单/多选、下拉、级联、日期、日期区间、地址、人员、部门、附件、图片、富文本、签名和子表等都由 Mobile Field Kit 输入和规范化;其中选择面板、日期流程、地址级联、键盘、触摸目标和安全区沿用并升级平台已经验证的移动体验。页面可以自由使用移动组件库完成布局、导航、按钮和普通弹层,但不得直接用 Ant Design 桌面字段、原生输入控件或临时移动控件替代标准平台字段。缺失能力通过显式 Field Kit 扩展补齐,不在业务页面内形成第二套字段协议。
|
|
126
|
+
|
|
127
|
+
图片和附件字段只能使用 Field Kit 的平台附件组件。组件继续使用稳定附件值、上传、下载、鉴权预览、图片压缩和未绑定文件清理协议;应用不得直接使用 Ant Design `Upload`、原生文件输入或自行拼接对象存储 URL。生成器、ESLint 规则和模板静态审计把绕过行为视为构建错误。
|
|
128
|
+
|
|
129
|
+
列表、详情和表单使用同一 Field Renderer Registry。基础类型覆盖文本、长文本、布尔、日期时间、数值、金额、百分比、链接和枚举;平台类型覆盖成员、部门、角色主体、图片、附件和流程状态。成员/部门展示头像、名称和辅助组织信息,枚举使用声明色彩和标签,多选采用有界折叠,数值按精度、单位和 locale 格式化;未知类型使用安全文本降级并在开发诊断中报告,不能直接渲染 `[object Object]` 或原始内部编码。
|
|
130
|
+
|
|
131
|
+
## 5. 本地开发、构建与发布
|
|
132
|
+
|
|
133
|
+
`openxiangda dev` 继续是一条命令的生命周期入口,但改为监督 Umi 开发服务、NestJS 和独立本地平台服务。真实 PostgreSQL 仍由本地平台按工作区隔离管理,不要求开发者在电脑中手工安装数据库。Umi Mock 不能承载平台事实;本地平台与远程平台消费同构的身份、Data、Workflow 和 Event HTTP 合同。
|
|
134
|
+
|
|
135
|
+
AppPackage 的边界不变:生产构建仍输出静态前端 `dist`、NestJS OCI 镜像、配置合同和摘要。构建入口从 Vite 迁移到 Umi/utoopack;同一源代码连续构建必须闭包一致,生产包静态证明不包含本地 Mock、测试用户或开发凭据。
|
|
136
|
+
|
|
137
|
+
生产体积门禁按浏览器实际传输成本和解析上限分别约束:每个异步 JavaScript 块 gzip 后不得超过 420KB、解压后不得超过 1.5MB,首屏脚本解压总量不得超过 1.5MB。Ant Design/Pro 的异步共享块不再沿用 Vite 时代 800KB 的单一原始文本阈值;路由拆分数量、首屏闭包和开发标记扫描仍独立失败关闭。
|
|
138
|
+
|
|
139
|
+
正式切换完成时删除:
|
|
140
|
+
|
|
141
|
+
- Vite 配置和只服务旧模板的插件;
|
|
142
|
+
- 手写 React Router 路由树和重复菜单树;
|
|
143
|
+
- 自研 `AdminShell` 布局及其专用 CSS;
|
|
144
|
+
- 与 ProTable、ProForm、ProDescriptions 重复的通用搜索、列表、表单和详情壳;
|
|
145
|
+
- 旧流程提交常驻预览布局;
|
|
146
|
+
- 模板中的仪器业务演示和所有兼容开关。
|
|
147
|
+
|
|
148
|
+
不删除平台服务端身份、Data/Workflow HTTP 合同、route manifest 合同和运行诊断协议。旧前端中的 Provider、DirtyStateRegistry、受限偏好存储、路由匹配和生命周期实现全部删除;需要的产品行为在新的 Pro/Umi 边界重新实现,不允许通过 import、包装或复制旧源码继续使用。
|
|
149
|
+
|
|
150
|
+
允许复用的代码仅限不含 React、DOM、路由、样式或页面状态的生成契约与 HTTP 客户端。凡位于旧 `openxiangda-admin/src` 或旧模板 `apps/web/src` 的实现,一律视为待删除前端代码。
|
|
151
|
+
|
|
152
|
+
## 6. 默认参考应用
|
|
153
|
+
|
|
154
|
+
新参考应用改为“企业采购申请”,避免用仪器系统代表通用框架。默认覆盖:
|
|
155
|
+
|
|
156
|
+
- 采购申请人、部门负责人、财务、采购管理员和应用管理员;
|
|
157
|
+
- 采购单 CRUD、服务端搜索/排序/分页、附件、金额统计和部门数据范围;
|
|
158
|
+
- 多角色稳定切换、应用管理员授权声明和字段读写策略;
|
|
159
|
+
- 金额条件分支、审批预览 Modal、同意/拒绝/转交/回退/加签/代理;
|
|
160
|
+
- 流程事件消费、一个应用自定义 App API 动作与幂等回执;
|
|
161
|
+
- preproduction 默认运行,只有执行发布正式功能后才创建 production workload。
|
|
162
|
+
|
|
163
|
+
参考应用是验收载体,不向 `openxiangda-admin` 引入采购领域代码。
|
|
164
|
+
|
|
165
|
+
## 7. 失败、并发与资源边界
|
|
166
|
+
|
|
167
|
+
- route manifest 生成不一致、重复路径、缺 renderer 或权限漂移必须在 generate/check/build 阶段失败。
|
|
168
|
+
- Umi 开发服务唯一拥有 `src/.umi`;普通类型检查复用已存在的开发类型,只在目录缺失时初始化。生产构建只使用 `src/.umi-production`,不得通过 `max setup` 删除正在运行的开发工件。
|
|
169
|
+
- RoleSession bootstrap 失败时 fail closed,并提供重试、重新登录和 request id;页面不能以无权限空态掩盖系统错误。
|
|
170
|
+
- identity epoch 变化后中止旧请求;无法中止的 ProTable/React Query 响应按 generation 丢弃。
|
|
171
|
+
- 表单保存、流程 prepare/start 和自定义动作使用 revision/CAS 与稳定幂等键,重复点击或网络重试不能重复创建。
|
|
172
|
+
- 异步 chunk 加载失败使用路由级错误边界和就地重试,不能把整个应用变成白屏。
|
|
173
|
+
- 浏览器持久存储只允许有界 UI 偏好和逻辑路由,不保存 token、capability、业务响应或表单草稿。
|
|
174
|
+
- 删除 Pro 模板无用依赖和页面,业务模块按路由拆包;为首屏、单 chunk、总 JavaScript 和可选 Workflow chunk 建立预算。
|
|
175
|
+
|
|
176
|
+
## 8. 回滚边界
|
|
177
|
+
|
|
178
|
+
在首个正式 2.0 包发布前,回滚单位是整个工具链/模板/Admin 提交或 AppVersion,不在运行时保留旧 Shell。实现可以分提交,但对外只发布已删除旧实现且通过门禁的完整版本。
|
|
179
|
+
|
|
180
|
+
已经生成的 2.0 测试应用直接重新初始化或迁移源码贡献,不承诺 UI 组件 API 兼容。1.x 保持在 `tools/openxiangda` 与原平台运行时中,既不迁移也不回滚。
|
|
181
|
+
|
|
182
|
+
## 9. 可证伪验收
|
|
183
|
+
|
|
184
|
+
全量切换只有同时满足以下条件才算完成:
|
|
185
|
+
|
|
186
|
+
1. 从已打包工件在空目录创建企业采购参考应用,`openxiangda generate/check/test`、类型检查和 Umi production build 全部通过;
|
|
187
|
+
2. 依赖与源码审计证明没有 Vite、手写 React Router、旧 AdminShell、常驻流程预览或模板 Mock 进入生产包;
|
|
188
|
+
3. Ant Design lint、单元测试和 Playwright 覆盖 Admin 的 1280/1440px 桌面布局,以及用户端独立 Desktop/Mobile Renderer 的身份、字段、表单和流程主路径;Mobile 验收必须包含单/多选、下拉、级联、日期/日期区间、地址、人员/部门、数值、附件/图片和子表,且证明未加载桌面数据录入控件;
|
|
189
|
+
4. ProTable 覆盖服务端搜索、排序、分页、列配置、字段裁剪、修订冲突、导入导出和身份切换旧响应隔离;
|
|
190
|
+
5. ProForm/详情覆盖新建、编辑、脏状态、附件、审计、内部编码隐藏和服务端错误;
|
|
191
|
+
6. 流程页覆盖“业务表单 → 点击提交 → Modal 预览/补充选择 → 确认发起”,以及任务的完整标准动作;
|
|
192
|
+
7. `openxiangda dev/status/stop/reset` 在真实 PostgreSQL 上通过,前端与 Nest 热更新、本地重启保留和显式 reset 清理均有证据;
|
|
193
|
+
8. production bundle 不含 local canary、假用户、Mock API 或原始 Secret,并通过 chunk/首屏预算;
|
|
194
|
+
9. 同一 AppVersion 先部署 preproduction,再原样创建/晋级 production;失败可回滚上一 AppVersion;
|
|
195
|
+
10. 1.x View、流程、自动化与 1.x 发布回归无变化。
|
|
196
|
+
|
|
197
|
+
## 10. 实施顺序
|
|
198
|
+
|
|
199
|
+
1. 冻结官方 Pro v6 基线、依赖和新版页面设计验收稿;
|
|
200
|
+
2. 删除旧 Admin 与旧模板前端源码,建立空白 Umi Max / ProComponents 工程边界;
|
|
201
|
+
3. 从零实现 ProLayout、Umi route generator、身份启动、ProTable/ProForm/ProDescriptions、工作台和新的有界生命周期能力;
|
|
202
|
+
4. 改造流程提交 Modal、工作中心、任务和详情 Surface;
|
|
203
|
+
5. 从空白边界实现 2.0 Field Kit、用户端 Desktop/Mobile Renderer 与附件绕过门禁;
|
|
204
|
+
6. 更新本地开发编排、CLI/MCP/Skills、打包和发布门禁;
|
|
205
|
+
7. 用正式候选 tarball 创建企业采购参考应用并完成真实浏览器、NestJS、PostgreSQL、preproduction 验收;
|
|
206
|
+
8. 静态证明发布包没有旧源码、旧领域代码和兼容开关,通过 Changesets 物化一次正式候选版本。
|
|
207
|
+
|
|
208
|
+
上述步骤是一个发布单元内的实现顺序,不代表对外提供双框架。任一步不能达到可逆和可验证状态时,停止在源码提交边界修正,不把半成品发布给新应用。
|
|
209
|
+
|
|
210
|
+
## 11. 2026-08-16 实现轮门禁
|
|
211
|
+
|
|
212
|
+
### 问题证据与影响范围
|
|
213
|
+
|
|
214
|
+
- 当前模板仍受旧手写 `ApplicationShell`、路由匹配器、生命周期和仪器示例结构影响;局部替换为 ProLayout 后,真实浏览器验收出现身份操作被旧侧栏生命周期挤到底部的结构性冲突,证明渐进改造路线不可接受。
|
|
215
|
+
- `WorkflowSubmissionPage` 把审批预览常驻在页面,并把保存、预览、确认拆成多个主要动作。
|
|
216
|
+
- 影响范围限定为 `tools/openxiangda-v2` 的 Admin 包、模板、生成器、CLI/MCP/Skills 和新参考应用;1.x 仓库、1.x View、流程和自动化不引用本轮包。
|
|
217
|
+
|
|
218
|
+
### 稳定合同与失败语义
|
|
219
|
+
|
|
220
|
+
- route manifest 是路由、菜单和 capability 投影的唯一业务声明;生成器只产生 Umi/ProLayout 所需工件,不建立人工维护的第二棵树。
|
|
221
|
+
- RoleSession、DataQuery、Workflow Surface、AppVersion 与环境 Head 的服务端合同保持唯一事实源;Pro 组件只负责表现和参数适配。
|
|
222
|
+
- 身份初始化、异步 chunk、数据查询和流程 prepare 任一失败都显示带 request id 和重试动作的语义错误态,不允许白屏或伪装成空数据。
|
|
223
|
+
- 流程 prepare token 绑定业务数据 revision、主部门/审批人答案和身份 epoch;任一变化使旧 token 失效。重复确认使用稳定幂等键。
|
|
224
|
+
|
|
225
|
+
### 安全、资源与并发边界
|
|
226
|
+
|
|
227
|
+
- 浏览器不持久化 token、capability、业务响应、流程 token 或表单草稿;只保存有界 UI 偏好和逻辑路由。
|
|
228
|
+
- 标签最多 12 个、保活实例最多 6 个;身份 epoch 切换取消或丢弃旧请求与选择状态。
|
|
229
|
+
- 列表只做服务端分页、排序和有界筛选;图表只消费服务端受限聚合。
|
|
230
|
+
- production bundle 禁止包含模板 Mock、假用户、开发凭据和原始 Secret。
|
|
231
|
+
|
|
232
|
+
### 设计评审与回滚边界
|
|
233
|
+
|
|
234
|
+
本轮形成 3 张独立横向设计基线,见 [Admin Pro v6 设计说明](../design/admin-pro-v6/README.md):工作台、标准数据管理、流程提交 Modal。设计参数为视觉变化 3/10、动效 2/10、信息密度 5/10;实现以 Pro v6 token 和真实浏览器证据为准。首个新包发布前的回滚单位是整个 Admin/模板提交与 AppVersion,不保留旧 Shell 运行时开关。
|
|
235
|
+
|
|
236
|
+
### 可证伪检查
|
|
237
|
+
|
|
238
|
+
1. 空目录新建应用后不存在 Vite、手写路由树、旧 Shell、旧 Admin 源码引用和仪器领域代码;Umi production build 可重复通过。
|
|
239
|
+
2. ProTable、ProForm、ProDescriptions 和 ProLayout 的 API 均来自锁定版本,Ant Design lint、类型检查、单测和 Chromium 验收通过。
|
|
240
|
+
3. 流程提交页面静态审计只有一个主提交动作;审批路径只在 prepare 成功后的 Modal 中出现。
|
|
241
|
+
4. 直接 URL、菜单裁剪、标签恢复和 capability 使用同一生成 manifest;身份切换后旧请求不能回写当前页面。
|
|
242
|
+
5. `openxiangda-admin/src` 与模板 `apps/web/src` 的新实现不存在对被删除前端文件的 import、包装或复制;门禁不通过时只回滚整个绿地提交或候选 AppVersion,不发布半成品。
|
|
243
|
+
|
|
244
|
+
## 12. 2026-08-16 本地 Workflow Kernel 清单驱动决策
|
|
245
|
+
|
|
246
|
+
### 问题证据与能力所有者
|
|
247
|
+
|
|
248
|
+
- 本地平台已经接收编译后的 Workflow Definition、Binding 与 Activation,但准备、发起、条件分支、审批推进、退回、字段策略和参与人校验仍写死为旧“仪器预约”节点。这会让新应用的页面与清单看似正确,而真实提交执行另一套隐藏状态机。
|
|
249
|
+
- Workflow Definition/Binding 是节点、转移、操作、字段策略和审批角色的唯一所有者;Activation 是本地生效版本的唯一所有者;应用 NestJS 是 App API 业务逻辑的唯一所有者。本地平台不得再保存示例领域路由或第二份流程规则。
|
|
250
|
+
|
|
251
|
+
### 稳定不变量与失败语义
|
|
252
|
+
|
|
253
|
+
1. 本地 prepare、start、approve、reject、return、resubmit 与 Surface 全部读取当前 Activation 指向的 Definition/Binding;条件表达式复用 `openxiangda-workflow` 的解释器。
|
|
254
|
+
2. 业务数据继续由 Data API/App API 保存。完整模式的 App API 只代理当前 NestJS;纯前端模式仅提供平台诊断端点,业务接口明确返回不存在,不伪造成功。
|
|
255
|
+
3. 未激活流程、无效节点、不可解析审批角色、不允许的退回目标和并发版本冲突均失败关闭,且不写入一半实例或任务。
|
|
256
|
+
4. 代理、转交与加签仍校验当前节点 Binding 的角色和数据范围;应用管理员仍可按最高授权声明处理任务,但不改变原审批角色事实。
|
|
257
|
+
5. 变更只存在于 OpenXiangda 2.0 本地平台与新模板;1.x 流程、自动化、View 和发布链路没有依赖关系。
|
|
258
|
+
|
|
259
|
+
### 资源、并发与回滚边界
|
|
260
|
+
|
|
261
|
+
- 单次无人工节点解析最多 200 步,沿用 Workflow 编译器的无环校验;准备令牌继续绑定首个审批身份,发起前身份或分派变化必须重新预览。
|
|
262
|
+
- PostgreSQL 模式继续通过版本/CAS、幂等回执和单事务写入实例、任务与时间线;内存模式保持同样的可观察结果。
|
|
263
|
+
- 回滚单位是本地平台包、模板和生成清单的同一候选提交,不保留旧领域分支或兼容开关。
|
|
264
|
+
|
|
265
|
+
### 可证伪验证
|
|
266
|
+
|
|
267
|
+
1. 采购参考流程的低额路径直接进入采购审批,高额或专项复核路径依次进入部门、财务、采购审批;节点、标题与字段策略均与清单一致。
|
|
268
|
+
2. 退回目标只能来自当前审批节点的 `returnTargets`,重提回到原任务节点;非 `sequence` 审批模式不被本地运行时强制改写。
|
|
269
|
+
3. 更换为测试用的另一套节点名称和角色后,本地平台无需改代码即可 prepare/start/approve。
|
|
270
|
+
4. 源码与打包审计不再包含 `reservation-approval`、`college-review`、`instrument-review` 或示例 App API 路由。
|
|
271
|
+
|
|
272
|
+
### 本地代理身份夹具边界
|
|
273
|
+
|
|
274
|
+
- 问题证据:本地 Workflow Kernel 曾在运行时代码中内置“学院管理员/仪器管理员”和固定用户,导致代理、加签与身份切换只对旧示例成立,也让本地平台成为应用角色的第二个定义源。
|
|
275
|
+
- 能力归属:角色 code、名称和能力只由应用 `authz.roles` 声明;`openxiangda.local.json` 仅声明本地外部用户对应哪个既有角色成员身份及其测试范围。
|
|
276
|
+
- 稳定约束:本地代理目标必须引用已声明角色、已声明范围维度和 Directory 中的用户;平台不得生成行业角色或猜测用户授权。
|
|
277
|
+
- 契约:本地夹具新增可选 `workflowDelegationTargets[]`,每项使用稳定 code、userId、roleCode、scopeGrants;其本地 RoleSubject key 由平台确定性派生,不进入应用包或远端环境。
|
|
278
|
+
- 失败与并发:重复 code、未知用户、未知角色或未知范围维度在本地平台启动时立即失败;代理规则的重叠、幂等和版本竞争仍由 Workflow Kernel/PostgreSQL 事务负责。
|
|
279
|
+
- 安全与资源边界:该夹具只在 `local` 环境生效,不产生远端授权;应用超级管理员仍可做本地验收,但不会改变代理目标的正式角色能力。
|
|
280
|
+
- 回滚边界:删除 `workflowDelegationTargets` 只会关闭本地外部代理模拟,不影响清单、业务数据或远端环境;旧的内置行业目标不保留兼容分支。
|
|
281
|
+
- 可证伪验证:通用采购模板可将部门负责人代理给 Directory 用户并完成代理、加签、重启恢复和并发命令验收;运行时代码和打包模板不再出现旧行业角色常量。
|
|
282
|
+
|
|
283
|
+
### 加签参与者完成语义
|
|
284
|
+
|
|
285
|
+
- 问题证据:`any`/`single` 审批模式在用户执行后加签后仍会由原参与者的一次同意直接完成节点,等待中的加签参与者被取消,违背“显式加签必须处理”的用户意图。
|
|
286
|
+
- 能力归属:Workflow Kernel 是参与者队列与审批完成判定的唯一所有者;页面只提交 `add_assignee` 命令并渲染后端返回的参与者状态。
|
|
287
|
+
- 稳定约束:任何处于 `pending` 且 `required` 的参与者都是显式建立的顺序义务;当前参与者通过后必须先激活该参与者,不能被节点的 `single`/`any` 原始审批模式跳过。
|
|
288
|
+
- 失败与并发:参与者推进与任务/实例版本在同一 Workflow 命令事务内 CAS;重复命令走幂等回执,竞争命令只有一个版本胜出。
|
|
289
|
+
- 回滚边界:变更只影响 2.0 Kernel 的参与者完成规划,不修改 1.x 流程,也不增加兼容开关。
|
|
290
|
+
- 可证伪验证:`single`/`any` 节点的前加签和后加签均先推进必需参与者,所有必需参与者完成后才允许节点流转;完整 PostgreSQL 生命周期覆盖代理后加签和重启恢复。
|
|
291
|
+
|
|
292
|
+
## 13. 2026-08-16 候选包与独立参考应用一致性决策
|
|
293
|
+
|
|
294
|
+
### 问题证据与能力所有者
|
|
295
|
+
|
|
296
|
+
- 绿地 Admin 删除旧源码后,候选 tarball 仍包含旧 `dist` 文件;原因是 TypeScript 增量构建不会删除已经失去源码的历史输出。tarball 验证只检查入口存在,无法证明包内没有旧实现。
|
|
297
|
+
- 独立参考应用只更新依赖版本但仍保留旧仪器/预约源码,安装新 Admin 候选后类型检查失败。模板仓库与长期参考应用之间缺少“同代应用源码”约束。
|
|
298
|
+
- 每个公开包自己的 `build/prepack` 是发布字节的唯一所有者;`create-openxiangda` 模板是新建应用结构的唯一所有者;独立参考应用只拥有自身 app code、名称、仓库历史和线上 AppVersion,不另行维护一套框架源码。
|
|
299
|
+
|
|
300
|
+
### 稳定不变量、失败与并发
|
|
301
|
+
|
|
302
|
+
1. 所有公开包必须提供 `build:release`,在完整构建前删除已经没有对应 TypeScript 源文件的孤儿输出,且 `prepack` 必须执行该构建;修剪脚本只允许处理当前仓库 `packages/*/dist` 的文件,路径不匹配立即失败。它不删除仍有源码的当前输出,避免另一个 Turbo 任务或本地消费者在打包窗口读不到依赖类型。
|
|
303
|
+
2. 新建应用验收与独立参考应用验收使用同一组不可变候选 tarball。新建应用证明模板完整,独立应用证明真实仓库、锁文件与升级/部署链路完整。
|
|
304
|
+
3. Admin/模板发生绿地代际切换时,参考应用必须从当前模板重新生成并只保留自己的身份和业务增量;禁止靠兼容导出让旧示例继续编译。
|
|
305
|
+
4. 版本、参考应用源码或 lockfile 任一不一致时 release plan 失败关闭;不得发布部分包或让 registry tag 指向混合版本。
|
|
306
|
+
5. 同一候选的普通 build/check 与其他包的 release-build 可以并行;release-build 只修剪自己包内的孤儿文件,不制造当前入口缺失窗口。发布仍由单一 release plan 串行提交 registry tag,避免不同会话覆盖候选字节。
|
|
307
|
+
|
|
308
|
+
### 安全、资源与回滚边界
|
|
309
|
+
|
|
310
|
+
- 清理范围固定为直接包工作区下的 `dist`,不接受参数、环境变量、通配符或仓库根目录;不会接触源码、用户数据和 1.x 工件。
|
|
311
|
+
- 独立参考应用的绿地同步只删除其 Git 可恢复的旧 2.0 示例源码,不保留运行时兼容开关;线上回滚仍以最后一个健康 AppVersion 为单位。
|
|
312
|
+
- 回滚工具链时回滚构建不变量提交和对应 alpha 版本;参考应用可以从 Git 历史恢复上一提交。1.x 应用、流程、自动化和发布链路不在影响范围。
|
|
313
|
+
|
|
314
|
+
### 可证伪验证
|
|
315
|
+
|
|
316
|
+
1. 先构建含已删除源码的包,再执行 `pnpm pack`,tarball 中不存在对应历史 `dist` 文件。
|
|
317
|
+
2. 工作区编排门禁枚举所有公开包,缺少独立 release-build 或 prune-before-pack 任一约束即失败;并行 affected gate 中 pack 不会删除下游正在读取的当前输出。
|
|
318
|
+
3. 从候选 tarball 新建空目录应用以及绿地同步后的独立参考应用均通过 generate/check/test/build;旧 `ApplicationShell`、仪器和预约源码不再存在。
|
|
319
|
+
4. release plan 只在参考应用 manifest 与全部公开包候选版本完全一致时生成;正式发布前重新校验 lockfile 与 registry 工件一致。
|
|
320
|
+
5. 参考验收调用标准 CLI 命令而不要求应用增加仓库私有的 generate 脚本;显式安装候选到参考工作树时先写入一次生成契约,后续隔离副本和普通发布验收只允许 `generate --check`。生成模板必须从 Git 与 OCI 构建上下文排除 `.codegraph`、`.openxiangda`、`.env` 等本地状态。
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
状态:方案已确认并按 Native 实施顺序推进。2026-08-15 已完成 E4 运行时闭环:应用身份和预发/生产原生环境成对创建、Native DeploymentRun、按 run 隔离的候选 workload、`pending -> active -> retiring -> revoked` 运行凭据、凭据与 Head CAS 同事务激活、旧 token 随 Head 变化立即失效;App Gateway 使用最长 60 秒 invocation token + 最长 30 秒 Ed25519 请求 assertion,官方 NestJS 全局 transport guard 绑定当前 Native Head 与完整 HTTP 请求,本地平台使用同构协议且拒绝重放。单体 Nest 的后台消费由短租约选出一个活动实例,应用 Secret 只允许当前 Head 身份按声明读取,terminal/cancelled/超时候选由精确 GC 回收,`alpha -> native-2` 切换必须通过全平台实例 release/capability 门禁。Native production 仍须完成后续 E5 和真实预发 E2E 后再开放。
|
|
4
4
|
|
|
5
|
+
生命周期修订:2026-08-16 已确认新应用默认只创建预发环境,正式环境在首次明确发布时惰性创建。本文中“provision 成对创建预发/生产”的既有实现描述由[按需正式环境](./on-demand-production-environment-v2.md)取代;环境隔离、不可变 AppVersion、Head CAS 和预发/正式运行态分离等不变量保持不变。
|
|
6
|
+
|
|
5
7
|
## 1. 决策摘要
|
|
6
8
|
|
|
7
9
|
OpenXiangda 2.0 的运行语义采用三层模型:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# OpenXiangda 2.0 实施路线图与证据矩阵
|
|
2
2
|
|
|
3
|
-
状态日期:2026-08-
|
|
3
|
+
状态日期:2026-08-16
|
|
4
4
|
|
|
5
5
|
本文只记录可由源码、自动测试、真实 HTTP、新应用黑盒或已发布工件证明的状态。文档存在不等于运行时完成,Mock 通过不等于平台集成完成,npm 已发布也不等于某个应用已经部署。
|
|
6
6
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
| --- | --- |
|
|
11
11
|
| 已交付 | 平台/工具链实现、正式门禁和独立应用证据均闭环 |
|
|
12
12
|
| 已实现待晋级 | 代码与门禁已通过,但尚未作为目标 AppVersion 晋级指定环境 |
|
|
13
|
+
| 已确认待实施 | 架构决策已经确认,运行时尚未按新方案完成,不能对外宣称交付 |
|
|
13
14
|
| 已设计待确认 | 所有权、不变量、契约、失败恢复和验收矩阵已形成;根据架构门禁,确认前不修改运行时 |
|
|
14
15
|
| 未开始 | 尚无可以进入实现的确认设计 |
|
|
15
16
|
|
|
@@ -30,19 +31,19 @@
|
|
|
30
31
|
| 确定性工具链发布 | Changesets 版本提交、冻结工件清单、release receipt | 已交付 | 待消费 Changeset 在构建前 fail-fast;版本只由 Changesets 物化;正式发布只验证一次同一批 tarball;CLI alpha.20 与 skill-kit alpha.19 已按该状态机发布并打 Git tag | 周期性全量审计保留;不得恢复人工选包、手工版本或重复正式门禁 |
|
|
31
32
|
| 环境配置内核 E0-E6 | AppVersion/component revision + native Runtime Environment + minimal Environment Head + 环境运行态 | E1-C0/C1/S0/S1/T0 已完成 | breaking config/contracts v3、平台纯编译器、六领域不可变投影、聚合投影、AppVersion binding、compile receipt、精确 artifact shadow prepare 与真实 PostgreSQL 并发/来源防伪/绑定后不可变已经通过;全新 `openxiangda-v2-native-reference-app` 由候选 tarball 创建并完成 check/test/build,连续构建逐字节一致,config/contract v3 闭包和 artifact/manifest 篡改拒绝已进入发布门禁 | 下一步进入 A0 Native 环境授权;随后实现 Data physical/logical、最小 Head CAS、pending credential、调用委托/网关断言、runtime lease、候选 GC 与 generation cutover。旧 alpha 只留审计历史,不做双读、双写或导入 |
|
|
32
33
|
| 授权内核 A0-N/C/P | 不可变 authz revision + 环境 authz state + native role/scope 表 | 已确认实施;N0/N1/N2/C1/C2/P 完成 | N1/C1 建立不可变定义、两环境 state 与原子版本;N2 建立独立 Native 运行表与局部撤权;C2 建立 DB-authoritative evaluator、request cache、环境/版本 cache namespace、边界 TTL 与 RelationshipGrant 直读;P 升级 `native-2` 配置契约并建立 source definition、projection state/job/receipt/value/closure/effective grant、Data API 与 membership 原子失效、冷启动恢复与 strict gate;89 个 SQL migration 校验、35 个 2.0 migration 真实 PostgreSQL 幂等应用、39 个平台套件 / 263 项测试和工具链全 workspace 测试通过 | 当前推进 N3-N5。alpha membership/grant 不复制、不迁移,禁止给 legacy 表补 environmentKey 或建立长期双读/双写 |
|
|
33
|
-
|
|
|
34
|
+
| Ant Design Pro v6 Admin 全量切换 | Ant Design Pro v6 承担通用 Admin;`openxiangda-admin` 承担平台集成 | 已实现待发布 | Vite/旧自研 Shell 与仪器示例已从模板删除;React 19、Ant Design 6、Umi Max 4、ProComponents 3、utoopack、ProLayout、ProTable、ProForm、Field Kit 和企业采购参考应用已落地。桌面 Chromium 单链路通过工作台、菜单、会话标签、稳定角色切换、列表/详情、独立供应商表单、工作中心、单按钮流程提交和个人中心,并断言无运行时错误;production build 通过 420KB gzip/1.5MB raw 异步块与 1.5MB 首屏门禁 | 补 Changesets、`verify:affected` 和正式包发布;随后以已发布 tarball 创建仓库外新应用并完成 preproduction→production 在线验收。移动用户端 Field Kit 已有独立 renderer,完整移动页面模板与设备 Chromium 验收另列下一阶段 |
|
|
34
35
|
| Admin A1 RoleSession 上下文 | Native RoleSession bootstrap 是唯一身份资料/role subject/scope 来源 | 已设计待确认 | SubjectProfile 字段白名单、tenant 联合查询、非 active scope=null、capability=`authz.role-session-context`、有界 role subject 分页与切换 CAS 已定义 | A0 native cutover 后实现;A1 自身不再增加身份存储,但不得建立在 alpha 全局 assignment 上;平台先发,工具链后要求 capability |
|
|
35
36
|
| Admin B0-O 租户公共 Origin | Platform Server Origin module + 版本/head/hostname claim registry | 已设计待确认 | 全仓确认多套模糊解析和广泛 URL 调用者;prod-1 证实 HTTPS/HTTP 配置差异、未登记 vhost 别名,且生产 `default_configs` 没有源码宣称的复合唯一约束;稳定租户 UUID、不可变 staged→challenge→verified→active、head revision CAS、hostname claim、事务审计、全局兼容阶段+单租户事实源状态、无长期双写和[逐文件实施蓝图](./tenant-public-origin-implementation-blueprint.md)已定义 | 确认后先做 O0 只读 inventory/digest 与 plan validator;操作者显式决定 migrate/decommission,所有服务实例同版后进入 migrating,再逐租户冻结/验证/切换,单租户失败不阻塞全平台;B0-R 不得绕过该阶段 |
|
|
36
37
|
| Admin B0-C Cookie 安全 | Platform Server `AuthCookieService` + 无状态 policy resolver | 已设计待确认 | 已确认当前 DOMAIN JSON 同时决定 Cookie Domain 且 `secure:false`;共享会话/协议 Cookie 所有权、HTTPS Secure/`__Host-`/host-only、版本化名称、legacy scope manifest、C0/C1/C2 状态机和旧 host retirement 已定义 | B0-O registry 稳定后独立实现;首期不支持跨子域共享;C1 后只能回滚到理解 v2 Cookie 的兼容镜像,不和 Origin 数据迁移、return target 或 OAuth state 混发 |
|
|
37
38
|
| Admin B0-R 登录 return target 安全 | 平台通用登录代理和服务端 CAS 校验 | 已设计待确认 | 全仓审计确认平台、1.x View、流程、旧编辑器和 CLI 合法生产者均可归入同源;一次解析、8 KiB 上限、精确 origin、CAS 双阶段规范化、错误链路 fail closed 及回归向量已定义 | 明确确认后作为独立平台安全提交,不和 Shell 改造、OAuth state 或身份协议混发 |
|
|
38
39
|
| 旧平台第三方认证 S0 | Platform Server 一次性 OAuth state 与 purpose 绑定 | 未开始 | 已证明旧登录 state 仅为 tenantId、回调未消费 state,账号绑定指向未注册 `/bind-callback` 且 tenantId 为空 | 先单独形成登录/绑定事务、TTL、一次性消费和迁移设计;不得把它混入 B0-R,也不重做 2.0 Client Credentials/App Auth |
|
|
39
|
-
| Admin
|
|
40
|
+
| Admin 既有协议迁移输入 | `openxiangda-admin` 平台适配层与显式可选 contribution | 已实现,待迁入 Pro v6 | anyOf/allOf、manifest 闭包、直接 URL 403、独立数据表单/详情、资源级失效、工作中心服务端分页、DirtyStateRegistry、12 标签/6 keepAlive LRU、identityScope/epoch 隔离、个人中心贡献化和 Core-only Workflow 负向证明已有测试证据 | 保留协议和并发不变量,删除旧 UI 与重复通用组件;不得为旧组件 API 建兼容层,也不得引入临时全局状态、角色名判断、未绑定环境的缓存键或第二套查询 DSL |
|
|
40
41
|
|
|
41
42
|
## 3. 当前关键路径
|
|
42
43
|
|
|
43
44
|
```mermaid
|
|
44
45
|
flowchart LR
|
|
45
|
-
Audit["B0-R 全仓生产者审计(已完成)"] --> Confirm["确认 Admin
|
|
46
|
+
Audit["B0-R 全仓生产者审计(已完成)"] --> Confirm["确认 Admin 平台边界"]
|
|
46
47
|
Confirm --> CP["CP0/CP1 alpha 退役 preflight"]
|
|
47
48
|
CP --> E1["E1 Native config/contracts v3"]
|
|
48
49
|
E1 --> T0["E1-T0 全新 Native reference(已完成)"]
|
|
@@ -56,21 +57,18 @@ flowchart LR
|
|
|
56
57
|
B0O --> B0["B0-R 平台 return target 收敛"]
|
|
57
58
|
B0O --> B0C["B0-C Cookie 安全迁移"]
|
|
58
59
|
A1 --> A2["A2 identityScope / epoch"]
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
A2 --> D["D Data Workbench controller"]
|
|
60
|
+
A2 --> Pro6["Ant Design Pro v6 全量切换"]
|
|
61
|
+
B0 --> Pro6
|
|
62
|
+
Pro6 --> Pages["ProTable / ProForm / Workflow Surface"]
|
|
63
|
+
Pro6 --> Life["标签 / 有界 keepAlive / 个人中心"]
|
|
64
64
|
B0C --> Fresh["完整新应用 Chromium 验收"]
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
C --> Fresh
|
|
68
|
-
D --> Fresh
|
|
65
|
+
Pages --> Fresh
|
|
66
|
+
Life --> Fresh
|
|
69
67
|
Fresh --> Release["Changesets 物化与单次正式发布"]
|
|
70
68
|
Release --> Promote["同一 AppVersion 预发/正式晋级"]
|
|
71
69
|
```
|
|
72
70
|
|
|
73
|
-
|
|
71
|
+
当前产品缺陷与上游兼容性已经构成重写 Admin 表现层的证据,因此采用 [Ant Design Pro v6 全量切换](./ant-design-pro-v6-admin-foundation.md);这不等于重写 OAuth2、Secret、Events、Workflow、RoleSession、DataQuery 或环境内核。平台数据/授权轨仍按 CP0/CP1、E1/A0/E4 与 Native generation 边界推进;具体隔离与退役合同见[Alpha 退役与 Native 切换前置审计](./native-kernel-inventory-v2.md),bundle v3、最小 Head、不可变投影和激活事务边界见[原生配置投影蓝图](./native-configuration-projection-v2.md)。安全轨从 B0-O0/O1 开始;新 Pro Shell 的安全退出仍等待 B0-R,完整生产晋级同时通过 B0-C。不能为了页面迁移先改缓存、角色判断、登录跳转或给 legacy 表临时加环境分支。
|
|
74
72
|
|
|
75
73
|
## 4. 每轮执行记录要求
|
|
76
74
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
状态:L0-L3 已实现,并由打包工具链创建的全新应用在真实 PostgreSQL 上验证;本轮补齐可审计的 status/stop/reset 生命周期控制
|
|
4
4
|
|
|
5
|
+
> 2026-08-16 架构修订:Admin 前端目标工具链已[全量切换到 Ant Design Pro v6 / Umi Max](./ant-design-pro-v6-admin-foundation.md)。本文出现的 Vite 只描述切换前已实现证据;迁移后由 Umi 开发服务接替页面与 HMR,本地平台、真实 PostgreSQL、NestJS、生命周期与安全边界保持不变。
|
|
6
|
+
|
|
5
7
|
## 1. 产品结论
|
|
6
8
|
|
|
7
9
|
开发者在新建应用后只需要运行:
|
|
@@ -10,7 +12,7 @@
|
|
|
10
12
|
openxiangda dev
|
|
11
13
|
```
|
|
12
14
|
|
|
13
|
-
命令打开完整 Admin 应用并同时启动 React/
|
|
15
|
+
命令打开完整 Admin 应用并同时启动 React/Umi Max、NestJS 和本地平台服务。前端、后端、生成契约和应用声明支持有界热更新;开发者不需要先 provision、登录远程平台或创建第三个远程环境。
|
|
14
16
|
|
|
15
17
|
远程部署环境只有 `preproduction`、`production`。`local` 是进程运行模式,不是 environment registry 记录:
|
|
16
18
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# OpenXiangda 2.0 按需正式环境
|
|
2
|
+
|
|
3
|
+
状态:2026-08-16 已确认,作为 2.0 新应用的目标生命周期。尚未实现。
|
|
4
|
+
|
|
5
|
+
## 问题证据
|
|
6
|
+
|
|
7
|
+
当前 `app provision` 会同时创建预发和正式环境,参考应用部署后也容易同时保留两套后端工作负载。大多数 2.0 应用长期处于开发或试验阶段,不会正式投入使用。提前创建正式环境、运行凭据、环境状态和 Kubernetes 工作负载没有业务价值,还会增加资源占用、运维噪音和发布失败面。
|
|
8
|
+
|
|
9
|
+
## 能力归属
|
|
10
|
+
|
|
11
|
+
- 应用身份、环境注册、DeploymentRun、环境 Head 和运行期启停状态由平台控制面唯一拥有。
|
|
12
|
+
- Git 仓库和 AppPackage 只拥有源码、声明与不可变 AppVersion,不保存环境是否已创建或正在运行的事实。
|
|
13
|
+
- CLI、MCP、AI 和 Admin 管理端只是控制面客户端,不自行推导或补写正式环境。
|
|
14
|
+
|
|
15
|
+
## 决策
|
|
16
|
+
|
|
17
|
+
一个 2.0 逻辑应用默认只创建稳定的 `preproduction` 环境。`production` 是可选的长期环境,仅在开发者首次执行明确的“发布正式版”操作时惰性创建。
|
|
18
|
+
|
|
19
|
+
1. `app provision` 幂等创建应用身份、应用最高管理员授权和预发环境,不创建正式环境。
|
|
20
|
+
2. 日常 `deploy` 只向预发部署新的不可变 AppVersion。
|
|
21
|
+
3. 首次 `release production` 选择一个已在预发成功运行的 AppVersion,创建正式环境并把同一个 AppVersion 发布到正式环境。发布过程不重新构建制品。
|
|
22
|
+
4. 后续 `release production` 复用已有正式环境,只更新其环境 Head。
|
|
23
|
+
5. 预发和正式工作负载均支持显式启动、停止。停止只把期望运行副本降为零,不删除环境、业务数据、审计、Secret 元数据或历史 DeploymentRun。
|
|
24
|
+
6. 从未正式发布的应用永远没有正式环境、正式 RoleSession、正式 OAuth/Secret 运行态或正式后端 Pod。
|
|
25
|
+
|
|
26
|
+
## 稳定不变量
|
|
27
|
+
|
|
28
|
+
- 一个应用始终恰好有一个预发环境,最多有一个正式环境;环境 key 创建后不可改。
|
|
29
|
+
- 同一个 AppVersion 从预发发布到正式,前端、后端镜像、配置和数据契约摘要保持完全一致。
|
|
30
|
+
- 预发与正式的业务数据、角色成员、范围授权、OAuth 客户端、Secret 值、Workflow 实例和 Event receipt 相互独立。
|
|
31
|
+
- 首次正式发布不复制预发业务数据。需要初始化数据时使用应用明确声明、可审计且可重试的 seed/import 操作。
|
|
32
|
+
- 环境不存在、环境已停止和环境发布失败是三种不同状态,网关和管理端必须返回可区分的结果。
|
|
33
|
+
- 1.x 应用、流程、自动化和既有发布模型不读取也不写入该生命周期。
|
|
34
|
+
|
|
35
|
+
## 控制面契约
|
|
36
|
+
|
|
37
|
+
| 操作 | 结果 |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `app provision` | 创建应用身份和预发环境 |
|
|
40
|
+
| `deploy preproduction` | 构建或提交 AppPackage,并把候选 AppVersion 部署到预发 |
|
|
41
|
+
| `environment start/stop preproduction` | 启停预发工作负载,环境事实保持不变 |
|
|
42
|
+
| `release production` | 首次惰性创建正式环境,或复用已有正式环境,发布预发验证过的同一 AppVersion |
|
|
43
|
+
| `environment start/stop production` | 显式启停正式工作负载,不删除正式环境 |
|
|
44
|
+
|
|
45
|
+
管理端应用列表至少显示“仅预发、预发运行中、预发已停止、正式发布中、已发布、正式发布失败”,并提供与状态匹配的确定性操作。普通用户页面不展示环境 UUID、AppVersion ID、workflow code 或内部错误码;这些信息只进入应用管理员诊断面板。
|
|
46
|
+
|
|
47
|
+
## 失败与并发
|
|
48
|
+
|
|
49
|
+
- 首次正式发布使用稳定 operation/idempotency key,并以 `tenant + app + production` 唯一约束防止双击或并发会话创建两个正式环境。
|
|
50
|
+
- 发布先验证源 DeploymentRun、AppVersion 摘要、平台 capability、必需 Secret 和集群资源,再创建 Kubernetes 工作负载。
|
|
51
|
+
- 数据库注册与 Kubernetes 就绪不能伪装成一个跨系统事务。正式环境先进入 `provisioning`,只有候选工作负载通过 readiness 后,才在一个数据库事务中激活环境 Head 和发布成功状态。
|
|
52
|
+
- 候选失败时不产生正式活动 Head,不影响预发,也不覆盖既有正式版本。首次失败可以保留同一个正式环境身份和失败记录,重试继续使用该身份。
|
|
53
|
+
- 资源不足必须在创建 Pod 前返回明确的 CPU、内存或配额诊断,不能停留在无提示的 Pending。
|
|
54
|
+
|
|
55
|
+
## 资源边界
|
|
56
|
+
|
|
57
|
+
| 应用状态 | 默认运行后端数 |
|
|
58
|
+
|---|---:|
|
|
59
|
+
| 预发已停止且从未发布 | 0 |
|
|
60
|
+
| 正在预发验证 | 1 |
|
|
61
|
+
| 已发布且预发已停止 | 1 |
|
|
62
|
+
| 正式运行并同时进行预发验证 | 临时 2 |
|
|
63
|
+
|
|
64
|
+
平台可以为长期未访问的预发应用提供自动停止策略,但不能自动删除环境或业务数据。正式环境不做自动停止,除非开发者明确配置。
|
|
65
|
+
|
|
66
|
+
## 回滚边界
|
|
67
|
+
|
|
68
|
+
- 该变化只调整 2.0 新应用的环境创建时机和控制面命令语义,不删除已经存在的正式环境。
|
|
69
|
+
- 已有双环境 2.0 测试应用可以继续运行,后续通过显式清理任务停止或删除无用的正式工作负载。
|
|
70
|
+
- 实现阶段必须采用可独立回滚的数据库和 API 变更;回滚时允许恢复“provision 同时创建两环境”的旧行为,但不得删除惰性创建后产生的正式环境事实。
|
|
71
|
+
|
|
72
|
+
## 可证伪验收
|
|
73
|
+
|
|
74
|
+
1. 新应用执行 `app provision` 后,数据库和控制面查询只返回预发环境,Kubernetes 中没有正式 Deployment 或 Pod。
|
|
75
|
+
2. 预发部署成功后首次执行 `release production`,平台创建唯一正式环境,并发布与预发完全相同摘要的 AppVersion。
|
|
76
|
+
3. 并发执行两次首次正式发布,只能产生一个正式环境和一个活动 Head;另一个请求幂等复用或返回稳定冲突。
|
|
77
|
+
4. 首次发布因资源不足或 readiness 失败时,预发 Head 不变化,正式环境没有活动 Head,也没有残留运行 Pod。
|
|
78
|
+
5. 停止预发后副本数为零,再次启动恢复相同环境和活动版本。
|
|
79
|
+
6. 1.x 发布、流程和自动化回归测试结果不受影响。
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
1. 提交与 PR 使用 `pnpm verify:affected`,只运行受影响包及其依赖任务。
|
|
24
24
|
2. 已评审 Changesets 先由 `pnpm release:version` 在干净且已同步远端的 `master` 上物化;人工只审核生成的版本、内部依赖与模板 BOM,不手改版本。版本 diff 必须提交并推送后才成为候选源码事实。
|
|
25
25
|
3. 发布候选运行 `pnpm release:plan`,由真实候选 tarball 差异和包依赖图确定门禁;待消费 Changesets 未物化时在任何构建前失败。
|
|
26
|
-
4. `pnpm release:publish` 从干净的远端 `master` 生成一次带摘要的候选工件清单;候选安装、reference 验证和 npm publish 复用相同 tarball
|
|
26
|
+
4. `pnpm release:publish` 从干净的远端 `master` 生成一次带摘要的候选工件清单;候选安装、reference 验证和 npm publish 复用相同 tarball,禁止重新打包,并且只执行一次正式验证。公开 registry 确认收到相同 tarball 后,发布命令会从公开包自动同步 reference 仓库锁文件并执行 frozen install;锁文件不再从发布前的临时 registry 生成。`pnpm verify:release` 只用于需要提前获得无发布验收证据的演练,不是正式发布前必须重复执行的步骤。
|
|
27
27
|
从源码创建候选 tarball 前,制品入口按候选包及其 workspace 依赖统一执行一次 Turbo 增量构建;不能直接打包工作区里可能过期的 `dist`。如果输入已经是带摘要的 release artifact manifest,则跳过构建并只消费冻结制品。
|
|
28
28
|
5. 每次候选都在全新独立项目安装真实 tarball 并完成 generate/check/test/build;浏览器相关变化再执行完整 Chromium E2E。
|
|
29
29
|
6. 平台集成测试部署到测试环境;只有平台协议或部署能力变更才需要阻塞核心发布。
|
|
@@ -43,6 +43,7 @@ reviewed Changesets
|
|
|
43
43
|
-> deterministic affected validation plan
|
|
44
44
|
-> candidate closure + independent tarball verification
|
|
45
45
|
-> npm publish of the exact validated tarballs
|
|
46
|
+
-> published reference lock synchronization + frozen install
|
|
46
47
|
-> independent-project acceptance
|
|
47
48
|
-> immutable promotion
|
|
48
49
|
```
|