openxiangda-skill-kit 2.0.0-alpha.29 → 2.0.0-alpha.31
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 +1 -1
- package/docs/architecture/implementation-roadmap.md +4 -3
- package/docs/architecture/mobile-user-standard-pages-v2.md +88 -0
- package/docs/architecture/release-verification-receipt-v2.md +72 -0
- package/docs/architecture/repository-and-release.md +4 -3
- package/docs/delivery.md +4 -4
- package/docs/frontend.md +4 -4
- package/docs/getting-started.md +2 -1
- package/package.json +1 -1
- package/skills/openxiangda-v2-delivery/SKILL.md +9 -5
- package/skills/openxiangda-v2-frontend/SKILL.md +3 -1
|
@@ -996,7 +996,7 @@ flowchart LR
|
|
|
996
996
|
|
|
997
997
|
- 单次提交/PR:`pnpm verify:affected`,Admin 阶段另跑 `pnpm --filter openxiangda-admin check test build`;浏览器交互实际变化时运行模板聚焦 Playwright。
|
|
998
998
|
- 本地完整里程碑:`pnpm verify:local`,用真实 tarball 创建并销毁全新应用,执行 generate/check/test/Chromium/build,并验证持久 reference app、Skills 和文档;它是主动全量验收,不是每次保存文件的必跑项。
|
|
999
|
-
- 正式候选:Changesets 经 `pnpm release:version` 物化并形成已推送的版本提交后,`pnpm release
|
|
999
|
+
- 正式候选:Changesets 经 `pnpm release:version` 物化并形成已推送的版本提交后,`pnpm verify:release` 冻结真实候选 tarball,再由机器生成并执行一次增量矩阵并留下验证凭据;`pnpm release:publish` 只消费相同凭据和字节。每个候选始终在 monorepo 外的新应用完成 install/generate/check/test/build;只有 Admin/浏览器契约变化升级 Chromium,核心 SDK 变化增加临时 Verdaccio reference app,未知变化 fail closed 到全量。
|
|
1000
1000
|
- 周期审计或重大 alpha:`pnpm verify:release:full`。发包不回放 1.x 测试,也不为多个候选包重复运行同一浏览器路径。
|
|
1001
1001
|
|
|
1002
1002
|
## 14. 明确拒绝的方案
|
|
@@ -28,13 +28,14 @@
|
|
|
28
28
|
| Workflow Kernel v2 | Kernel 状态机与平台持久实例;业务字段仍在 Data/App API | 已交付基线 | 同意/拒绝、转交、回退、撤回、加签、代理、两种退回语义、重新提交、长任务委托、Provider 恢复与并发 CAS/lease 真实链路通过 | 可视化编辑器和更多业务协议按独立需求设计;不把业务字段迁入流程库 |
|
|
29
29
|
| 独立 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 |
|
|
30
30
|
| 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 命令 |
|
|
31
|
-
| 确定性工具链发布 | Changesets 版本提交、冻结工件清单、release receipt | 已交付 |
|
|
31
|
+
| 确定性工具链发布 | Changesets 版本提交、冻结工件清单、release receipt | 已交付 | `verify:release` 已成为唯一候选验证入口并产出绑定 HEAD/registry/模式/工件摘要的 `validated` receipt;`release:publish` 已以同一冻结工件完成真实候选发布,未重跑正式门禁,并在发布后显式同步 reference lock;工作区单写者、不可变工件、可恢复阶段、Skill 与文档门禁均通过,详见[发布验证凭据](./release-verification-receipt-v2.md) | 后续发布继续只消费机器计划与 Changesets,不新增 AI 临场选包、升版或跳过门禁路径 |
|
|
32
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 只留审计历史,不做双读、双写或导入 |
|
|
33
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 或建立长期双读/双写 |
|
|
34
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 单链路通过工作台、菜单、会话标签、稳定角色切换、列表/详情、独立供应商表单、工作中心、单按钮流程提交和个人中心;正式包已发布,仓库外参考应用使用 registry lock 构建,并以同一 AppPackage 完成 preproduction→production 晋级 | 移动用户端 Field Kit 已有独立 renderer;完整移动页面模板与设备 Chromium 验收另列后续主题,不回填到 PC Admin |
|
|
35
|
+
| 独立移动用户端标准页面 | `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 或样式树 |
|
|
35
36
|
| 前端动态挂载路径 | 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,不增加环境专用构建或第二套路由状态 |
|
|
36
|
-
| 稳定字段值合同与服务端 UI 依赖边界 | `openxiangda-contracts` 拥有值形状;Field Kit 拥有 codec/平台控制器/renderer |
|
|
37
|
-
| Admin A1 RoleSession 上下文 | Native RoleSession
|
|
37
|
+
| 稳定字段值合同与服务端 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 镜像 |
|
|
38
|
+
| 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 真实角色切换验收 |
|
|
38
39
|
| 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 不得绕过该阶段 |
|
|
39
40
|
| 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 混发 |
|
|
40
41
|
| Admin B0-R 登录 return target 安全 | 平台通用登录代理和服务端 CAS 校验 | 已设计待确认 | 全仓审计确认平台、1.x View、流程、旧编辑器和 CLI 合法生产者均可归入同源;一次解析、8 KiB 上限、精确 origin、CAS 双阶段规范化、错误链路 fail closed 及回归向量已定义 | 明确确认后作为独立平台安全提交,不和 Shell 改造、OAuth state 或身份协议混发 |
|
|
@@ -0,0 +1,88 @@
|
|
|
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 和路由拆分。 |
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# OpenXiangda 2.0 发布验证凭据
|
|
2
|
+
|
|
3
|
+
状态:2026-08-16 决策确认,进入实现。
|
|
4
|
+
|
|
5
|
+
## 问题证据
|
|
6
|
+
|
|
7
|
+
一次工具链发布先显式执行了 `pnpm verify:release`,随后
|
|
8
|
+
`pnpm release:publish` 又重新运行完整候选依赖闭包、全新应用、reference app、
|
|
9
|
+
Skills 和文档门禁。13 个包已经写入 npm 后,发布命令又尝试修改独立 reference
|
|
10
|
+
仓库的 lockfile,并因该仓库存在正常源码改动而以失败退出。registry 已经发生不可逆
|
|
11
|
+
写入,但命令表面状态仍是失败,既浪费时间,也扩大了跨仓库并发和恢复歧义。
|
|
12
|
+
|
|
13
|
+
## 能力所有者
|
|
14
|
+
|
|
15
|
+
- `release-publish.mjs` 是工具链候选工件、验证凭据和 npm/Git 发布状态的唯一所有者。
|
|
16
|
+
- Git `master` 是源码与版本清单事实源;冻结 tarball 是待发布字节事实源;npm 和 Git
|
|
17
|
+
tag 只保存已经发布的不可变结果。
|
|
18
|
+
- 独立 reference app 只拥有自身源码和 lockfile。工具链发布器可在隔离副本中消费它做
|
|
19
|
+
验收,但不得在 npm 发布事务中修改其工作树。
|
|
20
|
+
- AI、CLI 会话和 reference 仓库均不拥有发布状态,也不能临场选择版本、测试范围或
|
|
21
|
+
跳过门禁。
|
|
22
|
+
|
|
23
|
+
## 稳定不变量与命令合同
|
|
24
|
+
|
|
25
|
+
1. `pnpm verify:release` 是正式候选的准备与验证入口。它只打包一次,运行机器规划的
|
|
26
|
+
正式门禁,并留下 phase 为 `validated` 的凭据。
|
|
27
|
+
2. 凭据绑定精确 Git HEAD、registry、普通/全量模式、候选包版本、工件清单摘要以及
|
|
28
|
+
每个 tarball 的 SHA-256、npm integrity 和字节数。
|
|
29
|
+
3. `pnpm release:publish` 只接受同一提交的 `validated` 凭据;没有凭据或凭据仍为
|
|
30
|
+
`planned` 时在第一次 registry 写入前失败,并提示先执行对应 verify 命令。
|
|
31
|
+
4. publish 重新检查主线、候选尚未被并发发布、dist-tag 可恢复状态和全部工件摘要,
|
|
32
|
+
但不重复 check/test/build、Chromium、reference、Skills 或文档门禁。
|
|
33
|
+
5. `verify:release:full` 生成 full 凭据,只能由 `release:publish:full` 消费;普通与全量
|
|
34
|
+
模式不能交叉复用。
|
|
35
|
+
6. reference 验收继续使用一次性 loopback registry 中的同一批冻结 tarball;发布后
|
|
36
|
+
lockfile 收敛由显式 `pnpm release:sync-reference` 完成,不影响 npm/Git 发布成功。
|
|
37
|
+
7. 1.x 仓库、应用、流程、自动化和发布脚本不读取该凭据,也不进入本门禁。
|
|
38
|
+
|
|
39
|
+
## 失败、并发与资源边界
|
|
40
|
+
|
|
41
|
+
- 验证失败保留 `planned` 凭据和冻结工件,修复源码形成新提交后可安全废弃;同一提交
|
|
42
|
+
重试 verify 复用工件并重新执行尚未成功的正式门禁。
|
|
43
|
+
- publish 在每个不可逆阶段前后原子写凭据。进程中断后,已发布且 integrity 一致的包
|
|
44
|
+
被跳过;内容不同、外部 dist-tag 漂移或 Git tag 指向其他提交时 fail closed。
|
|
45
|
+
- 一旦进入 `publishing-packages`,凭据不能跨 Git 提交重建或丢弃;必须在原提交上恢复
|
|
46
|
+
到 npm 内容、dist-tag 和 Git tag 全部收敛。
|
|
47
|
+
- reference 工作树脏、不可访问或锁文件尚未同步不再发生在 registry 事务内,因而不会
|
|
48
|
+
把“包已发布”伪装成“发布失败”。显式同步仍要求 reference 的 `master` 干净且与远端
|
|
49
|
+
一致。
|
|
50
|
+
- 凭据和 tarball 位于 Git 私有目录,不进入应用包或 npm;文件权限为 0600。状态机不
|
|
51
|
+
持有 npm token、应用 Secret 或用户数据。验证次数从两次降为一次,不增加浏览器、
|
|
52
|
+
PostgreSQL 或临时 registry 的并发实例。
|
|
53
|
+
|
|
54
|
+
## 受影响合同与回滚边界
|
|
55
|
+
|
|
56
|
+
这是 2.0 工具仓维护命令的 breaking workflow change:发布者必须先 verify,再
|
|
57
|
+
publish。公开 npm 包内容、应用运行时协议、Data API、Workflow 和平台数据库均不变。
|
|
58
|
+
回滚单元仅包含发布脚本、测试、文档和 Skill;尚未写 registry 时可以整体回滚。开始
|
|
59
|
+
写 registry 后只能依照原凭据向前恢复,不能用代码回滚覆盖已发布版本。
|
|
60
|
+
|
|
61
|
+
## 可证伪验证
|
|
62
|
+
|
|
63
|
+
1. 无凭据直接 publish 在任何 npm 写调用前失败。
|
|
64
|
+
2. verify 成功后 receipt 为 `validated`,第二次 verify 不重跑门禁,publish 复用同一
|
|
65
|
+
manifest/tarball 并不调用 `release-validate.mjs`。
|
|
66
|
+
3. 修改 HEAD、registry、full 模式、manifest 或任一 tarball 后,publish 在写入前失败。
|
|
67
|
+
4. 在 `planned`、`validated`、`publishing-packages`、`packages-published`、
|
|
68
|
+
`dist-tags-synchronized` 注入中断,重试只执行允许的后续阶段。
|
|
69
|
+
5. reference 仓库脏时,正式 publish 状态机测试仍可完成;显式 sync 单独给出清晰错误。
|
|
70
|
+
6. release 脚本单测、边界扫描、2.0 受影响验证和模拟 registry 故障测试通过,测试不得
|
|
71
|
+
连接真实写权限 registry。
|
|
72
|
+
|
|
@@ -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
|
|
26
|
+
4. `pnpm verify:release` 从干净的远端 `master` 生成一次带摘要的候选工件清单;候选安装和 reference 验证消费相同 tarball,只执行一次正式验证,并留下绑定 HEAD、registry、模式和工件摘要的 `validated` receipt。`pnpm release:publish` 没有该凭据就拒绝写 registry,只重复不可变与并发前置检查后发布同一批字节,不重新打包或重跑门禁。公开 registry 发布完成后,通过独立的 `pnpm release:sync-reference` 收敛 reference 仓库锁文件;跨仓库同步不属于 npm 发布事务。
|
|
27
27
|
从源码创建候选 tarball 前,制品入口按候选包及其 workspace 依赖统一执行一次 Turbo 增量构建;不能直接打包工作区里可能过期的 `dist`。如果输入已经是带摘要的 release artifact manifest,则跳过构建并只消费冻结制品。
|
|
28
28
|
5. 每次候选都在全新独立项目安装真实 tarball 并完成 generate/check/test/build;浏览器相关变化再执行完整 Chromium E2E。
|
|
29
29
|
6. 平台集成测试部署到测试环境;只有平台协议或部署能力变更才需要阻塞核心发布。
|
|
@@ -42,8 +42,9 @@ reviewed Changesets
|
|
|
42
42
|
-> immutable tarball/version preflight
|
|
43
43
|
-> deterministic affected validation plan
|
|
44
44
|
-> candidate closure + independent tarball verification
|
|
45
|
+
-> validated receipt
|
|
45
46
|
-> npm publish of the exact validated tarballs
|
|
46
|
-
-> published reference lock synchronization + frozen install
|
|
47
|
+
-> explicit published reference lock synchronization + frozen install
|
|
47
48
|
-> independent-project acceptance
|
|
48
49
|
-> immutable promotion
|
|
49
50
|
```
|
|
@@ -54,7 +55,7 @@ Changeset,但包版本只能由 Changesets 物化,最终范围由 Git diff
|
|
|
54
55
|
`master` 可审计提交,Git 中的 package.json、候选 tarball、npm 版本和 Git tag
|
|
55
56
|
共同指向同一份源码事实。
|
|
56
57
|
|
|
57
|
-
增量门禁不是按文件名随意跳测试:计划器读取 npm 当前版本和上一发布版本,解包并比较真实发行物。候选包和依赖闭包永远 check/test/build,候选 tarball 永远安装进全新应用。Admin 或浏览器契约变化触发 Chromium;核心 SDK/后端/Workflow 变化触发 reference app;Skill Kit 变化触发 Skill 与文档;未知包、没有可比较前版或显式 `--full`
|
|
58
|
+
增量门禁不是按文件名随意跳测试:计划器读取 npm 当前版本和上一发布版本,解包并比较真实发行物。候选包和依赖闭包永远 check/test/build,候选 tarball 永远安装进全新应用。Admin 或浏览器契约变化触发 Chromium;核心 SDK/后端/Workflow 变化触发 reference app;Skill Kit 变化触发 Skill 与文档;未知包、没有可比较前版或显式 `--full` 一律运行完整矩阵。`verify:release` 成功后固定门禁证据,正式写 registry 前只再次确认候选版本仍未被并发发布以及 receipt 和工件未变化。
|
|
58
59
|
|
|
59
60
|
## OAuth2 外部应用身份
|
|
60
61
|
|
package/docs/delivery.md
CHANGED
|
@@ -44,15 +44,15 @@ Changesets 管理各个 `openxiangda-*` 包、CLI、MCP 与 skill-kit 的独立
|
|
|
44
44
|
|
|
45
45
|
版本物化是发布状态机的独立步骤:`pnpm release:version` 只允许在干净、已同步 `origin/master` 的 `master` 上运行,把尚未消费的评审 Changesets 确定性写入包版本、内部依赖和模板 BOM;它不提交、不发包。生成 diff 经审核、提交并推送后,才允许 `release:plan`、`verify:release` 或 `release:publish` 识别候选。这样 Git 中的版本清单是 npm 工件和 Git tag 的唯一源码事实,不使用临时目录里的虚拟版本,也不允许手工跳过物化。
|
|
46
46
|
|
|
47
|
-
`release
|
|
47
|
+
`verify:release` 在真正写 registry 前执行不可变版本门禁:未发布版本进入候选集;已经发布的版本则分别解包 registry 工件和当前本地包并逐文件比较。相同内容视为未变包,不重复发布;任何内容差异都必须先用 Changesets 产生新版本;没有新版本时拒绝空发布。`release:publish` 只消费该门禁形成的验证凭据。发布范围、版本和是否允许写入由机器判定,不由 AI 临场决定。
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
`verify:release` 只打包一次,并在 Git 私有目录写入绑定源码 `HEAD`、registry、验证模式、包版本、字节数、SHA-256 与 npm SHA-512 integrity 的工件清单和 `validated` receipt。全新应用、独立 reference app 与正式 npm publish 必须消费同一批 `.tgz`;`release:publish` 没有对应凭据就拒绝写入,任何字节或清单变化也都会在写 registry 前失败。部分发布中断后可以从 receipt 继续:已经发布且 integrity 一致的包被跳过,不一致则停止。npm 在逐包写入时可能先推进预发布 tag;receipt 只接受这一个可恢复中间态,并在所有包确认后统一收敛最终 dist-tag 和 Git tag。
|
|
50
50
|
|
|
51
|
-
`pnpm verify:local` 是日常可重复执行的全量验收入口。涉及本地 PostgreSQL 生命周期时,候选 tarball 只在 monorepo 外的新应用中运行一次 Chromium:生命周期门禁先通过受所有权校验的 reset 建立确定性数据库,再让同一浏览器套件同时经过 React、本地平台、NestJS 与 PostgreSQL;不会先跑 UI-only 再重复浏览器工作,也不会清理开发者现有应用的数据。正式候选在版本提交推送后由 `pnpm release:plan` 比较 npm 与本地 tarball,并比较候选与上一发布版本;漏升版或待消费 Changeset 会在昂贵测试前直接失败。`pnpm release
|
|
51
|
+
`pnpm verify:local` 是日常可重复执行的全量验收入口。涉及本地 PostgreSQL 生命周期时,候选 tarball 只在 monorepo 外的新应用中运行一次 Chromium:生命周期门禁先通过受所有权校验的 reset 建立确定性数据库,再让同一浏览器套件同时经过 React、本地平台、NestJS 与 PostgreSQL;不会先跑 UI-only 再重复浏览器工作,也不会清理开发者现有应用的数据。正式候选在版本提交推送后由 `pnpm release:plan` 比较 npm 与本地 tarball,并比较候选与上一发布版本;漏升版或待消费 Changeset 会在昂贵测试前直接失败。`pnpm verify:release` 冻结一次候选工件并执行机器生成的增量计划;候选依赖闭包永远完成 check/test/build,每个候选 tarball 都在 monorepo 外安装进全新生成应用并完成 generate/check/test/build。浏览器相关变化提升到真实 Chromium E2E,核心应用 SDK 变化增加持久 reference app,Skill/文档变化增加相应门禁。成功凭据随后由 `release:publish` 复用,发布命令不再重跑这些门禁。未知变化 fail-closed 到完整矩阵;周期审计使用匹配的 `verify:release:full` 与 `release:publish:full`。
|
|
52
52
|
|
|
53
53
|
Playwright 浏览器使用官方缓存目录;`playwright install chromium` 已安装对应版本时是无操作。发包门禁不会额外运行 1.x 测试,也不会为每个包重复浏览器验收,而是在最终独立新应用上只运行一次完整用户路径。
|
|
54
54
|
|
|
55
|
-
当计划要求 reference app 时,工具仓只把本次候选包发布到一次性、仅绑定 `127.0.0.1` 的 registry。每个候选包按精确包名注册为本地权威源且禁止回源,防止同版本公网包抢先占位或旧包被静默安装;未变化的包和普通依赖才继续从 npm 代理取得。验收副本不复用 reference worktree 的 lockfile,而是在临时目录从本轮 registry 生成一次 scratch-only lock,避免尚未物化新版本时相同预发布版本的旧 integrity 触发无意义重试;源仓锁文件不会被隐式修改。持久独立 reference app 再执行安装、契约生成、类型检查、单测、真实 NestJS 身份/Data API 进程验收和生产构建。`pnpm reference:install:from-build` 可在未公开发包时通过同一 registry 协议刷新 reference worktree 的本地依赖,避免 `file:`/`link:`
|
|
55
|
+
当计划要求 reference app 时,工具仓只把本次候选包发布到一次性、仅绑定 `127.0.0.1` 的 registry。每个候选包按精确包名注册为本地权威源且禁止回源,防止同版本公网包抢先占位或旧包被静默安装;未变化的包和普通依赖才继续从 npm 代理取得。验收副本不复用 reference worktree 的 lockfile,而是在临时目录从本轮 registry 生成一次 scratch-only lock,避免尚未物化新版本时相同预发布版本的旧 integrity 触发无意义重试;源仓锁文件不会被隐式修改。持久独立 reference app 再执行安装、契约生成、类型检查、单测、真实 NestJS 身份/Data API 进程验收和生产构建。`pnpm reference:install:from-build` 可在未公开发包时通过同一 registry 协议刷新 reference worktree 的本地依赖,避免 `file:`/`link:` 破坏独立性。公开 npm integrity 的采用由发布成功后的 `pnpm release:sync-reference` 显式执行;reference 工作树状态不会参与 registry 事务。
|
|
56
56
|
|
|
57
57
|
增量门禁先用 Turbo 完成候选包及其依赖闭包的 check/test/build;全量模式完成整个 workspace。后续生成契约、tarball 黑盒、技能校验和文档构建复用已验证的 `dist`。`distribution:smoke`、`skills:check`、`docs:build` 仍保留可独立执行的自包含入口。
|
|
58
58
|
|
package/docs/frontend.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 前端架构
|
|
2
2
|
|
|
3
|
-
状态:2026-08-16
|
|
3
|
+
状态:2026-08-16 桌面 Admin 已发布;独立移动用户端标准页面包和生成模板双入口已经实现,移动 Chromium 已覆盖身份、数据与流程提交主链路。旧自研 Shell 与 Vite 模板已经删除,企业采购参考应用已通过类型检查、测试、Umi production build 与桌面/移动 Chromium 验收。完整决策见[Ant Design Pro v6 Admin 全量切换](/architecture/ant-design-pro-v6-admin-foundation)、[移动用户端标准页面](/architecture/mobile-user-standard-pages-v2),状态证据见[实施路线图](/architecture/implementation-roadmap)。
|
|
4
4
|
|
|
5
5
|
## 默认技术栈
|
|
6
6
|
|
|
@@ -56,11 +56,11 @@ OpenXiangda 2.0 桌面管理端采用 React 19、Ant Design 6、Umi Max 4、ProC
|
|
|
56
56
|
所有平台字段使用 `openxiangda-field-kit` 的稳定值协议。人员、部门、单选、多选、单选框、复选框、日期、日期区间、地址、关联、图片、附件、数值等都由统一定义驱动存储与显示。
|
|
57
57
|
|
|
58
58
|
- 桌面 Admin 从 `openxiangda-field-kit/desktop` 使用 Ant Design 控件。
|
|
59
|
-
-
|
|
59
|
+
- 移动用户端由 `openxiangda-user/mobile` 提供工作台、数据列表/表单/详情和流程提交/任务/实例页面,并从 `openxiangda-field-kit/mobile` 使用 Ant Design Mobile 的独立字段交互;不把桌面 Select、DatePicker 或 Cascader 缩小后复用。
|
|
60
60
|
- 人员、部门、行政区、关联数据、上传、下载和预览都通过平台 API;应用不自行复制平台目录或文件协议。
|
|
61
61
|
- UI 必填、默认值、显隐、布局和帮助文本属于页面层;后端业务不应假设自定义页面一定执行了前端校验。
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
生成模板将桌面 Admin 与移动用户端放在同一个 AppPackage 的两个独立懒加载路由树中;`/admin` 只加载 Pro 页面,`/m` 只加载 `openxiangda-user/mobile`,根入口按设备能力一次性选择。移动 Chromium 已验证两棵树不混用 DOM,并覆盖稳定角色切换、列表/详情、流程发起与平台特殊字段。
|
|
64
64
|
|
|
65
65
|
## 本地开发与门禁
|
|
66
66
|
|
|
@@ -73,6 +73,6 @@ pnpm --filter @app/web test:e2e
|
|
|
73
73
|
pnpm --filter @app/web build
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
CLI 同时监督 Umi、NestJS、本地平台与工作区 PostgreSQL。UI-only
|
|
76
|
+
CLI 同时监督 Umi、NestJS、本地平台与工作区 PostgreSQL。UI-only 只用于非持久化界面预览。桌面 Chromium 链路覆盖工作台、菜单、标签、角色切换、数据列表/详情、供应商标准表单、流程工作中心、单按钮流程提交与个人中心;移动 Chromium 链路覆盖自动入口、独立 UI 树、角色切换、数据列表/详情、流程发起和平台字段。两条链路都断言没有浏览器运行时错误。
|
|
77
77
|
|
|
78
78
|
生产构建分别约束首屏脚本、异步 chunk 的 gzip/原始体积与开发标记;不得包含模板假用户、Umi Mock、开发 Secret、Vite 或旧 AdminShell。
|
package/docs/getting-started.md
CHANGED
|
@@ -70,10 +70,11 @@ pnpm verify:local
|
|
|
70
70
|
pnpm release:version
|
|
71
71
|
# review, commit and push the generated version diff
|
|
72
72
|
pnpm release:plan
|
|
73
|
+
pnpm verify:release
|
|
73
74
|
pnpm release:publish
|
|
74
75
|
```
|
|
75
76
|
|
|
76
|
-
`release:version` 不提交、不发包,只把 Changesets 确定的候选版本写入 Git 工作树;未完成这一步时,后续所有发布命令会在构建前失败。`release:plan` 会完成 npm 不可变性检查并比较候选包与上一发布版本的真实 tarball。`release
|
|
77
|
+
`release:version` 不提交、不发包,只把 Changesets 确定的候选版本写入 Git 工作树;未完成这一步时,后续所有发布命令会在构建前失败。`release:plan` 会完成 npm 不可变性检查并比较候选包与上一发布版本的真实 tarball。`verify:release` 冻结一批带摘要的候选 tarball,只针对这批工件执行一次正式增量门禁,并留下不可变验证凭据;`release:publish` 必须消费该凭据,只复查并发与摘要后发布同一批字节,不会重复测试。真实 PostgreSQL 生命周期门禁也只在本地平台、开发生命周期或相关模板发生变化时运行。无法分类的新包或变化自动升级为全量验证,周期审计使用配对的 `pnpm verify:release:full` 和 `pnpm release:publish:full`。发布后需要更新独立 reference 仓库时,再显式执行 `pnpm release:sync-reference`。
|
|
77
78
|
|
|
78
79
|
## OAuth2 应用身份
|
|
79
80
|
|
package/package.json
CHANGED
|
@@ -51,11 +51,15 @@ the monorepo into a newly generated application. Admin/browser changes require
|
|
|
51
51
|
Chromium, core application SDK changes require the independent reference app,
|
|
52
52
|
and Skill Kit changes require Skills/docs. Unknown or first-release packages
|
|
53
53
|
fail closed to the full matrix. Run `pnpm verify:release:full` for the periodic
|
|
54
|
-
complete audit. `pnpm release
|
|
55
|
-
runs the formal gate once, and
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
complete audit. `pnpm verify:release` freezes one candidate artifact manifest,
|
|
55
|
+
runs the formal gate once, and leaves a validated receipt bound to the exact
|
|
56
|
+
HEAD, registry, mode and tarball digests. `pnpm release:publish` requires that
|
|
57
|
+
receipt, repeats only immutable/concurrency preconditions, and publishes those
|
|
58
|
+
exact bytes without rerunning the formal gate. Use `verify:release:full` only
|
|
59
|
+
with `release:publish:full`. The final publish command repeats version
|
|
60
|
+
availability before writing npm, so concurrent publication cannot invalidate
|
|
61
|
+
the reviewed plan. It never modifies the independent reference worktree;
|
|
62
|
+
`pnpm release:sync-reference` is an explicit post-publication repository task.
|
|
59
63
|
`pnpm distribution:smoke` runs only this packed-distribution verification.
|
|
60
64
|
Keep `strictDepBuilds: true` in the official workspace and template. Permit only
|
|
61
65
|
reviewed dependency lifecycle scripts (`esbuild` today); never suppress the
|
|
@@ -22,12 +22,14 @@ Build in `apps/web` with React 19, Ant Design 6, Umi Max 4 and ProComponents 3.
|
|
|
22
22
|
|
|
23
23
|
## Platform fields and mobile user UI
|
|
24
24
|
|
|
25
|
-
1. Use `openxiangda-field-kit/desktop` in the desktop Admin
|
|
25
|
+
1. Use `openxiangda-field-kit/desktop` in the desktop Admin. Build the independent mobile tree with `OpenXiangdaUserProvider` from `openxiangda-user` and the standard pages from `openxiangda-user/mobile`; those pages consume `openxiangda-field-kit/mobile`. Mobile is not a CSS-responsive copy of the Admin.
|
|
26
26
|
2. Platform fields include all supported kinds, not only personnel and files: text/textarea, number/money/percent, boolean, single/multiple select, radio/checkbox/cascade, date/datetime/date range, user/users, department/departments, relation, address/location, image/attachments, signature, subtable/JSON, serial and workflow status.
|
|
27
27
|
3. Persist established stable values. Directory/option/relation values use `{ label, value }`; address, location and attachment values use the `openxiangda-field-kit` types. Never replace them with display-only strings or Ant Design component instances.
|
|
28
28
|
4. Personnel, departments, administrative divisions, relations, uploads, downloads and previews must use platform APIs. Do not copy platform directory data or write a second upload protocol.
|
|
29
29
|
5. Keep database declarations minimal: field code, storage type, nullability, index and storage constraints. Required/default/hidden/layout/help/conditional display are page behavior. A custom page may implement different UI validation, so critical business rules must also be enforced by NestJS/Data API policy.
|
|
30
30
|
6. Render list/detail values by field kind. Show readable labels, tags, formatted dates/numbers/amounts, address text, user/department identity, image preview and attachment download instead of raw JSON or internal IDs.
|
|
31
|
+
7. Prefer `MobileAppShell`, `MobileWorkbenchPage`, `MobileResourceListPage`, `MobileResourceFormPage`, `MobileResourceDetailPage`, `MobileWorkflowSubmissionPage`, `MobileWorkflowWorkCenterPage`, `MobileWorkflowTaskPage` and `MobileWorkflowInstancePage`. The Workflow submission page must show only the business form and one Submit action until save and prepare succeed; only then open the approval preview.
|
|
32
|
+
8. Keep the mobile package out of NestJS dependencies. The browser may call only platform-relative Native clients under the current RoleSession; it must not persist platform tokens, service addresses, permission decisions or business responses.
|
|
31
33
|
|
|
32
34
|
## Verification
|
|
33
35
|
|