openxiangda-skill-kit 2.0.0-alpha.39 → 2.0.0-alpha.47

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.
Files changed (102) hide show
  1. package/README.md +4 -6
  2. package/dist/bin.js +0 -0
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +74 -43
  6. package/dist/index.js.map +1 -1
  7. package/dist/internal/skill-installer.d.ts +9 -0
  8. package/dist/internal/skill-installer.d.ts.map +1 -0
  9. package/dist/internal/skill-installer.js +53 -0
  10. package/dist/internal/skill-installer.js.map +1 -0
  11. package/package.json +2 -6
  12. package/skills/manifest.json +2 -32
  13. package/skills/openxiangda-v2/SKILL.md +11 -42
  14. package/skills/openxiangda-v2/references/architecture.md +5 -0
  15. package/skills/openxiangda-v2/references/backend.md +5 -0
  16. package/skills/openxiangda-v2/references/data-authz.md +5 -0
  17. package/skills/openxiangda-v2/references/delivery.md +11 -0
  18. package/skills/openxiangda-v2/references/frontend.md +5 -0
  19. package/docs/architecture/admin-shell-v2.md +0 -1030
  20. package/docs/architecture/ant-design-pro-v6-admin-foundation.md +0 -343
  21. package/docs/architecture/app-api-user-delegation-v2.md +0 -40
  22. package/docs/architecture/authorization-consistency-v2.md +0 -419
  23. package/docs/architecture/best-practice-template-rebuild-v2.md +0 -206
  24. package/docs/architecture/environment-configuration-kernel-v2.md +0 -290
  25. package/docs/architecture/field-component-migration-matrix-v1-to-v2.md +0 -76
  26. package/docs/architecture/field-value-contract-boundary.md +0 -92
  27. package/docs/architecture/frontend-runtime-mount-v2.md +0 -82
  28. package/docs/architecture/implementation-roadmap.md +0 -79
  29. package/docs/architecture/local-development-v2.md +0 -136
  30. package/docs/architecture/mobile-user-standard-pages-v2.md +0 -88
  31. package/docs/architecture/native-configuration-projection-v2.md +0 -488
  32. package/docs/architecture/native-kernel-inventory-v2.md +0 -196
  33. package/docs/architecture/native-managed-files-v2.md +0 -18
  34. package/docs/architecture/on-demand-production-environment-v2.md +0 -102
  35. package/docs/architecture/proven-field-components-and-standard-surfaces-v2.md +0 -133
  36. package/docs/architecture/release-verification-receipt-v2.md +0 -72
  37. package/docs/architecture/repository-and-release.md +0 -65
  38. package/docs/architecture/school-contact-default-access-v2.md +0 -13
  39. package/docs/architecture/stable-field-protocol-adoption.md +0 -174
  40. package/docs/architecture/standard-surface-runtime-corrections-v2.md +0 -108
  41. package/docs/architecture/tenant-public-origin-implementation-blueprint.md +0 -484
  42. package/docs/architecture/tenant-public-origin-v2.md +0 -236
  43. package/docs/architecture/verification-orchestration-v2.md +0 -24
  44. package/docs/backend.md +0 -102
  45. package/docs/concepts.md +0 -34
  46. package/docs/data-authz.md +0 -127
  47. package/docs/delivery.md +0 -77
  48. package/docs/design/admin/README.md +0 -124
  49. package/docs/design/admin/data-management-v1.png +0 -0
  50. package/docs/design/admin/workbench-v1.png +0 -0
  51. package/docs/design/admin/workflow-detail-v1.png +0 -0
  52. package/docs/design/admin-pro-v6/README.md +0 -26
  53. package/docs/design/admin-pro-v6/data-management.png +0 -0
  54. package/docs/design/admin-pro-v6/workbench.png +0 -0
  55. package/docs/design/admin-pro-v6/workflow-submit-modal.png +0 -0
  56. package/docs/design/admin-shell-dashboard-v2.png +0 -0
  57. package/docs/design/admin-standard-pages-v2.png +0 -0
  58. package/docs/design/admin-v2/README.md +0 -60
  59. package/docs/design/admin-v2/data-management.png +0 -0
  60. package/docs/design/admin-v2/form-detail.png +0 -0
  61. package/docs/design/admin-v2/form-submit.png +0 -0
  62. package/docs/design/admin-v2/workbench.png +0 -0
  63. package/docs/design/admin-v2/workflow-detail.png +0 -0
  64. package/docs/design/admin-v2/workflow-submit.png +0 -0
  65. package/docs/design/openxiangda-2.0-high-fidelity/README.md +0 -293
  66. package/docs/design/openxiangda-2.0-high-fidelity/admin-component-acceptance.png +0 -0
  67. package/docs/design/openxiangda-2.0-high-fidelity/admin-data-form.png +0 -0
  68. package/docs/design/openxiangda-2.0-high-fidelity/admin-workbench.png +0 -0
  69. package/docs/design/openxiangda-2.0-high-fidelity/mobile-approval-preview.png +0 -0
  70. package/docs/design/openxiangda-2.0-high-fidelity/mobile-data-list.png +0 -0
  71. package/docs/design/openxiangda-2.0-high-fidelity/mobile-form.png +0 -0
  72. package/docs/design/openxiangda-2.0-high-fidelity/mobile-request-form.png +0 -0
  73. package/docs/design/openxiangda-2.0-high-fidelity/mobile-request-list.png +0 -0
  74. package/docs/design/openxiangda-2.0-high-fidelity/mobile-submit-workflow-preflight.png +0 -0
  75. package/docs/design/openxiangda-2.0-high-fidelity/mobile-workbench.png +0 -0
  76. package/docs/design/openxiangda-2.0-high-fidelity/mobile-workflow-detail.png +0 -0
  77. package/docs/design/openxiangda-2.0-high-fidelity/user-pc-data-list.png +0 -0
  78. package/docs/design/openxiangda-2.0-high-fidelity/user-pc-form-workflow-preview.png +0 -0
  79. package/docs/design/openxiangda-2.0-high-fidelity/user-pc-request-form-approval.png +0 -0
  80. package/docs/design/openxiangda-2.0-high-fidelity/user-pc-request-list.png +0 -0
  81. package/docs/design/openxiangda-2.0-high-fidelity/user-pc-workbench.png +0 -0
  82. package/docs/field-components.md +0 -93
  83. package/docs/frontend.md +0 -78
  84. package/docs/getting-started.md +0 -148
  85. package/docs/index.md +0 -27
  86. package/docs/llms.txt +0 -20
  87. package/docs/reference/cli.md +0 -69
  88. package/docs/reference/mcp.md +0 -31
  89. package/docs/school-contact-relations.md +0 -136
  90. package/docs/workflow-events.md +0 -86
  91. package/skills/openxiangda-v2-architecture/SKILL.md +0 -30
  92. package/skills/openxiangda-v2-architecture/agents/openai.yaml +0 -4
  93. package/skills/openxiangda-v2-backend/SKILL.md +0 -48
  94. package/skills/openxiangda-v2-backend/agents/openai.yaml +0 -4
  95. package/skills/openxiangda-v2-data-authz/SKILL.md +0 -58
  96. package/skills/openxiangda-v2-data-authz/agents/openai.yaml +0 -4
  97. package/skills/openxiangda-v2-delivery/SKILL.md +0 -88
  98. package/skills/openxiangda-v2-delivery/agents/openai.yaml +0 -4
  99. package/skills/openxiangda-v2-frontend/SKILL.md +0 -50
  100. package/skills/openxiangda-v2-frontend/agents/openai.yaml +0 -4
  101. package/skills/openxiangda-v2-workflow-events/SKILL.md +0 -56
  102. package/skills/openxiangda-v2-workflow-events/agents/openai.yaml +0 -4
@@ -1,92 +0,0 @@
1
- # 稳定字段值合同与 UI 依赖边界
2
-
3
- 状态:2026-08-16 已实现待发布
4
-
5
- 本决策是[稳定字段数据协议采用与声明分层决策](./stable-field-protocol-adoption.md)的实现收口,只调整 OpenXiangda 2.0 包所有权和应用依赖图,不改变字段值、数据库、Data API 或 1.x 运行时协议。
6
-
7
- ## 1. 问题证据
8
-
9
- 独立参考应用的 NestJS 后端只从 `@app/domain` 导入 `PurchaseRequestRecord` 类型,但当前依赖链为:
10
-
11
- ```text
12
- @app/server
13
- -> @app/domain
14
- -> openxiangda-field-kit
15
- -> antd
16
- -> antd-mobile
17
- -> React peer/runtime dependency tree
18
- ```
19
-
20
- `pnpm --filter @app/server deploy --prod --legacy` 实测生成约 253MB、195 个生产包,并报告 `antd-mobile`/React peer 依赖。`@app/domain` 使用 Field Kit 的唯一原因是三个稳定值 TypeScript 类型;后端不渲染任何组件,也不执行 Field Kit codec。
21
-
22
- 这不仅增加镜像构建、传输、解压和漏洞扫描成本,也违反已确认的不变量:稳定字段值协议必须是不依赖 React 的跨前后端共享合同。
23
-
24
- ## 2. 能力所有者
25
-
26
- | 能力 | 唯一所有者 |
27
- | --- | --- |
28
- | 稳定字段值形状 | `openxiangda-contracts` |
29
- | DataResource、Data API 与工作流跨进程合同 | `openxiangda-contracts` |
30
- | 值归一化、格式化和平台文件/组织控制器 | `openxiangda-field-kit` |
31
- | Desktop/Mobile/Readonly/List/Detail renderer | `openxiangda-field-kit` |
32
- | 应用业务记录与输入类型 | 应用 `packages/domain`,只组合 contracts 类型 |
33
- | NestJS DTO、业务校验和写入 | 应用 `apps/server` |
34
-
35
- `openxiangda-contracts` 不依赖 Field Kit、React、Ant Design、浏览器 API 或 Node 专属运行时。Field Kit 可以从 contracts 导入并重新导出稳定值类型,方便 UI 代码使用,但不能成为这些类型的事实源。
36
-
37
- ## 3. 稳定不变量与受影响合同
38
-
39
- 以下值形状原样移动,不改字段名、可选性或语义:
40
-
41
- - `StableOptionValue`
42
- - `AttachmentVariant`
43
- - `StableAttachmentValue`
44
- - `StableAddressValue`
45
- - `StableLocationValue`
46
-
47
- 受影响的公开面只有 TypeScript 导出所有权:
48
-
49
- 1. `openxiangda-contracts` 根入口和 `/browser` 入口新增上述类型。
50
- 2. `openxiangda-field-kit` 继续重新导出上述类型,现有前端源码无需迁移才能工作。
51
- 3. 官方模板和参考应用的 `@app/domain` 改从 `openxiangda-contracts/browser` 导入,并删除对 Field Kit 的生产依赖。
52
- 4. Web 应用仍直接依赖 Field Kit,并继续使用其 Desktop/Mobile 组件、codec、附件与平台数据能力。
53
- 5. 官方 NestJS Dockerfile 只安装 `@app/server...` 的 workspace 闭包,并在复制源码前禁用 lifecycle script;源码复制后显式执行所选 workspace 的 build,再以已构建产物生成生产目录。前端源码可以仍在 Git 仓库中,但不进入后端依赖安装和构建步骤。
54
-
55
- 数据库物理类型、JSONB 形状、查询运算符、索引、Data API 请求、业务 API、AppPackage schema 和平台部署合同均不变化。
56
-
57
- ## 4. 失败、并发与安全边界
58
-
59
- - 这是编译期所有权迁移,不新增并发状态、缓存、迁移表或运行时分支。
60
- - contracts 与 Field Kit 的声明不一致必须由 TypeScript 和包测试直接失败,禁止复制两份相似接口。
61
- - 服务端模板的生产依赖边界必须静态拒绝 React、React DOM、Ant Design、Ant Design Mobile、Umi、Admin 和 Field Kit。
62
- - 前端仍必须通过 Field Kit 提交稳定值;本次瘦身不授权应用后端或自定义页面发明新的人员、部门、地址或附件格式。
63
- - 不增加新的网络权限、Secret、数据库权限或容器特权。后端运行镜像只减少无关依赖。
64
- - Docker 依赖层只复制根/服务端/domain/contracts manifests 与 lockfile,避免普通前端源码修改击穿后端依赖缓存。安装阶段使用 frozen lock,不能在镜像构建中改写解析结果。
65
- - Field Kit 的实质变更要求候选 tarball、新应用浏览器构建/E2E、模板生成检查和独立参考应用;它本身不触发本地 PostgreSQL 生命周期、Skills 或文档门禁。只有这些领域也发生变化时才运行对应昂贵门禁,避免把“未映射包”当作理由重复执行无关历史校验。
66
-
67
- ## 5. 资源上限与回滚
68
-
69
- 服务端部署闭包不得包含 `openxiangda-field-kit`、`antd`、`antd-mobile`、`react`、`react-dom`、`@umijs/*` 或 `openxiangda-admin`。生产目录大小记录为趋势指标,不作为跨 pnpm/Node 版本的唯一正确性判断;依赖闭包门禁才是稳定约束。
70
-
71
- 回滚单位是 contracts/Field Kit/creator 的一个版本组合,以及参考应用的一个 Git/AppVersion。由于值协议和数据库未变化,回滚不需要数据迁移。1.x 代码、镜像、流程和自动化均不在改动范围内。
72
-
73
- ## 6. 可证伪验收
74
-
75
- 1. contracts 根入口与 `/browser` 可以编译导入全部稳定字段值类型,且 package manifest 无运行依赖。
76
- 2. Field Kit 的 codec、Desktop、Mobile、格式化和现有测试继续通过,证明只移动所有权、不改变值行为。
77
- 3. 官方模板 `@app/domain` 和独立参考应用 `@app/domain` 不再依赖或导入 Field Kit。
78
- 4. `pnpm --filter @app/server why openxiangda-field-kit|antd|antd-mobile|react` 不再出现来自服务端的生产依赖路径。
79
- 5. `pnpm --filter @app/server deploy --prod --legacy` 生成的目录中不存在上述 UI 包。
80
- 6. 后端 Docker 构建日志的安装/build 选择器只包含 server、domain、应用 contracts;最终镜像启动和 readiness 通过。
81
- 7. 官方模板 check/test/build、独立参考应用 check/test/build 和工具链 `verify:affected` 全部通过。
82
- 8. Changesets 确定性覆盖 contracts、Field Kit 和 creator;发布后从 registry 创建的新应用重复第 3-7 项。
83
- 9. 参考应用使用同一 AppPackage 先部署 preproduction,再显式晋级 production;Data API 与字段往返结果保持一致。
84
-
85
- ## 7. 当前实现证据
86
-
87
- - contracts、Field Kit、官方模板 check/test/build 与 49 项 affected task 已通过。
88
- - Field Kit 的单/多选、地址、附件、UI 校验分层和移动 renderer 测试全部通过。
89
- - 新的服务端生产目录约 54MB、85 个包,相比基线分别减少约 79% 和 56%。
90
- - 生产目录未发现 Field Kit、React、React DOM、Ant Design、Ant Design Mobile 或 Admin。
91
- - 瘦身后的生产目录已直接启动 NestJS,平台健康/就绪、事件、工作流 provider 和采购 App API 路由均完成注册。
92
- - 正式发包、registry 新应用、Docker 镜像和线上 preproduction→production 仍是本主题的剩余验收。
@@ -1,82 +0,0 @@
1
- # OpenXiangda 2.0 前端运行时挂载路径
2
-
3
- 状态:2026-08-16 已实现待发布,当前发布阻断项。
4
-
5
- ## 问题证据
6
-
7
- 同一个 Native 2.0 前端制品会先挂载在
8
- `/service/openxiangda-apps/{appCode}/preproduction/`,通过验收后再原样挂载到
9
- `/view/{appCode}/`。平台已经在返回的 `index.html` 中注入 `<base>` 和
10
- `openxiangda-runtime-base`,但官方 Umi 模板仍以 `basename=/` 创建 browser
11
- history。应用加载后,根路由重定向会把预发地址改写成域名根目录;静态资源已经加载,
12
- 但后续路由、刷新和身份初始化不再处于该应用的环境挂载路径。
13
-
14
- 这不是单个参考应用的页面错误,而是官方模板与平台动态挂载契约不闭合。把模板改为
15
- hash history 可以规避跳转,但会降低正式地址质量,也会把已有 browser route、标签页和
16
- 深链接语义全部改成另一套协议,因此不采用。
17
-
18
- ## 能力归属
19
-
20
- - Platform Server 是环境、活动前端修订和运行时挂载路径的唯一所有者。
21
- - Platform Server 通过受控的 `index.html` 装饰写入
22
- `meta[name="openxiangda-runtime-base"]`;应用、CLI 和 AI 不自行拼接环境 URL。
23
- - `openxiangda-admin` 是 Umi/React Admin 的平台适配层,唯一负责把平台挂载路径转换为
24
- Umi runtime `basename`。
25
- - 应用只在 `src/app.ts` 注册官方适配函数,不复制解析、校验或环境判断逻辑。
26
-
27
- ## 决策
28
-
29
- 1. 继续使用 Umi browser history,不改为 hash history。
30
- 2. `openxiangda-admin` 提供纯函数读取并校验平台注入的 runtime base,再提供 Umi
31
- `modifyContextOpts` 适配函数。
32
- 3. 官方模板在 `src/app.ts` 注册该适配函数;开发者页面和业务路由仍只使用以 `/` 开头的
33
- 应用内路径。
34
- 4. 本地开发没有 runtime meta 时稳定回退到 `/`。
35
- 5. runtime base 必须是同源绝对路径,不接受协议、host、query、fragment、反斜杠、控制字符
36
- 或超长输入。无效输入关闭到 `/`,不导航到外部 origin。
37
- 6. 前端制品、AppPackage 和 AppVersion 不包含环境专用 base;预发到正式晋级仍复用完全相同
38
- 的制品摘要。
39
-
40
- ## 稳定不变量与契约
41
-
42
- - 环境挂载路径只由当前 HTTP 响应中的平台 meta 决定,不由 localStorage、构建变量、角色、
43
- URL query 或应用业务数据决定。
44
- - Umi 的路由定义、`useNavigate('/path')`、Admin 菜单路径和标签页路径始终是应用内路径;
45
- SDK 只在 history/router 边界加一次 basename。
46
- - `/service` Data API、App API、OAuth2 和身份端点仍是平台同源绝对服务路径,不拼入前端
47
- basename。
48
- - 深链接和刷新必须回到同一环境的前端修订;预发路由不得落入 production,production
49
- 路由不得落入预发。
50
- - 该契约只作用于 Native 2.0 前端,不修改 1.x View、流程或自动化路由。
51
-
52
- ## 失败、并发与安全边界
53
-
54
- - runtime base 在 React/Umi 创建 history 前同步解析,不产生异步竞争或第二份状态。
55
- - 多标签、多角色切换和环境同时存在时,每个 HTML 文档只消费自己的 meta;标签之间不共享
56
- mutable basename。
57
- - 平台漏注入或输入非法时回退 `/`,页面可以显示确定性诊断;SDK 不猜测 appCode 或环境。
58
- - 解析最长接受 2048 字符,只允许以单个 `/` 开头的 pathname,并规范为尾部 `/`。
59
- - 适配函数不读取 Cookie、token、用户资料或业务数据,不扩大身份和授权边界。
60
-
61
- ## 资源与性能边界
62
-
63
- 该方案只增加一次同步 meta 查询和 pathname 校验,不增加请求、缓存、数据库状态或运行实例。
64
- 前端仍只产出一份可复用制品,不为预发和正式重复构建。
65
-
66
- ## 回滚边界
67
-
68
- - SDK helper、官方模板注册和文档属于一个独立发布主题,可通过回退对应
69
- `openxiangda-admin` 与 `create-openxiangda` 版本撤销。
70
- - 平台现有 `<base>`/meta 注入保持兼容,不需要数据库迁移或 Platform Server 发布。
71
- - 已生成的 2.0 测试应用可显式采用 helper;不自动改写 1.x 或其他历史应用。
72
-
73
- ## 可证伪验收
74
-
75
- 1. 纯函数对预发和正式 base 返回规范 pathname,对外部 URL、query、fragment、控制字符和
76
- 超长输入回退 `/`。
77
- 2. 官方模板继续声明 browser history,并注册 SDK 的 Umi runtime context 适配器。
78
- 3. 生产构建在注入预发 meta 后访问应用根路径,浏览器 URL 保持在预发挂载路径;导航、回退、
79
- 深链接刷新均不离开该前缀。
80
- 4. 同一前端 artifact 晋升 production 后,在 `/view/{appCode}/` 下通过相同场景。
81
- 5. 两个环境的身份请求分别携带正确环境语义,控制台没有未处理异常、资源 404 或无效 JSON。
82
- 6. 全量 2.0 release gate、仓库外参考应用构建与线上 preproduction→production 验收通过。
@@ -1,79 +0,0 @@
1
- # OpenXiangda 2.0 实施路线图与证据矩阵
2
-
3
- 状态日期:2026-08-16
4
-
5
- 本文只记录可由源码、自动测试、真实 HTTP、新应用黑盒或已发布工件证明的状态。文档存在不等于运行时完成,Mock 通过不等于平台集成完成,npm 已发布也不等于某个应用已经部署。
6
-
7
- ## 1. 状态定义
8
-
9
- | 状态 | 含义 |
10
- | --- | --- |
11
- | 已交付 | 平台/工具链实现、正式门禁和独立应用证据均闭环 |
12
- | 已实现待晋级 | 代码与门禁已通过,但尚未作为目标 AppVersion 晋级指定环境 |
13
- | 已确认待实施 | 架构决策已经确认,运行时尚未按新方案完成,不能对外宣称交付 |
14
- | 已设计待确认 | 所有权、不变量、契约、失败恢复和验收矩阵已形成;根据架构门禁,确认前不修改运行时 |
15
- | 未开始 | 尚无可以进入实现的确认设计 |
16
-
17
- ## 2. 能力矩阵
18
-
19
- | 能力主题 | 唯一事实来源 | 当前状态 | 已有证据 | 尚缺内容与下一道门 |
20
- | --- | --- | --- | --- | --- |
21
- | 按需生产环境与运行启停 | Platform Server Native 环境 registry + Environment Head + DeploymentRun;K3s 只执行平台期望状态 | 已交付 | provision 仅创建预发、promotion 惰性创建唯一生产、`runtime_state` CAS、start/stop durable run、停止网关 503、ReplicaFailure 快速诊断、CLI/MCP/Contracts 与能力协商均已实现;工具链正式包和平台版本已部署 prod-1;全新应用证明初始只有 preproduction、stop→0/start→1 Ready/stop→0,以及首次 promotion 才创建 production,并且两环境使用完全相同的 AppVersion 与包摘要;reference 与 legacy HGY 入口回归 200 | 后续启停策略、闲置环境自动停止和资源诊断分别按独立运维主题演进;不得让客户端或 `kubectl scale` 成为第二状态源 |
22
- | OAuth2 外部应用身份 | Platform Server OAuth2 服务与数据库;Nest SDK 只消费 token | 已交付 | Client Credentials、租户/应用/环境/scope 绑定、一次性 Secret、轮换宽限、撤销、审计、跨环境拒绝、应用 Principal;平台 unit/持久化/真实 HTTP 和 Nest 测试通过 | 后续只按新 scope 或凭据策略单独设计,不与 Admin 用户会话混合 |
23
- | 平台托管后端运行凭据 | Platform Server credential 状态 + Environment Head/DeploymentRun | 已交付功能基线,E4 激活语义待收敛 | CAS 暂存、同 AppVersion 滚动部署、旧凭据宽限、重试幂等、CLI 不获得明文;真实 HTTP 两轮通过 | 当前候选凭据仍可能在 Head 前进入可用链路。E4 改为 pending→active→retiring→revoked,业务 token/后台 lease 只授予当前 Head 对应 run;配额、告警另做运维主题 |
24
- | 应用 Secret | Platform Server Secret 版本与审计表 + runtime activation policy | 已交付功能基线,active-only 注入待收敛 | 环境级 AAD、只写值、不可变版本、CAS 幂等、required/optional 部署语义、删除和审计测试 | P0 只校验所需版本存在,不向 pending runtime 提前注入 active-only Secret;E4 通过短时 runtime identity 按需读取并受 egress policy 约束。KMS 替换保持同一协议,不在应用端增加第二套存储 |
25
- | Data API / App API | Platform Server 物理 schema + 环境 Head 选择的逻辑 config projection;应用后端承载业务逻辑 | Native 调用委托与请求路径证明已交付;逻辑配置投影继续收敛 | 用户与服务 Principal、PostgREST RLS、字段/行权限、受限事务批处理、最长 60 秒 invocation token、最长 30 秒 Ed25519 assertion、Nest 全局 transport guard 与同构本地平台已通过 | 继续完成 E2 physical/logical 分离和 E4 runtime lease;NodePort/NetworkPolicy 只缩小暴露面,不参与授权正确性 |
26
- | RBAC + 业务关系权限 | Platform Server 原生 authz revision、环境 state、RoleMembership、RelationshipGrant、RoleSession | A0-N0/N1/N2/C1/C2/P 已实现 | N2 新建环境级 manual role/membership/delegation/relationship、应用级 super-admin grant、Native RoleSession 与不可变 mutation receipt;C2 每请求先以 PostgreSQL 校验 session/state/主体,再使用环境、authz/scope 版本与主体 revision 隔离的 Redis summary;P 以 `scopeSources` 将学院管理员、仪器管理员等业务表映射为环境范围 grant,Data API 同事务置 stale/建任务,Worker 提供 lease/retry/DLQ/replay/receipt/closure,strict 投影失败关闭且恢复扫描不依赖 Redis | 下一步 A0-N3/N4 完成全实例 gate、Native generation switch 与真实 PostgreSQL/PostgREST/K3s 验收;Admin A1 只消费 native kernel |
27
- | Events/Automation v2 | Platform Server delivery/receipt 状态;Nest handler 承担业务副作用 | 已交付 | CloudEvents 签名、claim lease、重复投递、进程崩溃接管、stale token 隔离、重试/DLQ/replay、双密钥、重启恢复与持久 receipt 真实链路两轮通过;Native 本地层已由 CLI 新建独立应用,在真实 PostgreSQL 上覆盖 503 + Retry-After、确定性 400 死信、幂等重放和成功回执;Timer 使用严格六段 Cron + IANA 时区,调度、事件、outbox 与下一触发点在同一事务提交,并通过同一计划时间并发 claim、重启恢复与 reset 验收 | 外部副作用仍必须使用 event id 做下游幂等;不承诺跨系统 exactly-once;停机期间的 Timer 采用合并补偿而非历史洪峰补发 |
28
- | Workflow Kernel v2 | Platform Server 持久状态机;Admin 只解释 Surface 协议 | 进行中 | 已完成 Kernel Native RoleSession/RoleSubject 数据模型切换;打包后的 CLI 已创建全新独立应用,并在真实 PostgreSQL、平台、NestJS 与 Chromium 中通过预览令牌单次消费、实例/任务/参与者链/时间线/回执事务提交、跨重启幂等回放、实例与任务版本 CAS、并发审批唯一成功和 reset 清理;转交与任务代理真实切换 Native RoleSubject 待办归属,前/后加签使用有序参与者链,目标身份按 membership 修订、角色和数据 scope 校验;长期代理按半开时间窗和不重叠规则解析,在预览与任务创建间 CAS 校验,把规则、有效期和原/代理 RoleSubject 快照冻结进参与者链,撤销仅影响新任务;8 条浏览器场景覆盖角色切换、代理冻结、完整审批动作和管理员终止 | 下一步执行远端 2.0 Kernel 离线切换、预发/生产冒烟和过期任务管理员重分派验收。1.x 双核运行路径保持不变 |
29
- | Workflow Kernel v2 | Kernel 状态机与平台持久实例;业务字段仍在 Data/App API | 已交付基线 | 同意/拒绝、转交、回退、撤回、加签、代理、两种退回语义、重新提交、长任务委托、Provider 恢复与并发 CAS/lease 真实链路通过 | 可视化编辑器和更多业务协议按独立需求设计;不把业务字段迁入流程库 |
30
- | 独立 NestJS 后端与应用交付 | 应用 Git/AppPackage;Platform Server DeploymentRun/Environment Head | 已交付功能基线,E4 激活边界待实现 | 不可变包摘要、后端 OCI digest、版本化 Kubernetes workload、readiness、重试/取消/回滚/晋级和资源限制已有证据 | 候选当前可能先取得可用 runtime credential,同进程 Worker/Scheduler 缺活动 Head lease,共享 NodePort 缺强路径证明。E4 以 pending credential、短租约、gateway assertion、failed candidate GC 收敛;仍保持每应用独立容器,不拆成多应用 Node 进程或强制三个 Deployment |
31
- | 2.0 CLI/MCP/Skills/模板 | 独立 `openxiangda-v2` 仓库与已发布 npm 工件 | 已交付基线 | 16 包 check/test/build、边界扫描、真实 tarball 新应用、持久 reference app、Chromium、Skills、文档全部通过;2026-08-15 再以 12 个候选 tarball 经临时本地 registry 安装到仓库外参考应用,生成、类型检查、单测、真实 NestJS OAuth2/Native 身份联调与生产构建全部通过;不调用 1.x | 新能力必须同时更新命令/MCP/Skill/模板消费证据,禁止只写 CLI 命令 |
32
- | 确定性工具链发布 | Changesets 版本提交、冻结工件清单、release receipt | 已交付 | `verify:release` 已成为唯一候选验证入口并产出绑定 HEAD/registry/模式/工件摘要的 `validated` receipt;`release:publish` 已以同一冻结工件完成真实候选发布,未重跑正式门禁,并在发布后显式同步 reference lock;工作区单写者、不可变工件、可恢复阶段、Skill 与文档门禁均通过,详见[发布验证凭据](./release-verification-receipt-v2.md) | 后续发布继续只消费机器计划与 Changesets,不新增 AI 临场选包、升版或跳过门禁路径 |
33
- | 环境配置内核 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 只留审计历史,不做双读、双写或导入 |
34
- | 授权内核 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 或建立长期双读/双写 |
35
- | 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 和企业采购参考应用已落地。线上审计发现双菜单高亮、默认标签几何、页面视觉和平台字段交互未达到设计合同,当前应用只作为 lifecycle acceptance app;P1 已完成唯一菜单激活和标签第一轮重建,单测/构建与桌面/移动 Chromium 通过 | 按[最佳实践模板重建计划](./best-practice-template-rebuild-v2.md)继续 P1-P5;完成截图、真实组织和 prod-1 预发验收前不得宣称最终模板 |
36
- | 独立移动用户端标准页面 | `openxiangda-user` 拥有用户端身份生命周期和页面组合;Field Kit 拥有移动字段值/控件;平台拥有身份、数据、流程和文件事实 | 已实现,待线上验收 | 已新增无 UI Native RoleSession Provider,以及移动工作台、数据列表/表单/详情、流程提交/工作中心/任务/实例页面;同一 AppPackage 内 `/admin` 与 `/m` 是两个独立懒加载 UI 树,根入口只做一次设备选择;流程预览只在业务保存和 prepare 后弹出,字段统一经过 `openxiangda-field-kit/mobile`;模板 check/test/build、桌面/移动 Chromium、创建器快照和 `verify:affected` 通过;14 个候选 tarball 已在仓库外创建全新应用,完成确定性 AppPackage、真实 PostgreSQL/NestJS/本地平台、桌面/移动 Chromium、工作流/事件/定时/并发/重放与资源限制验收 | 发布正式候选并用 prod-1 preproduction 验证真实 OAuth2、RoleSession、Data API、Workflow 和文件链路;不复用 PC Admin DOM 或样式树 |
37
- | 前端动态挂载路径 | Platform Server 注入 runtime base;`openxiangda-admin` 适配 Umi basename | 已交付 | `openxiangda-admin@2.0.0-alpha.26` 与 `create-openxiangda@2.0.0-alpha.27` 已发布;参考应用的同一前端 digest 先部署 preproduction 再晋级 production。正式根入口和业务深链均返回 200、`application-v2`、production 环境修订和正确 runtime base,全部 JS/CSS 资源 200;Chrome 保持 `/view/openxiangda-v2-reference-app/` 并显示应用标题 | 后续路由能力只按独立需求增加;不改 hash history,不增加环境专用构建或第二套路由状态 |
38
- | 稳定字段值合同与服务端 UI 依赖边界 | `openxiangda-contracts` 拥有值形状;Field Kit 拥有 codec/平台控制器/renderer | 已交付 | 稳定值类型已移到无依赖 contracts,Field Kit 保留前端重导出,模板 domain 删除 Field Kit;13 个对应 npm 候选已发布并打 Git tag。参考应用 amd64 镜像约 63.8MB、生产依赖 85 包且不含 Field Kit/React/Ant Design;同一 AppPackage 已完成 prod-1 preproduction→production 晋级,正式根路由、深链和六个首屏资源均返回 200,详见[稳定字段值合同与 UI 依赖边界](./field-value-contract-boundary.md) | 后续只按新字段合同或后端制品边界独立演进,不把 UI 运行时重新引入 Nest 镜像 |
39
- | Admin A1 RoleSession 上下文 | Native RoleSession context/switch 是唯一身份资料、RoleSubject 与 scope 来源 | 已实现,待 Native K4 线上激活验收 | Platform Server 已提供有界 RoleSubject 分页、稳定身份资料、非 active scope=null、切换 expected RoleSession CAS 与 identityScope;桌面 Admin 和 `openxiangda-user` 均只消费该 Native 合同,并以 identity epoch 清理页面生命周期 | 不再实现第二套身份接口;待同一切换窗口机器验证 DB/K3s/drain 证据后再执行 K4,随后完成 preproduction/production 真实角色切换验收 |
40
- | 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 不得绕过该阶段 |
41
- | 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 混发 |
42
- | Admin B0-R 登录 return target 安全 | 平台通用登录代理和服务端 CAS 校验 | 已设计待确认 | 全仓审计确认平台、1.x View、流程、旧编辑器和 CLI 合法生产者均可归入同源;一次解析、8 KiB 上限、精确 origin、CAS 双阶段规范化、错误链路 fail closed 及回归向量已定义 | 明确确认后作为独立平台安全提交,不和 Shell 改造、OAuth state 或身份协议混发 |
43
- | 旧平台第三方认证 S0 | Platform Server 一次性 OAuth state 与 purpose 绑定 | 未开始 | 已证明旧登录 state 仅为 tenantId、回调未消费 state,账号绑定指向未注册 `/bind-callback` 且 tenantId 为空 | 先单独形成登录/绑定事务、TTL、一次性消费和迁移设计;不得把它混入 B0-R,也不重做 2.0 Client Credentials/App Auth |
44
- | Admin 既有协议迁移输入 | `openxiangda-admin` 平台适配层与显式可选 contribution | 已实现,待迁入 Pro v6 | anyOf/allOf、manifest 闭包、直接 URL 403、独立数据表单/详情、资源级失效、工作中心服务端分页、DirtyStateRegistry、12 标签/6 keepAlive LRU、identityScope/epoch 隔离、个人中心贡献化和 Core-only Workflow 负向证明已有测试证据 | 保留协议和并发不变量,删除旧 UI 与重复通用组件;不得为旧组件 API 建兼容层,也不得引入临时全局状态、角色名判断、未绑定环境的缓存键或第二套查询 DSL |
45
-
46
- ## 3. 当前关键路径
47
-
48
- ```mermaid
49
- flowchart LR
50
- Audit["B0-R 全仓生产者审计(已完成)"] --> Confirm["确认 Admin 平台边界"]
51
- Confirm --> CP["CP0/CP1 alpha 退役 preflight"]
52
- CP --> E1["E1 Native config/contracts v3"]
53
- E1 --> T0["E1-T0 全新 Native reference(已完成)"]
54
- T0 --> E2["E2 Data API physical/logical 分离"]
55
- T0 --> A0["A0 native environment authz"]
56
- E2 --> E4["E4 Head CAS / 调用委托 / runtime gate"]
57
- A0 --> E4
58
- E4 --> Cutover["E5 native generation 与 reference app cutover"]
59
- Confirm --> B0O["B0-O 租户 canonical origin 收敛"]
60
- Cutover --> A1["A1 平台 RoleSession 上下文"]
61
- B0O --> B0["B0-R 平台 return target 收敛"]
62
- B0O --> B0C["B0-C Cookie 安全迁移"]
63
- A1 --> A2["A2 identityScope / epoch"]
64
- A2 --> Pro6["Ant Design Pro v6 全量切换"]
65
- B0 --> Pro6
66
- Pro6 --> Pages["ProTable / ProForm / Workflow Surface"]
67
- Pro6 --> Life["标签 / 有界 keepAlive / 个人中心"]
68
- B0C --> Fresh["完整新应用 Chromium 验收"]
69
- Pages --> Fresh
70
- Life --> Fresh
71
- Fresh --> Release["Changesets 物化与单次正式发布"]
72
- Release --> Promote["同一 AppVersion 预发/正式晋级"]
73
- ```
74
-
75
- 当前产品缺陷与上游兼容性已经构成重写 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 表临时加环境分支。
76
-
77
- ## 4. 每轮执行记录要求
78
-
79
- 后续每轮在修改前必须给出:问题证据、能力所有者、不变量、上下游契约、并发与失败语义、安全/资源上限、回滚单元、可证伪验收。修改后把实际证据回填到本矩阵;若证据与设计冲突,先更新设计并重新确认,不用局部兼容分支掩盖冲突。
@@ -1,136 +0,0 @@
1
- # OpenXiangda 2.0 本地开发内核
2
-
3
- 状态:L0-L3 已实现,并由打包工具链创建的全新应用在真实 PostgreSQL 上验证;本轮补齐可审计的 status/stop/reset 生命周期控制
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
-
7
- ## 1. 产品结论
8
-
9
- 开发者在新建应用后只需要运行:
10
-
11
- ```bash
12
- openxiangda dev
13
- ```
14
-
15
- 命令打开完整 Admin 应用并同时启动 React/Umi Max、NestJS 和本地平台服务。前端、后端、生成契约和应用声明支持有界热更新;开发者不需要先 provision、登录远程平台或创建第三个远程环境。
16
-
17
- 远程部署环境只有 `preproduction`、`production`。`local` 是进程运行模式,不是 environment registry 记录:
18
-
19
- ```text
20
- local source + local state
21
- | build once
22
- v
23
- immutable AppVersion -> preproduction Head -> production Head
24
- ```
25
-
26
- 因此公共合同必须区分:
27
-
28
- ```ts
29
- type LocalRuntimeMode = "local";
30
- type DeploymentEnvironment = "preproduction" | "production";
31
- type RuntimeMode = LocalRuntimeMode | DeploymentEnvironment;
32
- ```
33
-
34
- CLI 不提供 `deploy development`、`deploy local` 或 `promote preproduction` 的反向路径;production 只接收已经在 preproduction 验证过的同一 AppVersion/package/image digest。
35
-
36
- ## 2. 架构门禁
37
-
38
- | 维度 | 决定 |
39
- | --- | --- |
40
- | 问题证据 | 当前模板已有 Vite 内存平台模拟器和并行 `pnpm dev`,但 Nest 默认仍把环境写成 `development`,Data/Workflow/Event 状态主要在前端进程中模拟;这足以演示页面,不能证明真实 PostgreSQL、进程重启、前后端调用和安全边界。 |
41
- | 能力所有者 | `openxiangda dev` 是本地生命周期唯一编排者;本地平台服务拥有身份、Data API、Workflow/Event 和开发状态;Vite 只负责页面/HMR,Nest 只负责应用业务接口。应用代码不自行启动数据库或伪造平台 token。 |
42
- | 稳定不变量 | local 永不出现在远程 registry/Head/DeploymentRun;AppPackage 不含目标环境;本地状态和凭据不发布;同一源码生成的合同由本地测试和远程运行共同消费,不维护第二套业务 API。 |
43
- | 上下游合同 | CLI 生成一个 loopback manifest,向 Web/Nest 注入 local base URL、app identity 和短期 local credential;Data API、Admin context、Workflow/Event 的 HTTP/JSON 合同与 Native v3 一致,只有 issuer、存储生命周期和副作用策略不同。 |
44
- | 并发与失败 | 每个工作区按 canonical path digest 持有单实例锁、动态端口和本地状态目录;第二个 `dev` 返回已有 URL,不重复启动。任一子进程失败时有界终止整组进程并保留诊断,不调用远程写接口。`dev stop` 通过 PID + 进程启动身份防止 PID 重用误杀;`dev reset --data` 与启动争抢同一锁,不能边运行边删除。重启恢复持久开发数据,显式 reset 才精确重建当前工作区状态。 |
45
- | 安全与资源 | 服务默认只监听 `127.0.0.1`;local token 固定 local issuer/audience 且不能被远程平台接受,远程 OAuth/Secret 不自动导入。PostgreSQL 容器有磁盘/内存预算;本地数据库凭据、OAuth 原始 Secret 和加密主材料只在权限为 0600 的 Git 忽略目录保存,原始 OAuth Secret 只注入 NestJS,日志与响应不输出 token/Secret。生产 build 静态证明不包含 local middleware。 |
46
- | 回滚单元 | L0-L3 都只改变 CLI、模板和本地测试;不修改线上 Head。异常时可回退本地工具版本。数据库数据只由带所有权验证的 `dev reset --data` 删除;手工删除 `.openxiangda/local` 不是受支持的数据回滚方式,因为会丢失凭据和资源绑定证据。 |
47
- | 可证伪验收 | 从空目录创建应用后一个命令打开完整 Admin;前端和 Nest 修改均热更新;真实 PostgreSQL 事务/RLS/幂等测试通过;停止/重启保持数据、`dev reset --data` 清空;伪造会话或 Docker 标签时零删除;local token 调远程和远程 token 调 local 均拒绝;production bundle 对 local canary 零命中。 |
48
-
49
- ## 3. 默认本地拓扑
50
-
51
- ```text
52
- Browser
53
- -> Vite/Admin (loopback, HMR)
54
- -> /service -> Local Platform Service
55
- -> RoleSession/OAuth verification
56
- -> /openxiangda-app-api -> NestJS application
57
- -> Data/OAuth/Secret -> PostgreSQL
58
- -> local workflow/event dispatcher
59
- ```
60
-
61
- - CLI 先执行增量 `generate` 并确认生成成功,再启动依赖;生成失败不会带着旧合同继续运行。
62
- - CLI 自动选择端口并打印/打开一个 URL;Admin 的菜单、路由、标签页、个人中心和角色切换都走同一页面入口。
63
- - Local Platform Service 是 Node 进程,不嵌入 Vite middleware。这样 Nest、浏览器和测试共享同一个平台状态,Vite 重启不会丢失后端事实。
64
- - PostgreSQL 是默认平台状态存储。开发者不安装 PostgreSQL 服务、客户端、用户或建库脚本;只需 Docker Desktop 或兼容容器运行时。CLI 启动摘要固定的 PostgreSQL 16 镜像,按 canonical workspace 创建独立容器和 volume,自动完成建库、迁移、健康检查与 schema digest 校验,不复用任意同端口数据库。
65
- - 无容器运行时时,默认命令返回明确诊断;显式 `--ui-only` 才允许使用无持久性的页面模拟器,并在页面持续显示“UI-only,不可作为平台验证”的标识。CI、`openxiangda test` 和发布检查从不接受 UI-only 证据。
66
-
67
- ### 3.1 2026-08-14 Native App API 用户身份闭环
68
-
69
- | 门禁 | 决定 |
70
- | --- | --- |
71
- | 问题与证据 | 完整本地会话中,Admin 已使用 `openxiangda.native-role-session/v2`,App API 网关也签发绑定该会话的 60 秒 loopback token;Nest SDK 却继续请求 alpha `/authz/principal`。本地验证器最终又把 token 中的 Native session id 与 `openxiangda.role-session/v2` 比较,导致真实 Chromium 流程保存稳定返回 `401 LOCAL_USER_IDENTITY_INVALID`。 |
72
- | 能力所有权 | Native RoleSession 服务是 2.0 用户身份的唯一所有者;网关只签发和转发短期调用身份;`openxiangda-nest` 只通过平台 `/native/authz/principal` 与 `/native/authz/explain` 校验并注入 Native Principal/RoleSession,不建立映射或兼容状态。 |
73
- | 稳定不变量 | 浏览器原始 Authorization 不进入应用;token 必须绑定 app、`runtimeMode=local`、Native RoleSession、60 秒 TTL 和随机 nonce;Nest handler 只收到平台重新验证后的 Native identity。应用身份 OAuth2 仍走独立 `/oauth2/principal`,不允许用无 RoleSession 的服务身份冒充用户。 |
74
- | 上下游契约 | `openxiangda-nest` 的用户上下文改为 `NativePrincipal + NativeRoleSession`,SDK 用户授权路径固定为 `/native/authz`;本地平台补齐同形 principal 端点;官方 Nest 模板的 controller/service 类型同步改为 Native 类型。2.0 不增加 alpha fallback 或运行时开关。 |
75
- | 失败与并发 | 缺失、签名错误、过期、错误 app 或 stale Native RoleSession 均在业务 handler 前拒绝。角色切换后旧 token 即使尚未到期也因 session id 不匹配失败;授权 explain 必须再次校验同一 Native session,写操作不自动重放。 |
76
- | 安全与资源上限 | loopback token 固定 60 秒且只接受 HMAC 等长比较;payload 不携带 allow 结果、业务数据或 Secret。principal/explain 仍受 SDK 5 秒默认超时约束,不增加缓存或后台刷新。 |
77
- | 回滚边界 | 只发布 `openxiangda-local-platform`、`openxiangda-nest` 和包含新类型消费的创建模板;本地数据 schema、远程 Head、1.x SDK 与旧应用无变化。回滚时三个工件作为同一测试 BOM 恢复。 |
78
- | 可证伪验收 | 单测断言 Nest 请求 Native 路径并注入 Native schema;本地平台拒绝伪造/错误 session token;全新独立应用在真实 PostgreSQL 下通过 App API 保存、流程预览、发起和后续审批 Chromium 场景。 |
79
-
80
- ### 3.2 2026-08-14 确定性浏览器验收边界
81
-
82
- | 门禁 | 决定 |
83
- | --- | --- |
84
- | 问题与证据 | Playwright 复用日常开发会话时,历史修改会污染种子数据断言;若测试配置自行删除数据库,又会绕过 CLI 对工作区、容器和 volume 的所有权校验。先跑 UI-only、再跑完整会话还会重复同一批浏览器成本,却不能增加后端证据。 |
85
- | 能力所有权 | 日常 `openxiangda dev` 永远保留开发数据;外部 `OPENXIANGDA_E2E_BASE_URL` 只连接现有会话且零清理;发布门禁由打包工具链创建一次性外部应用,并且只能通过 `openxiangda dev reset --data` 建立确定性初始状态。 |
86
- | 稳定不变量 | 浏览器测试不拥有任意开发者 volume。一次性验收应用完成重置后,Chromium 只运行一次,但路径必须同时穿过 React、独立本地平台、NestJS 与真实 PostgreSQL。UI-only 只服务快速页面回归,不能重复计作完整证据。 |
87
- | 失败与回滚 | reset、进程就绪或任一浏览器场景失败立即终止门禁并保留诊断;一次性工作区与其有所有权标签的资源是唯一清理边界。回滚只需恢复打包验证器,不改变开发数据和线上环境。 |
88
- | 可证伪验收 | 被历史修改污染的持久会话不再用于种子套件;全新 tarball 应用在安全 reset 后通过 8 个 Chromium 场景、重启持久化、事务幂等、并发、事件重放、Workflow/Timer 恢复和最终隔离检查。 |
89
-
90
- ## 4. 本地身份与状态
91
-
92
- - 本地平台为当前工作区生成短期签名材料和 runtime OAuth client,保存在 `.openxiangda/local/`,目录必须被 Git 忽略。原始 OAuth Secret 只注入 NestJS 子进程;Web 子进程和 manifest 只能看到非敏感元数据。
93
- - 默认提供开发者、应用最高管理员以及应用声明的示例角色;切换角色仍生成稳定单角色 RoleSession,不能在前端直接替换 role code。
94
- - local Principal 明确包含 `runtimeMode=local`,不伪造 preproduction/production environment UUID。
95
- - Secret 值只通过本地管理 API 从一次性表单或显式本机输入进入 PostgreSQL 加密存储,不写 config、AppPackage、日志或浏览器持久存储;管理 API 只返回元数据,创建、轮换、幂等回放和审计均不回显明文。
96
- - 本地状态只属于当前工作区。复制仓库不会沿用 identity;工作区 canonical path 改变时需要显式 `dev adopt` 或重新创建,防止两个目录同时写同一 volume。
97
-
98
- ## 5. Data、Workflow 与 Events
99
-
100
- 本地开发分清“快速交互”和“发布证据”,但不分裂合同:
101
-
102
- 1. 页面、Nest App API、Data API 都调用 Native v3 路径和 DTO。
103
- 2. Data API 在本地 PostgreSQL 上执行真实 schema、事务、约束、RLS 与幂等逻辑;应用仍不能拿数据库凭据。
104
- 3. Workflow Kernel 使用相同定义编译器和命令状态机,本地提供可控时钟、审批人和操作面板;业务字段仍存 Data API/App API。
105
- 4. Event 使用与 Data API 写事务一致的持久 outbox、带租约的 delivery 和平台 receipt。暂停订阅后既不生成新 delivery,也不领取已有待处理 delivery;恢复后继续领取。网络错误、408、409、425、429、5xx 按有界指数退避,`Retry-After` 优先,其他 4xx 直接死信;领取代次 CAS 阻止过期 Worker 覆盖新结果;同一原投递与重放幂等键只创建一个 delivery。handler 调用真实 Nest endpoint,应用重启后 receipt 继续抑制重复副作用。
106
- 5. Timer 使用持久 schedule/firing 记录和严格六段 Cron;IANA 时区、DST 计算与声明校验由成熟解析器完成。到期事件与 schedule 推进、outbox、delivery 在同一 PostgreSQL 事务内提交,多实例通过行锁与计划时间 CAS 保证同一计划时间只触发一次。停机恢复将遗漏时段合并为一次触发,避免产生无界补偿洪峰;Cron 或时区声明变化会原子重算下一次执行。`openxiangda event timer fire <timer-id>` 只对完整本地开发会话开放,用于无需等待真实时间的端到端验证,仍走相同持久化和 Nest 投递链路。
107
- 6. 任何只在 UI-only 模式中通过的场景都不能满足 `openxiangda check` 或 `openxiangda test` 的集成项。
108
-
109
- ## 6. 命令面
110
-
111
- ```bash
112
- openxiangda doctor
113
- openxiangda dev [--no-open]
114
- openxiangda dev status
115
- openxiangda dev stop
116
- openxiangda dev reset --data
117
- openxiangda dev --reset
118
- openxiangda dev --ui-only
119
- openxiangda event timer fire <timer-id>
120
- openxiangda test
121
- openxiangda deploy preproduction
122
- openxiangda deploy production --package <package-digest>
123
- ```
124
-
125
- 日常开发不要求记忆容器编排命令、端口、数据库连接或环境 ID。`doctor` 会把 Docker CLI 缺失与 daemon 不可用作为完整本地开发的阻断诊断,同时返回本地会话摘要。`dev status` 不启动 Docker,`dev stop` 保留 volume,`dev reset --data` 是唯一独立的数据删除入口;它先解析全部目标并验证容器 runtime/credential 标签和 volume workspace/runtime 标签,再删除任意目标。高级诊断仍保存在 `.openxiangda/local/diagnostics.json`,内部 Docker 参数不扩展为公共命令。
126
-
127
- ## 7. 实施顺序
128
-
129
- 1. **L0 合同切分(已完成)**:Native 合同 `2.0.0-alpha.2` 已删除远程 `development`,引入 `RuntimeMode=local`;模板与测试不再把 local 伪装成远程环境。新 AppPackage 只能部署到 preproduction,同一 AppVersion 只能晋级到 production,回滚只允许两个远端环境。OAuth 等运维轮换使用受当前 Head 和成功运行历史约束的 `redeploy`,不再滥用 promotion。平台所有 Native 远端入口共用同一 fail-closed 环境断言;SQL 合同拒绝新写入 `development`,但保留既有 alpha 行作为不可变审计历史。
130
- 2. **L1 生命周期(已完成)**:CLI 已实现按工作区单实例锁、动态端口、进程组监督、就绪后浏览器打开、结构化诊断、日志捕获和安全退出;`--local-sdk` 使用发布同形的 npm tarball 工件,避免源码链接产生多份 React/NestJS 运行时。全新独立应用已经通过 CLI 自身的 check/test/build 以及真实 Vite + NestJS 启停验证。
131
- 3. **L2a 独立本地平台(已完成)**:完整模式已把 Vite 内存模拟器抽成独立 loopback 服务;CLI 分别监督应用进程组和平台进程,浏览器通过 Vite 代理、NestJS 通过平台 URL 访问同一状态。任一进程失败会终止整组,第二次启动复用会话,动态三端口和退出清理已在全新独立应用验证。日常开发以 `openxiangda dev` 为唯一受监督入口;内部 `pnpm dev` 只供 CLI 编排,不作为公开入口。
132
- 4. **L2b 持久本地平台(已完成)**:本地平台内核已从应用前端模板移入独立 `openxiangda-local-platform` 工具链包;CLI 使用摘要固定的 PostgreSQL 16 镜像,为每个 canonical workspace 建立带所有权标签的容器与 volume,并限制为 1 CPU、512 MiB、200 PID。数据库只绑定 loopback,凭据保存在 Git 忽略且权限为 0600 的工作区状态目录,声明通过文件而非环境变量传递。Data API 的记录、审计、乐观 revision、受限事务、幂等凭证与活动角色已经持久化;授权从应用声明的 RBAC、数据范围、关系授权和字段策略统一求值。runtime/external OAuth client、短期应用 token、应用身份 Data API、加密 Secret、CAS/幂等/审计也使用同一控制存储。浏览器 App API 经过平台网关,浏览器 token 不会直传,网关签发绑定 app 与当前 RoleSession 的 loopback 身份给 NestJS。完整停止再启动保持业务数据、Secret 元数据和 OAuth 凭据,只有 `--reset` 在所有权核验后精确重建当前工作区 volume。发布计划只在这些能力或关联模板发生变化时,使用真实打包工件和全新应用重跑数据库生命周期门禁,不让无关包重复承担该成本。
133
- 5. **L3a Events(已完成)**:编译器生成订阅代码契约,CLI 为每项声明生成仅注入 Nest/本地平台的 0600 签名材料;Data API 与 outbox 同事务提交,dispatcher 使用 `SKIP LOCKED`、领取租约、代次 CAS、状态分类、`Retry-After`、有界退避、死信与幂等重放。Nest 默认使用平台持久 receipt;完整停止/重启和 `--reset` 行为已通过真实打包工件创建的新应用、真实 PostgreSQL、真实 Nest endpoint 与 Chromium 验证。
134
- 6. **L3b Timer / Workflow(已完成)**:Timer 已实现严格六段 Cron/IANA 时区校验、持久 schedule/firing、同事务 outbox/delivery、暂停、重启恢复、停机合并、声明变更重算和仅限本地会话的 CLI 快进。两个绑定同一 `expectedScheduledAt` 快照的并发 claim 只生成一个 firing;连续执行“触发下一次”则按定义推进到不同计划时间。Workflow Kernel 已实现定义编译、预览令牌、实例/任务/时间线/回执事务提交、实例与任务版本 CAS、同幂等键重放、同任务并发唯一成功、转交、前后加签、回退、角色/数据 scope 审批人解析,以及带有效期和不重叠约束的长期代理;任务创建时冻结原审批人、代理规则和最终参与者,撤销规则不改历史任务。完整停止/重启保持进度,显式 reset 精确清空。
135
-
136
- 每一步只在本地新建应用和真实打包工件中验证。L0 与 Native E1 是同一个 breaking contract 变更,不能先加兼容枚举再二次迁移;L2/L3 不阻塞 CP0-CP2 只读退役审计。
@@ -1,88 +0,0 @@
1
- # OpenXiangda 2.0 移动用户端标准页面
2
-
3
- 状态:2026-08-16 已确认并进入实现
4
-
5
- 适用范围:OpenXiangda 2.0 新应用的移动用户端、`openxiangda-user/mobile`、生成模板和移动 Chromium 验收。PC Admin、1.x View、稳定字段数据协议和平台数据库不在本轮修改范围内。
6
-
7
- ## 1. 实现门禁
8
-
9
- | 项目 | 决策 |
10
- | --- | --- |
11
- | 问题证据 | `openxiangda-field-kit/mobile` 已覆盖移动字段交互,但 2.0 只有 PC Admin 标准页面。应用若直接组合桌面 ProForm、原生 `select/file` 或临时流程页面,会重新产生字段值漂移、移动端难用、审批预览常驻和操作协议分叉。 |
12
- | 能力所有者 | Platform Server 继续唯一拥有身份、授权、Data/App API、Workflow Surface 和文件/目录能力;`openxiangda-user` 只持有当前 React 页面生命周期内的身份快照和 UI 状态;Field Kit 唯一拥有平台字段值归一化及移动控件。 |
13
- | 稳定不变量 | 移动端与 PC Admin 提交完全相同的稳定字段值;页面必填不冒充服务端业务校验;一个用户同时只使用一个稳定 RoleSubject;应用管理员仍由平台授权;Workflow 业务字段始终由 Data/App API 保存,Kernel 只保存流程状态和字段策略。 |
14
- | 上下游契约 | Provider 只消费 Native RoleSession context/switch;数据页面只消费 Data API 的服务端分页、revision/CAS 与审计;流程提交先保存业务数据,再 prepare,点击提交后才打开审批预览;任务/实例页只解释 Workflow Surface 的可见操作和 JSON input schema。 |
15
- | 并发与失败 | 身份请求以 generation 丢弃迟到响应,RoleSubject 切换使用 expected RoleSession CAS 并推进 identity epoch;列表分页请求丢弃旧响应;更新带 revision;流程命令带 task/instance version 和幂等键;页面卸载后不提交状态。 |
16
- | 安全与资源上限 | 浏览器不保存平台 Token、授权结论、服务地址或业务响应;最多展示 50 条移动列表、30 条审计和 100 条工作中心记录;文件、人员、部门、地址和关联数据必须走 Field Kit/平台 API;移动包不得依赖 `antd`、`@ant-design/pro-components` 或 `openxiangda-admin`。 |
17
- | 回滚边界 | 本轮是新增前端包和生成模板能力,不改平台表或远端 API。可回滚移动 AppVersion 或移除模板入口;字段协议、PC Admin 和 1.x 不受影响。 |
18
- | 可证伪验收 | 静态依赖扫描证明移动包没有桌面 UI;SSR/单测覆盖身份 gate、角色选择、字段渲染、列表和流程操作协议;真实移动 Chromium 覆盖工作台、列表、表单、提交后审批预览、详情和流程任务;桌面 Admin 回归通过。 |
19
-
20
- ## 2. 产品与视觉基线
21
-
22
- 本轮先生成并评审了五屏移动设计板:工作台、数据列表、表单提交、提交后的审批预览、流程任务详情。设计板是页面结构、视觉层级、间距、状态和操作顺序的可执行合同;业务示例数据可以变化,但实现不能退化成移动组件库默认皮肤或只保留信息架构:
23
-
24
- - 接受白底卡片、浅灰页面底色、中低信息密度、44px 以上触摸目标和底部安全区;
25
- - 接受首页指标与快捷入口、记录卡片列表、分区表单、底部主操作、纵向审批路径和任务页固定操作栏;
26
- - 流程预览只在点击“提交”并完成业务保存/prepare 后出现,不能常驻表单;
27
- - 页面只保留一个主操作。退回、拒绝、转交、代理、加签等由 Surface 决定,并收纳到任务页底部操作区或“更多”;
28
- - 不采用设计图中偶发的渐变按钮,正式实现使用单色主按钮;不把设计图中的示例字段、状态或角色名称写死到框架;
29
- - 不使用桌面侧栏、缩小后的 ProTable/ProForm、玻璃拟态、大面积装饰插画或以颜色替代文字状态。
30
-
31
- 基础 token:页面背景 `#f5f7fa`、卡片 `#ffffff`、主文字 `#172033`、次文字 `#667085`、边框 `#e6eaf0`、主色 `#1677ff`、成功 `#12a594`、警告 `#ed8b2c`、危险 `#e5484d`;卡片圆角 12px,页面水平间距 12px,区块间距 12px,底部操作栏包含 `env(safe-area-inset-bottom)`。
32
-
33
- ## 3. 包和运行时边界
34
-
35
- 新增 `openxiangda-user`:
36
-
37
- - 包根导出无 UI 的 `OpenXiangdaUserProvider`、context/types 和身份生命周期;
38
- - `openxiangda-user/mobile` 导出独立的 Mobile Identity Gate、App Shell、Workbench、Data List/Form/Detail、Workflow Submission/Work Center/Task/Instance;
39
- - `openxiangda-user/mobile.css` 只提供移动 token、页面结构和安全区样式;
40
- - Mobile 子入口可以依赖 `antd-mobile` 与 `openxiangda-field-kit/mobile`,不得引用 PC Admin;
41
- - 后续 Desktop 用户端使用独立子入口。自动识别入口只动态加载一个 UI 子树,并在一次页面会话内固定 experience;窗口缩放不把已填写表单热切到另一棵 UI。
42
-
43
- Provider 不建立第二套身份事实源。它只缓存平台返回的当前 context,暴露 `loading/error/identity/identityEpoch/reloadIdentity/switchRole/appApi`;所有授权仍由服务端重新判断。
44
-
45
- ## 4. 标准页面合同
46
-
47
- ### 4.1 工作台
48
-
49
- 工作台只做展示组合:问候、最多四个指标、最多八个快捷入口和有界最近事项。指标由应用通过受限聚合/App API 加载;框架不生成假统计,也不按角色名称推断数字。
50
-
51
- ### 4.2 数据列表、表单与详情
52
-
53
- 移动列表使用搜索、可选状态筛选、卡片和游标式“加载更多”体验;底层仍是 Data API `limit/offset`,不会把全量记录拉到浏览器。列表字段、标题字段、摘要字段和状态字段由页面 Surface 指定,所有值使用 `MobileFieldValue`。
54
-
55
- 表单用移动分区和固定底部提交栏,所有持久化字段用 `MobileFieldControl`。创建调用 Data API create;编辑先读当前记录并以 revision 更新。页面层 required 只负责即时提示,服务端字段错误仍需原样呈现。
56
-
57
- 详情按 Field Kit 只读 renderer 展示业务字段,并显示有界审计时间线。附件/图片的下载预览继续由 Field Kit 和平台 API 负责。
58
-
59
- ### 4.3 流程提交与详情
60
-
61
- 流程提交页初始只显示业务表单和一个“提交”按钮。点击后顺序固定为:
62
-
63
- 1. 归一化字段值并通过应用提供的 `saveBusiness` 保存业务记录;
64
- 2. 使用同一稳定保存幂等键准备流程;
65
- 3. 在底部弹层展示 Kernel 返回的审批节点、条件说明、候选审批人与主部门问题;
66
- 4. 需要输入时提交答案并重新 prepare;ready 后使用 preparation token 和独立 start 幂等键确认发起。
67
-
68
- 任务/实例页同时展示流程摘要、业务数据、审批时间线和 Surface 允许的操作。框架不复制同意、拒绝、退回、转交、加签或代理规则;操作输入只按后端 JSON schema 构建基础移动表单,复杂业务操作由应用通过 `app_action` 扩展且不能覆盖 Kernel 操作。
69
-
70
- ## 5. 分阶段交付
71
-
72
- 1. 新增 `openxiangda-user` Provider、移动标准页面、样式、单测和包边界门禁;
73
- 2. 生成模板新增独立用户端入口和通用采购申请示例,不复用 PC Admin 页面;
74
- 3. 启动本地平台/PostgreSQL/NestJS,在移动 Chromium 验收真实字段、角色切换、Data API 和 Workflow;
75
- 4. 经 Changeset、正式 release receipt 发布,再以全新应用在 prod-1 预发验收;只有明确发布时才创建/晋级 production。
76
-
77
- ## 6. 生成模板接入门禁
78
-
79
- | 项目 | 决策 |
80
- | --- | --- |
81
- | 问题证据 | AppPackage v3 只有一个不可变 `frontend` 制品和入口文件;为移动端另建第二个前端根会迫使编译器、部署状态和网关同时理解两套制品,超出页面问题本身。现有 Umi 已支持顶层路由懒加载,可在一个制品中承载互不嵌套的 Admin 与移动用户端 UI 树。 |
82
- | 能力所有者 | `apps/web` 仍是唯一 frontend 构建和制品根;`Application` 只拥有桌面 Admin 树,新增 `MobileApplication` 只拥有移动用户树;`openxiangda.config.ts` 是 admin/user route surface 的发布事实源;平台继续只部署一个 frontend digest。 |
83
- | 稳定不变量 | 两棵 UI 树不互相包裹或复用 DOM;移动路由不得进入 `AdminLayout`;显式 `/m` 路由始终选择移动 UI;自动识别只在应用根入口执行一次,表单填写期间的缩放或旋转不切换 UI;现有显式桌面业务 URL 始终进入 Admin。 |
84
- | 上下游契约 | Umi 顶层路由分别挂载 `Application` 和 `MobileApplication`;移动树使用同一个平台相对 `/service` 客户端、Native RoleSession、Data/App API 与 Workflow 合同;AppPackage route manifest 为移动路由声明 `surface: user`。 |
85
- | 并发与失败 | 入口识别为同步纯函数,不请求远端、不持久化选择;无法识别时默认桌面 Admin。身份、列表、详情和流程请求继续使用 `openxiangda-user` 的 generation/CAS/idempotency 语义;移动路由卸载不得接收迟到响应。 |
86
- | 安全与资源上限 | 自动识别不参与授权,任何 route 仍由平台 capability/Data/Workflow 授权;不保存 Token 或设备指纹;移动树路由级懒加载,首屏不得渲染 `.oxa-admin-root`,标准列表/审计/工作中心上限保持不变。 |
87
- | 回滚边界 | 仅新增模板移动路由、页面和同一 frontend 制品内的入口选择;不改平台数据库、网关或 AppPackage 格式。可回滚 `create-openxiangda`/`openxiangda-user` 候选和目标 AppVersion,桌面 Admin 与 1.x 不变。 |
88
- | 可证伪验收 | 纯函数测试覆盖手机、触屏窄屏、普通桌面与缺失浏览器信息;桌面 Chromium 继续通过原套件;移动 Chromium 从根入口自动进入 `/m`,覆盖工作台、列表、详情、字段表单、角色切换和“提交前无审批预览”;完整本地模式再验证业务保存、prepare/start 与任务操作;构建门禁验证 user surface 和路由拆分。 |