openxiangda 2.67.2 → 2.67.4
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/documentation/AGENTS.md +1 -0
- package/documentation/application-operations.md +23 -0
- package/documentation/concepts.md +2 -0
- package/documentation/data-authz.md +2 -0
- package/documentation/getting-started.md +7 -7
- package/documentation/manifest.json +14 -8
- package/documentation/multi-organization.md +152 -0
- package/documentation/product-design.md +2 -0
- package/documentation/reference/mcp.md +270 -0
- package/documentation/workflow-events.md +5 -0
- package/package.json +24 -24
- package/releases/2.67.3.json +39 -0
- package/releases/2.67.4.json +34 -0
- package/skills/manifest.json +1 -1
- package/skills/openxiangda-v2/SKILL.md +7 -4
- package/skills/openxiangda-v2/references/application-operations.md +23 -0
- package/skills/openxiangda-v2/references/concepts.md +2 -0
- package/skills/openxiangda-v2/references/data-authz.md +2 -0
- package/skills/openxiangda-v2/references/getting-started.md +7 -7
- package/skills/openxiangda-v2/references/mcp.md +270 -0
- package/skills/openxiangda-v2/references/multi-organization.md +152 -0
- package/skills/openxiangda-v2/references/product-design.md +2 -0
- package/skills/openxiangda-v2/references/workflow-events.md +5 -0
- package/releases/2.63.0.json +0 -45
- package/releases/2.63.1.json +0 -46
- package/releases/2.66.0.json +0 -29
- package/releases/2.66.1.json +0 -29
- package/releases/2.66.2.json +0 -29
- package/releases/2.67.0.json +0 -33
- package/releases/2.67.1.json +0 -35
- package/releases/2.67.2.json +0 -34
package/documentation/AGENTS.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
- 模型、页面、导航和权限由应用声明一次;编译器生成契约。业务代码不改生成结果、不创建 platform/data、不复制平台 Router、字段组件、客户端或权限状态。
|
|
9
9
|
- 当前用户、角色并集、数据授权和部署状态归平台;应用不保存凭据或授权快照。普通 CRUD 走 Data API,真实业务动作才按需启用 Nest。想写后端接口时先按 docs development 的"判定是否真的需要 Nest 后端"逐行核对:列表/表单/详情/删除用 `createNativeResourceClient`,幂等、时间窗、状态前置用平台事务与守卫,聚合用服务端聚合;check 会拒绝未绑定已声明 operation 的应用 controller 路由。
|
|
10
|
+
- 教育局与独立学校企业、多校家长、多组织教师、家校角色或班级范围需求先读 `docs multi-organization`(MCP `docs_read` 同一 topic)。平台维护组织、安装、成员与来源身份;应用不另建企业树或钉钉身份库。核对当前 HTTP/SDK 可用入口、待接通的组织数据权限和实际站点状态,不能把 `corpId` 或组织树当授权证明。
|
|
10
11
|
- 标准业务字段使用 `openxiangda/field-kit`;PC 补充控件使用 antd,移动使用有作用域的 `openxiangda/mobile` 和 MobileSurface,不引入上游全局重置。
|
|
11
12
|
- 界面开发默认按 docs design-workflow 由当前 Agent 完成视觉、真实页面实现和浏览器修正;需要新视觉方向时可用 Image 2.5 等当前图片能力生成少量参考。图片不定义交互、权限或验收。设备由真实任务决定;复用 Shell 导航事实、标准字段行为,通过 ui 和局部样式应用设计,不复制权限或导航状态。采用的参考图、tokens 和必要原型以 AppSpec assets 固定。模板 /home 不替代页面选型。
|
|
12
13
|
- 有管理任务时选择可编辑后台源码模板,通过 ui.admin.shell 挂载唯一外壳;PC、移动与登录外观分别选择模板。应用可自行重构页面;resourcePages 和 openxiangda/resource 提供获准扩展边界。平台拥有路由、身份、授权、数据及登录行为。既有页面保留 SDK fallback,模板初始化不自动覆盖应用;没有管理任务时不强行加后台。选模板前读 docs application-templates 或 template list / MCP template_list,已有授权无需额外确认。
|
|
@@ -183,3 +183,26 @@ Native记录事件才能使用 `ordering:record`。订阅错误先修正应用
|
|
|
183
183
|
重启MCP。应用AI不需要本地平台、数据库、Docker或学校服务器账号。
|
|
184
184
|
先做只读诊断、无实际收件人的健康测试及CAS拒绝验证,再验收单笔回执/落库/实际投递。
|
|
185
185
|
不要用批量导入或历史群发测试恢复。首次会话授权、权限委托和外部身份owner边界沿用原合同。
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
## TEST 验收数据收尾 {#acceptance-data}
|
|
189
|
+
|
|
190
|
+
需要回收的验收先从目录选择 `acceptance-data.prepare`,显式提供原 requestKey、当前 TEST AppVersion/Head、actors;默认 100 条累计创建和 240 分钟,最高 1000 条/一天。目录的 actor schema 与原身份规则一致。普通验收身份未 opt-in,不自动归入可回收批次。平台仅接受简单 Native CRUD;workflow、文件、事件、通知、外部效果或压测批次继续使用各自 owner。
|
|
191
|
+
|
|
192
|
+
创建结果中的 runId 和一次性登录链接用于本批真实身份操作。文件中仅存下列 input,当前 workspace 提供应用、站点和身份:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{"runId":"<原批次UUID>"}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
先执行 `admin execute acceptance-data.stop --environment test --input <文件> --json`;超时先用 `acceptance-data.status` 核对原 run,stopped 表示后续批次写入被拒绝。用户/成员仍保留;会话撤销 pending 不改变已经提交的 stop 栅栏。再执行 `acceptance-data.preview-cleanup`,核对 actionCount、remainingRecordCount、manifestSha256 和原 repairReference。
|
|
199
|
+
|
|
200
|
+
真正执行只传原 preview digest:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{"runId":"<原批次UUID>","manifestSha256":"<预览SHA256>","mode":"canary"}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
在已经授权清理的范围运行 `acceptance-data.execute-cleanup`,核对金丝雀原回执,再把 mode 改为 remaining。丢响应先 preview/status,不换 run 或 digest;pending 清单复用原 repair。每份计划最多100条/1MiB,终结后重新 preview 下一批。外部修改、坏凭证、变化 Head、未知/预算结果及部分失败不会返回 purged。只有完整读回 `cleanupState: purged` 和剩余0表示此批 owned Native 数据验空;registry、参与者、凭证、审计和原修复回执保留。
|
|
207
|
+
|
|
208
|
+
MCP仍通过 `application_operations/application_operation` 使用同一目录,不提供任意URL或重建来源。生产、旧数据、其他run不接受此入口。目录可用不代表目标平台已升级;404核对版本,不用直接SQL旁路。
|
|
@@ -27,6 +27,8 @@ flowchart LR
|
|
|
27
27
|
|
|
28
28
|
## 数据边界
|
|
29
29
|
|
|
30
|
+
教育局与独立学校企业、多校家长、多组织教师等场景复用平台组织注册、安装、成员和工作组织上下文。应用不另建身份或企业组织树;已实现 HTTP 契约、家校角色/班级事实与尚未接通的 SDK/组织数据权限见[多组织与家校目录](./multi-organization.md)。组织树存在不代表 Data API 已自动执行跨组织授权。
|
|
31
|
+
|
|
30
32
|
首期不为应用创建独立数据库。业务后端通过统一 Data API 访问平台数据;Data API 提供资源化查询、字段策略、行级授权、并发修订和受限事务批处理。这样保留统一治理,又不限制应用后端表达业务逻辑。
|
|
31
33
|
|
|
32
34
|
应用后端声明具名 Operation 时,不应重新手写用户、部门、资源引用和文件字段协议。`openxiangda/config` 提供 `resourceRecordSchema`、`schemaRef`、`composeJsonSchema` 和 `composeAppOperationSchemas`:它们从同一 Resource declaration 和公共 `FIELD_VALUE_SCHEMAS` 投影请求/响应 JSON Schema,只允许有界的本地 `$defs`/`$ref`,不会改变 Data API、权限或业务事务 owner。
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
授权由四层组成:页面/操作 capability、行谓词、字段 read,以及字段 create/update。前端只消费平台返回的最终访问结果来隐藏按钮、只读输入和剔除 payload;平台每次请求重新执行权威校验。
|
|
4
4
|
|
|
5
|
+
涉及独立企业的上下级组织、跨学校身份或家校班级范围时,先读[多组织与家校目录](./multi-organization.md)。平台已有组织/成员/会话基础;V2 角色 reach、目录事实应用映射和组织行边界尚未完整接通,不能将当前普通角色并集、unrestricted 规则或前端 `corpId` 当成自动跨组织授权。
|
|
6
|
+
|
|
5
7
|
以下仅以仪器管理应用举例,不是平台默认模型或角色。该示例的行规则是:学校管理员不受行谓词限制;学院管理员按记录 `collegeId` 匹配;仪器管理员按 `instrumentAdminIds` 包含当前用户匹配。不要增加影子范围字段。
|
|
6
8
|
|
|
7
9
|
`collegeId` 是应用 `colleges` Native Resource 的记录 UUID。学院 scope dimension 通过
|
|
@@ -68,10 +68,10 @@ MCP 服务随项目根包一起安装,AI 客户端的 stdio 连接仍需配置
|
|
|
68
68
|
以下命令的版本占位符由随包资料替换为该根包的精确版本。网站源码阅读者应先确认要使用的发行版本。
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
|
-
pnpm dlx openxiangda@2.67.
|
|
72
|
-
pnpm dlx openxiangda@2.67.
|
|
73
|
-
pnpm dlx openxiangda@2.67.
|
|
74
|
-
pnpm dlx openxiangda@2.67.
|
|
71
|
+
pnpm dlx openxiangda@2.67.4 skill install --force
|
|
72
|
+
pnpm dlx openxiangda@2.67.4 auth status --base-url <平台地址> --json
|
|
73
|
+
pnpm dlx openxiangda@2.67.4 login --cwd my-app --base-url https://platform.example.com
|
|
74
|
+
pnpm dlx openxiangda@2.67.4 create my-app --base-url https://platform.example.com
|
|
75
75
|
cd my-app
|
|
76
76
|
pnpm openxiangda context --json
|
|
77
77
|
pnpm openxiangda dev
|
|
@@ -206,9 +206,9 @@ MCP 的 `docs_read` 可以读取本说明,当前没有独立的源码操作 MC
|
|
|
206
206
|
无需本地工作区,使用本 Skill 随包精确版本或已安装的对应 CLI:
|
|
207
207
|
|
|
208
208
|
```bash
|
|
209
|
-
pnpm dlx openxiangda@2.67.
|
|
210
|
-
pnpm dlx openxiangda@2.67.
|
|
211
|
-
pnpm dlx openxiangda@2.67.
|
|
209
|
+
pnpm dlx openxiangda@2.67.4 auth status --base-url <平台> --json
|
|
210
|
+
pnpm dlx openxiangda@2.67.4 source resolve <仓库URL> --base-url <平台> --json
|
|
211
|
+
pnpm dlx openxiangda@2.67.4 source clone <仓库URL> <新目录> --base-url <平台> --json
|
|
212
212
|
```
|
|
213
213
|
|
|
214
214
|
登录缺失或站点不匹配时,先按该平台执行 login。resolve 根据平台已经登记的绑定返回
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "openxiangda.documentation/v1",
|
|
3
|
-
"version": "2.67.
|
|
3
|
+
"version": "2.67.4",
|
|
4
4
|
"topics": [
|
|
5
5
|
{
|
|
6
6
|
"id": "getting-started",
|
|
7
7
|
"title": "安装与开始开发",
|
|
8
8
|
"file": "getting-started.md",
|
|
9
|
-
"sha256": "
|
|
9
|
+
"sha256": "39aecb85f42c043e27a4b2b5f833e32e1a8f7dc4b6f9e7d91041fafeb95705fa"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"id": "product-design",
|
|
13
13
|
"title": "对话发现与详细产品设计",
|
|
14
14
|
"file": "product-design.md",
|
|
15
|
-
"sha256": "
|
|
15
|
+
"sha256": "796d6a41ed63cfc708802def95b9a8cb13e0486c75bbe162692f15341b5fbd4a"
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"id": "design-workflow",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"id": "concepts",
|
|
55
55
|
"title": "架构与能力所有者",
|
|
56
56
|
"file": "concepts.md",
|
|
57
|
-
"sha256": "
|
|
57
|
+
"sha256": "6c6dde8da42b71795004c3ac791dda26f4734e2914775859d22909b7d46659d1"
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
60
|
"id": "application-templates",
|
|
@@ -78,7 +78,13 @@
|
|
|
78
78
|
"id": "data-authz",
|
|
79
79
|
"title": "数据查询与权限",
|
|
80
80
|
"file": "data-authz.md",
|
|
81
|
-
"sha256": "
|
|
81
|
+
"sha256": "317ecd5c68c7a8713dfb01d96a82b58be0dff27cd5213374dacc68aa0c1911be"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "multi-organization",
|
|
85
|
+
"title": "多组织、局校管理与家校目录",
|
|
86
|
+
"file": "multi-organization.md",
|
|
87
|
+
"sha256": "ac57ad47e8f818cce1d0123b3d5a4d6559a1861e8f2bbe311e5687c8bd8d0928"
|
|
82
88
|
},
|
|
83
89
|
{
|
|
84
90
|
"id": "public-access",
|
|
@@ -90,7 +96,7 @@
|
|
|
90
96
|
"id": "workflow-events",
|
|
91
97
|
"title": "审批、事件与通知",
|
|
92
98
|
"file": "workflow-events.md",
|
|
93
|
-
"sha256": "
|
|
99
|
+
"sha256": "95bf0fb50d0d7e1866c952b92f8ecb674a324a8b909293cfb3c071851eb9f780"
|
|
94
100
|
},
|
|
95
101
|
{
|
|
96
102
|
"id": "backend",
|
|
@@ -138,7 +144,7 @@
|
|
|
138
144
|
"id": "application-operations",
|
|
139
145
|
"title": "AI 自助诊断、环境密钥和通知配置",
|
|
140
146
|
"file": "application-operations.md",
|
|
141
|
-
"sha256": "
|
|
147
|
+
"sha256": "d31ac969dabfab23fed865d6c5b3824cfd6e7437123a96c574c76a4e7e22178b"
|
|
142
148
|
},
|
|
143
149
|
{
|
|
144
150
|
"id": "testing",
|
|
@@ -168,7 +174,7 @@
|
|
|
168
174
|
"id": "mcp",
|
|
169
175
|
"title": "MCP 配置与工具参考",
|
|
170
176
|
"file": "reference/mcp.md",
|
|
171
|
-
"sha256": "
|
|
177
|
+
"sha256": "8d1ef95eaa131685cc8ec192160a12ea1f0794d95c0d3854568d93aeb187c7fd"
|
|
172
178
|
}
|
|
173
179
|
]
|
|
174
180
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# 多组织与家校目录
|
|
2
|
+
|
|
3
|
+
教育局与多所学校各有独立钉钉企业、同一教师属于多个组织、家长的孩子在不同学校时,优先复用平台的组织与身份基础能力。应用不再建立第二份企业组织树、钉钉身份库或学校密钥配置。
|
|
4
|
+
|
|
5
|
+
本专题描述 2026-10-13 的源码契约基线。组织基础能力已有服务器实现;应用 SDK、目录角色读取与跨组织数据权限尚有接入缺口。目标站点是否部署了这些接口,需现场核实;安装新工具或读到本专题不证明平台已经升级。
|
|
6
|
+
|
|
7
|
+
## AI 识别场景与选择能力 {#scenario}
|
|
8
|
+
|
|
9
|
+
遇到以下需求,先读本专题,再结合[数据与权限](./data-authz.md)和[按需后端](./backend.md)设计应用:
|
|
10
|
+
|
|
11
|
+
- 上级机构管理多个拥有独立钉钉企业的下级机构,例如教育局与学校。
|
|
12
|
+
- 一个企业三方应用安装到多个企业,统一同步普通通讯录和家校通讯录。
|
|
13
|
+
- 同一个人以不同组织身份进入同一应用,或在同一会话中切换学校。
|
|
14
|
+
- 使用教师、学生、家长、班主任来源身份及班级管理范围。
|
|
15
|
+
- 下级业务数据隔离、上级按授权看后代数据、上级发布下级可见的公共内容。
|
|
16
|
+
|
|
17
|
+
先识别“平台已经维护的事实”和“应用希望赋予的业务权限”。不把教育局、学校、作业或公告写成平台固定模型。用户已说明的组织归属、角色和权限意图直接沿用;技术接入缺口记录为平台依赖,不让用户重新设计一套身份体系。
|
|
18
|
+
|
|
19
|
+
## 平台负责什么与当前可用程度 {#availability}
|
|
20
|
+
|
|
21
|
+
| 能力 | 当前源码状态 | AI 可以据此做什么 |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| 真实企业组织、单父树、最多三级 | 已实现平台注册与查询 | 复用平台 `organization.id`、`corpId`、父级和祖先路径,不以部门替代企业组织 |
|
|
24
|
+
| 预开通与企业三方安装匹配 | 已实现显式 reconciliation;匹配后激活 | 由有权限的管理端预开通,核对真实企业名称;业务应用不保存各校 appSecret |
|
|
25
|
+
| 普通/家校目录同步投影 | 已实现主体、成员和来源角色事实存储 | 以平台同步事实为身份来源,不自行抓取后再维护一套通讯录 |
|
|
26
|
+
| 当前人的可切换组织 | 已有平台会话 HTTP 读取入口 | 读取本人活动成员列表,显示对应企业/学校选项 |
|
|
27
|
+
| 当前工作组织、同会话切换 | 已有平台登录上下文、HTTP 切换和原始授权响应字段 | 在支持本契约的会话中读取/切换;不能从 URL 直接产生授权 |
|
|
28
|
+
| 组织管理授权 | 已实现平台管理员授予人/部门,祖先授权覆盖后代 | 管理操作由平台核验;不能把“教育局成员”当作“全区管理员” |
|
|
29
|
+
| 应用角色 `self` / `subtree` | 传统平台角色 CRUD 能保存 `organizationReach`;V2 声明与执行尚未接通 | 在设计中明确每个角色的组织覆盖意图,不向 V2 config 填入未支持字段 |
|
|
30
|
+
| 家校事实到应用角色、班级范围的消费 | 平台已存事实,完整应用读取/映射契约尚未接通 | 声明拟使用哪些事实及范围,将接入列为依赖;不能凭空调用 SDK |
|
|
31
|
+
| 组织数据归属、隔离、后代可见与公共内容下发 | Native Data API 的组织边界尚未接通 | 不能宣称已经自动隔离或继承,也不能用前端筛选代替服务端权限 |
|
|
32
|
+
| 安装回调、每校自动定时同步、组织通知路由与链接生成 | 尚未完成整条自动接入 | 不假定安装完成后立即能登录,不假定消息自动选中正确安装 |
|
|
33
|
+
|
|
34
|
+
平台管理组织的授权与应用业务授权是两种事实。能开通学校或查询组织树,不会自动获得该学校的业务数据权限;看到一条成员关系,也不会自动成为应用管理员。
|
|
35
|
+
|
|
36
|
+
## 可直接取得的组织与会话信息 {#http-contracts}
|
|
37
|
+
|
|
38
|
+
以下是已实现的服务器 HTTP 契约,不是新增 SDK 导出或独立 MCP 工具。调用前确认目标站点版本、当前平台会话及其访问范围。开发期回环代理未覆盖这些路径时,不能自行把凭据放进 URL 或另建登录代理。
|
|
39
|
+
|
|
40
|
+
### 本人的可切换组织
|
|
41
|
+
|
|
42
|
+
`GET /openxiangda-api/v2/platform/organizations/me/memberships`
|
|
43
|
+
|
|
44
|
+
成功响应为 `{ code: 200, message, data: [...] }`。服务端只返回当前租户、当前用户的活动成员,并要求组织及安装均为 `active`;它不是所有学校列表,也不代表应用角色授权。空数组表示当前没有符合条件的成员,不能据此猜测一个 `corpId` 或创建成员。
|
|
45
|
+
|
|
46
|
+
每项包含:
|
|
47
|
+
|
|
48
|
+
| 字段 | 可直接使用的信息 |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| `membershipId` | 平台成员关系 ID |
|
|
51
|
+
| `organization.id` | 平台组织 ID,区别于钉钉 `corpId` |
|
|
52
|
+
| `organization.tenantId`、`provider`、`corpId` | 所属租户、来源提供方和真实企业标识 |
|
|
53
|
+
| `organization.name`、`providerName` | 平台名称及安装匹配时记录的企业名称 |
|
|
54
|
+
| `organization.parentId`、`level`、`ancestorIds` | 平台维护的父级、层级与祖先路径 |
|
|
55
|
+
| `organization.status`、`activatedAt` | 组织活动状态及激活时间 |
|
|
56
|
+
| `organization.installation` | 安装 ID、suiteKey、状态、agentId、授权 scopes、authorizationRevision 等摘要;没有密钥/token |
|
|
57
|
+
| `source`、`profile` | 成员来源与同步资料;profile 是可空的来源快照,不是能力或角色授权结果 |
|
|
58
|
+
|
|
59
|
+
最小只读示例,运行在已经验证支持此接口的同源平台会话中:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const response = await fetch(
|
|
63
|
+
'/openxiangda-api/v2/platform/organizations/me/memberships',
|
|
64
|
+
{ credentials: 'same-origin' },
|
|
65
|
+
);
|
|
66
|
+
const result = await response.json();
|
|
67
|
+
if (!response.ok || result.code !== 200 || !Array.isArray(result.data)) {
|
|
68
|
+
throw new Error(result.errorCode || '组织成员信息读取失败');
|
|
69
|
+
}
|
|
70
|
+
const organizations = result.data.map(item => ({
|
|
71
|
+
membershipId: item.membershipId,
|
|
72
|
+
organizationId: item.organization.id,
|
|
73
|
+
corpId: item.organization.corpId,
|
|
74
|
+
name: item.organization.providerName || item.organization.name,
|
|
75
|
+
}));
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
这是现有 HTTP 响应的局部消费示例。不要将其中的字段或方法名写成 `openxiangda/react` 已导出的组织客户端。
|
|
79
|
+
|
|
80
|
+
### 当前工作组织
|
|
81
|
+
|
|
82
|
+
- `POST /api/auth/profile` 返回 `data.activeOrganizationId`,没有工作组织时为 `null`。它是平台会话 profile 接口,不能误写为 GET。
|
|
83
|
+
- `GET /openxiangda-api/v2/applications/{appCode}/native/authz/current?environmentKey={preproduction|production}` 的原始成功响应,在已有工作组织时包含 `data.environment.activeOrganizationId`;有活动应用授权时也包含 `data.principal.activeOrganizationId`。无组织时不包含这些可选字段;`state=unassigned` 时 principal 为 `null`。
|
|
84
|
+
- `GET /openxiangda-api/v2/platform/organizations/context?corpId=...` 的 `data` 是活动组织 ID 字符串;尚未启用组织注册的传统租户返回 `null`。这个接口只解析租户内组织及安装状态,不证明调用人是成员,不会切换会话,也不授予权限。
|
|
85
|
+
|
|
86
|
+
当前浏览器 SDK 的 `RuntimeIdentity` 投影和 `useOpenXiangdaRuntime().identity` 尚未保留上述组织字段。Nest 的 `@CurrentUser()`/`OpenXiangdaCurrentUser` 尚未提供可信工作组织,Native principal 也尚未完整传递。不要写 `identity.activeOrganizationId` 或 `user.activeOrganizationId` 并声称可用;不要把前端传入的组织 ID 填到 Nest 的可信用户上下文。
|
|
87
|
+
|
|
88
|
+
### 同一会话切换组织
|
|
89
|
+
|
|
90
|
+
`POST /api/auth/organization/switch`,JSON body 为 `{ "organizationId": "平台组织ID" }`。
|
|
91
|
+
|
|
92
|
+
服务端从已有会话确定用户和租户,再检查目标活动组织、安装及该用户活动成员;保持同一登录会话并重发认证 cookies。无需重新登录另一个钉钉企业。成功 `data` 包含 `activeOrganizationId`、目标 `organization`、`memberships` 及认证 token 字段;浏览器使用服务端 cookies,不记录或另行持久化这些 token。
|
|
93
|
+
|
|
94
|
+
组织切换不是选择一个应用角色,应用角色仍由平台授权结果提供。当前 V2 角色并集尚未按工作组织执行 reach 边界,不能把切换后的角色列表当作组织隔离证明。切换也不是 Perspective,后者只收窄读取。切换成功后废弃旧组织的页面数据、选择器、缓存和在途结果,再刷新/重读授权及数据;当前没有封装完整切换生命周期的应用 SDK,不能只改 localStorage 后继续使用旧授权。切换失败保留原会话,不能把目标名称当作已经切换成功。
|
|
95
|
+
|
|
96
|
+
### 管理面接口
|
|
97
|
+
|
|
98
|
+
`/openxiangda-api/v2/platform/organizations` 下的开通 `/open`、安装 `/installations/reconcile`、管理授权 `/admin-grants`、成员 `/memberships/upsert`、目录主体 `/directory/subjects/upsert` 和事实 `/directory/role-facts/upsert` 是平台管理/同步修复入口。
|
|
99
|
+
|
|
100
|
+
平台管理员可管理全树;获得组织管理授权的人可在被授予节点及后代内进行获准的组织管理操作。授予、撤销管理授权及目录修复要求平台管理员。`GET /openxiangda-api/v2/platform/organizations/` 返回调用者可管理的组织;普通成员列表仍使用 `/me/memberships`。业务应用不调用 upsert 建立权限,不通过遍历管理接口读取其他学校的人员资料。
|
|
101
|
+
|
|
102
|
+
## 平台已有的家校角色与范围事实 {#directory-facts}
|
|
103
|
+
|
|
104
|
+
平台将普通通讯录与家校通讯录作为不同来源投影:`dingtalk_directory`、`dingtalk_school_contact`。目录主体以组织、来源和 `sourceUserId` 隔离;同一个来源 userId 或班级 ID 在两个学校出现时,不会变成同一学校内的事实。
|
|
105
|
+
|
|
106
|
+
| 来源角色 code | 含义 | 来源范围 |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| `teacher` | 家校目录中的教师 | 对应班级事实 |
|
|
109
|
+
| `head_teacher` | 家校目录标记的班主任 | 可有多个班级事实;没有来源标记就不推断 |
|
|
110
|
+
| `guardian` | 家长/监护人 | 对应学校与班级事实 |
|
|
111
|
+
| `student` | 学生 | 对应学校与班级事实 |
|
|
112
|
+
|
|
113
|
+
家校角色事实使用 `scopeType: 'class'`、`scopeValue: <来源班级ID>`。这是来源事实,不是应用 Native Resource 的记录 UUID;应用业务班级模型需要明确映射,不能将其直接塞入要求平台记录 UUID 的关系字段。班主任 A、B 两个班级是两个范围事实,不能只保存一个“班主任=true”。同一人在普通目录、家校目录、多个学校的资料分别保留来源与组织维度。
|
|
114
|
+
|
|
115
|
+
平台使用真实钉钉 `unionId` 识别可关联的跨企业用户。`unionId` 受开放平台账号范围约束,应用不以姓名、手机号或用户自填字段合并身份,也不将它当所有平台的全局主键。缺少 unionId 的学生仍有平台目录主体 ID,不伪造 provider unionId;登录用户使用平台 `userId`。来源用户 ID、目录主体 ID、登录用户 ID 和组织成员 ID 不能混用。
|
|
116
|
+
|
|
117
|
+
这些事实已由平台存储,但当前 `/me/memberships` 不返回完整家校角色/班级范围,也没有完整面向应用的角色事实 list/read SDK。应用希望使用时,在设计中明确映射哪些来源角色、消费哪些班级范围,等待对应读取/映射契约接通;不要调用管理 upsert 来“获取”事实,不新增一套应用通讯录做替代。
|
|
118
|
+
|
|
119
|
+
## 应用角色与数据边界 {#authorization}
|
|
120
|
+
|
|
121
|
+
每个应用角色在设计中显式声明组织 reach,具体可执行的 V2 声明仍需后续接通:
|
|
122
|
+
|
|
123
|
+
| reach 意图 | 适用范围 | 例子 |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| `self` | 授予组织自身 | 学校教师只能在任职学校的业务范围操作 |
|
|
126
|
+
| `subtree` | 授予组织及全部后代 | 获授权的上级管理人员处理被授予组织子树内的业务 |
|
|
127
|
+
|
|
128
|
+
这是组织覆盖维度,与某资源的 `read/create/update/delete` 能力、班级 scope、行/字段策略分别组合。`subtree` 不自动授予修改权限;`self` 不是 Data API 的“记录属于当前人”谓词。上级学校/教育局的普通成员不会因层级自动成为管理员;共享 unionId 也不会把一个人在几所学校的权限合并到当前组织。
|
|
129
|
+
|
|
130
|
+
当前传统平台角色 CRUD 能保存 `organizationReach`,不等于 V2 `authz.roles` 已支持此字段。当前权限引擎也没有已接通的“当前工作组织”内置行条件,不存在可使用的 `currentOrganization()` helper。不要手改生成契约、追加虚构 requiredPlatformCapabilities 或把所有学校授予一个 unrestricted 角色来替代组织边界。
|
|
131
|
+
|
|
132
|
+
组织数据权限还需把工作组织送入可信 Native principal,并执行数据归属、reach 与服务端行边界。在该接入完成前,以下都不能作为已支持行为交付:学校互相隔离;教育局只看/代操作全部下级数据;上级公共内容自动向后代开放。现有 `publicRead` 是已认证用户的公共字段投影,不等于组织树下发;匿名公开访问也不是跨学校共享机制。
|
|
133
|
+
|
|
134
|
+
应用可以先设计业务模型、页面及明确的业务操作;数据访问仍走已有 Data API 和受支持的 Nest operation。涉及尚未接通的组织授权闭环,记录平台依赖和所需验收,不用前端隐藏、浏览器字段或另一套成员表绕过。
|
|
135
|
+
|
|
136
|
+
## 入口、同步与通知的处理边界 {#entry-sync}
|
|
137
|
+
|
|
138
|
+
工作台和通知链接尽量携带 `corpId`,作为选择组织的线索。必须由平台登录流程、活动安装和成员事实验证;`corpId` 不能证明发起人属于该校。无法确定组织时使用服务端本人成员列表供选择,多校家长或同时在上级和学校任职的人都适用。
|
|
139
|
+
|
|
140
|
+
组织已开通但尚未安装,或安装已匹配但成员尚未同步,均不等于用户已获得应用访问权限。提示“账号信息尚未同步,请稍后再试”等状态可以使用实际平台结果,不能假装登录成功。自动安装事件、逐组织定时同步、应用可触发的有界同步请求尚未接通,不应在应用里开启无界轮询或用管理员凭据调用修复接口。
|
|
141
|
+
|
|
142
|
+
平台组织 registry 支持每企业安装信息,但尚未完成 Notification Hub 按目标组织选择安装、corp-bound 详情链接的完整接入。消息到人、消息点击进入正确学校和该用户有业务权限是三个独立条件,需分别验收;不能仅凭 unionId 就认定通知会路由到正确学校。
|
|
143
|
+
|
|
144
|
+
## 开发前核对与验收 {#verification}
|
|
145
|
+
|
|
146
|
+
1. 用项目锁定版本的 `context --json` / MCP `workspace_context` 确认平台绑定;用 `docs multi-organization` / `docs_read` 读取同版本正文。文档主题已注册,不代表 `platform_capabilities` 已有新的组织能力 code;当前不能仅凭缺少/出现某个虚构 feature 判断支持。
|
|
147
|
+
2. 确认目标站点的源码/部署版本、正式 SQL 迁移与组织管理授权。资料版本、接口状态和实际启用分别记录;站点缺能力由平台维护者补齐,应用不自行执行迁移或发包。
|
|
148
|
+
3. 在测试组织核实本人成员列表、真实企业名称、活动安装、profile/原始授权组织字段,验证同会话切换与非成员拒绝。不以单次 HTTP 200 代替响应 `code` 和业务事实。
|
|
149
|
+
4. 使用家校角色前,确认平台已经提供可消费的事实读取及映射契约;使用 `self/subtree` 前,确认 V2 声明、可信上下文和服务端数据边界均已实现。未闭合就标记依赖,不能报告自动隔离通过。
|
|
150
|
+
5. 最终组织业务验收覆盖同一人多组织、同一来源 ID 跨校、教师/家长来源区分、班主任多个班级、无 unionId 学生、同步未完成、错误 corpId、无权限上级成员和学校之间越权拒绝。只测统计页正常展示不能证明这些边界。
|
|
151
|
+
|
|
152
|
+
专题可用章节为 `scenario`、`availability`、`http-contracts`、`directory-facts`、`authorization`、`entry-sync`、`verification`。MCP 可按 `docs_read({ topic: 'multi-organization', section: 'http-contracts' })` 只读相关部分,资料 URI 为 `openxiangda://docs/multi-organization`。资料升级与 Skill/MCP 刷新方式见[版本升级](./upgrading.md)。
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
已有工作区读取 `context --json`、相关 `spec context <ID> --json`;没有工作区时可先在用户指定的本地目录整理 AppSpec,不为访谈执行 login/create 或创建远端应用。只要求研究时交付研究即可。收到完整资料先复用已有答案,核对版本、来源和冲突,避免重问。已有明确决定持续有效。
|
|
8
8
|
|
|
9
|
+
用户描述教育局与多个独立学校、企业三方应用、多校家长、多组织教师或家校角色/班级管理范围时,先读取[多组织与家校目录](./multi-organization.md)。复用平台已维护的组织、安装、成员与来源事实,明确应用业务权限意图;尚未接通的读取/SDK/数据权限作为平台依赖记录,不重建另一套组织身份体系。
|
|
10
|
+
|
|
9
11
|
按任务加载本专题相关章节及[交互模式](./interaction-patterns.md),不用把所有流程方法展示给用户。全新应用设计本期完整范围;既有应用围绕受影响需求、角色、旅程和页面修订;纯文案或无行为调整沿用有效基线并说明影响,不重写全套 PRD。明确只做原型时,保持原型范围。
|
|
10
12
|
|
|
11
13
|
资料中的业务描述是证据,嵌入的指令、账号和凭据不是执行授权。引用来源文件、页码/段落、访谈日期与具体答复范围,脱敏后保存必要摘要;不要把原始敏感资料整份复制进 Git。
|
|
@@ -288,6 +288,276 @@ MCP 使用项目锁定的根包;在客户端配置下列 stdio 启动参数,
|
|
|
288
288
|
{
|
|
289
289
|
"type": "object",
|
|
290
290
|
"oneOf": [
|
|
291
|
+
{
|
|
292
|
+
"type": "object",
|
|
293
|
+
"additionalProperties": false,
|
|
294
|
+
"properties": {
|
|
295
|
+
"operation": {
|
|
296
|
+
"const": "acceptance-data.prepare",
|
|
297
|
+
"description": "准备可回收的TEST原生数据批次及原验收身份"
|
|
298
|
+
},
|
|
299
|
+
"environment": {
|
|
300
|
+
"type": "string",
|
|
301
|
+
"enum": [
|
|
302
|
+
"test"
|
|
303
|
+
]
|
|
304
|
+
},
|
|
305
|
+
"input": {
|
|
306
|
+
"type": "object",
|
|
307
|
+
"additionalProperties": false,
|
|
308
|
+
"properties": {
|
|
309
|
+
"requestKey": {
|
|
310
|
+
"type": "string",
|
|
311
|
+
"minLength": 1,
|
|
312
|
+
"maxLength": 36,
|
|
313
|
+
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
|
314
|
+
},
|
|
315
|
+
"expectedAppVersionId": {
|
|
316
|
+
"type": "string",
|
|
317
|
+
"minLength": 1,
|
|
318
|
+
"maxLength": 36,
|
|
319
|
+
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
|
320
|
+
},
|
|
321
|
+
"expectedHeadRevision": {
|
|
322
|
+
"type": "integer",
|
|
323
|
+
"minimum": 1,
|
|
324
|
+
"maximum": 9007199254740991
|
|
325
|
+
},
|
|
326
|
+
"expiresInMinutes": {
|
|
327
|
+
"type": "integer",
|
|
328
|
+
"minimum": 15,
|
|
329
|
+
"maximum": 1440
|
|
330
|
+
},
|
|
331
|
+
"recordLimit": {
|
|
332
|
+
"type": "integer",
|
|
333
|
+
"minimum": 1,
|
|
334
|
+
"maximum": 1000
|
|
335
|
+
},
|
|
336
|
+
"redirectUri": {
|
|
337
|
+
"type": "string",
|
|
338
|
+
"minLength": 1,
|
|
339
|
+
"maxLength": 2048
|
|
340
|
+
},
|
|
341
|
+
"actors": {
|
|
342
|
+
"type": "array",
|
|
343
|
+
"minItems": 1,
|
|
344
|
+
"maxItems": 12,
|
|
345
|
+
"items": {
|
|
346
|
+
"type": "object",
|
|
347
|
+
"additionalProperties": false,
|
|
348
|
+
"properties": {
|
|
349
|
+
"key": {
|
|
350
|
+
"type": "string",
|
|
351
|
+
"minLength": 1,
|
|
352
|
+
"maxLength": 80
|
|
353
|
+
},
|
|
354
|
+
"name": {
|
|
355
|
+
"type": "string",
|
|
356
|
+
"minLength": 1,
|
|
357
|
+
"maxLength": 255
|
|
358
|
+
},
|
|
359
|
+
"roleCodes": {
|
|
360
|
+
"type": "array",
|
|
361
|
+
"minItems": 1,
|
|
362
|
+
"maxItems": 32,
|
|
363
|
+
"uniqueItems": true,
|
|
364
|
+
"items": {
|
|
365
|
+
"type": "string",
|
|
366
|
+
"minLength": 1,
|
|
367
|
+
"maxLength": 128
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
"departmentIds": {
|
|
371
|
+
"type": "array",
|
|
372
|
+
"maxItems": 128,
|
|
373
|
+
"uniqueItems": true,
|
|
374
|
+
"items": {
|
|
375
|
+
"type": "string",
|
|
376
|
+
"minLength": 1,
|
|
377
|
+
"maxLength": 128
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
"required": [
|
|
382
|
+
"key",
|
|
383
|
+
"roleCodes"
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
"required": [
|
|
389
|
+
"requestKey",
|
|
390
|
+
"expectedAppVersionId",
|
|
391
|
+
"expectedHeadRevision",
|
|
392
|
+
"actors"
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
"required": [
|
|
397
|
+
"operation",
|
|
398
|
+
"environment",
|
|
399
|
+
"input"
|
|
400
|
+
]
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"type": "object",
|
|
404
|
+
"additionalProperties": false,
|
|
405
|
+
"properties": {
|
|
406
|
+
"operation": {
|
|
407
|
+
"const": "acceptance-data.status",
|
|
408
|
+
"description": "读回原TEST验收批次状态和修复引用"
|
|
409
|
+
},
|
|
410
|
+
"environment": {
|
|
411
|
+
"type": "string",
|
|
412
|
+
"enum": [
|
|
413
|
+
"test"
|
|
414
|
+
]
|
|
415
|
+
},
|
|
416
|
+
"input": {
|
|
417
|
+
"type": "object",
|
|
418
|
+
"additionalProperties": false,
|
|
419
|
+
"properties": {
|
|
420
|
+
"runId": {
|
|
421
|
+
"type": "string",
|
|
422
|
+
"minLength": 1,
|
|
423
|
+
"maxLength": 36,
|
|
424
|
+
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
"required": [
|
|
428
|
+
"runId"
|
|
429
|
+
]
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
"required": [
|
|
433
|
+
"operation",
|
|
434
|
+
"environment",
|
|
435
|
+
"input"
|
|
436
|
+
]
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"type": "object",
|
|
440
|
+
"additionalProperties": false,
|
|
441
|
+
"properties": {
|
|
442
|
+
"operation": {
|
|
443
|
+
"const": "acceptance-data.stop",
|
|
444
|
+
"description": "停止此TEST批次写入并撤销来源会话"
|
|
445
|
+
},
|
|
446
|
+
"environment": {
|
|
447
|
+
"type": "string",
|
|
448
|
+
"enum": [
|
|
449
|
+
"test"
|
|
450
|
+
]
|
|
451
|
+
},
|
|
452
|
+
"input": {
|
|
453
|
+
"type": "object",
|
|
454
|
+
"additionalProperties": false,
|
|
455
|
+
"properties": {
|
|
456
|
+
"runId": {
|
|
457
|
+
"type": "string",
|
|
458
|
+
"minLength": 1,
|
|
459
|
+
"maxLength": 36,
|
|
460
|
+
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
"required": [
|
|
464
|
+
"runId"
|
|
465
|
+
]
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
"required": [
|
|
469
|
+
"operation",
|
|
470
|
+
"environment",
|
|
471
|
+
"input"
|
|
472
|
+
]
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
"type": "object",
|
|
476
|
+
"additionalProperties": false,
|
|
477
|
+
"properties": {
|
|
478
|
+
"operation": {
|
|
479
|
+
"const": "acceptance-data.preview-cleanup",
|
|
480
|
+
"description": "只读精确归属、原repair清单和剩余对象;不执行删除"
|
|
481
|
+
},
|
|
482
|
+
"environment": {
|
|
483
|
+
"type": "string",
|
|
484
|
+
"enum": [
|
|
485
|
+
"test"
|
|
486
|
+
]
|
|
487
|
+
},
|
|
488
|
+
"input": {
|
|
489
|
+
"type": "object",
|
|
490
|
+
"additionalProperties": false,
|
|
491
|
+
"properties": {
|
|
492
|
+
"runId": {
|
|
493
|
+
"type": "string",
|
|
494
|
+
"minLength": 1,
|
|
495
|
+
"maxLength": 36,
|
|
496
|
+
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
|
497
|
+
}
|
|
498
|
+
},
|
|
499
|
+
"required": [
|
|
500
|
+
"runId"
|
|
501
|
+
]
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
"required": [
|
|
505
|
+
"operation",
|
|
506
|
+
"environment",
|
|
507
|
+
"input"
|
|
508
|
+
]
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
"type": "object",
|
|
512
|
+
"additionalProperties": false,
|
|
513
|
+
"properties": {
|
|
514
|
+
"operation": {
|
|
515
|
+
"const": "acceptance-data.execute-cleanup",
|
|
516
|
+
"description": "按预览digest通过原repair执行金丝雀或剩余删除"
|
|
517
|
+
},
|
|
518
|
+
"environment": {
|
|
519
|
+
"type": "string",
|
|
520
|
+
"enum": [
|
|
521
|
+
"test"
|
|
522
|
+
]
|
|
523
|
+
},
|
|
524
|
+
"input": {
|
|
525
|
+
"type": "object",
|
|
526
|
+
"additionalProperties": false,
|
|
527
|
+
"properties": {
|
|
528
|
+
"runId": {
|
|
529
|
+
"type": "string",
|
|
530
|
+
"minLength": 1,
|
|
531
|
+
"maxLength": 36,
|
|
532
|
+
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
|
533
|
+
},
|
|
534
|
+
"manifestSha256": {
|
|
535
|
+
"type": "string",
|
|
536
|
+
"minLength": 1,
|
|
537
|
+
"maxLength": 64,
|
|
538
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
539
|
+
},
|
|
540
|
+
"mode": {
|
|
541
|
+
"type": "string",
|
|
542
|
+
"enum": [
|
|
543
|
+
"canary",
|
|
544
|
+
"remaining"
|
|
545
|
+
]
|
|
546
|
+
}
|
|
547
|
+
},
|
|
548
|
+
"required": [
|
|
549
|
+
"runId",
|
|
550
|
+
"manifestSha256",
|
|
551
|
+
"mode"
|
|
552
|
+
]
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
"required": [
|
|
556
|
+
"operation",
|
|
557
|
+
"environment",
|
|
558
|
+
"input"
|
|
559
|
+
]
|
|
560
|
+
},
|
|
291
561
|
{
|
|
292
562
|
"type": "object",
|
|
293
563
|
"additionalProperties": false,
|
|
@@ -1230,6 +1230,11 @@ pnpm openxiangda workflow status --environment test
|
|
|
1230
1230
|
|
|
1231
1231
|
可加 `--adopt-handling-defaults` 把办理模式与按钮开关、文案作为源码默认值。它保留原有必需动作,不把管理员指定人员复制成源码默认值。导入的摘要基线写在源码 activation 的 `sourceBase`;来源环境与修订号只保留在审计锁文件,不进入密封应用制品。锁文件与导出的规范文档可能包含合法源码用户引用,应按项目访问权限管理。
|
|
1232
1232
|
|
|
1233
|
+
Source v2 新增条件人员覆盖的隐私投影:有序规则、标签、`otherwise` 和非指定人员来源保留完整声明;指定人员叶子只包含数量(包含零人),不导出环境人员 ID 或运行解析结果。未选择 `--adopt-handling-defaults` 时只导入原始规范源码;显式选择时,非指定人员规则须通过本地已发布来源、节点权限与条件事实校验,才作为节点独立源码绑定采用。任一叶子含指定人员,整个人员规则不导入,返回节点及数量提示,不将角色分支与缺失名单拼接成新规则。
|
|
1234
|
+
|
|
1235
|
+
新版 DTO/离线导入并不表示平台已经开放条件审批。v1 DTO 仍明确拒绝条件声明;旧消费者不认识 v2 时明确报错。平台 Source exporter 必须使用已发布的新 contracts 制品,且注册/发布仍受平台能力协商与验证门禁约束,不能使用导出文件绕过旧平台的能力限制。
|
|
1236
|
+
|
|
1237
|
+
|
|
1233
1238
|
`plan-registration` 是服务器只读查询,返回相同内容已有的版本号或下一整数;`--write` 只把数字写入本机源码。最终准备仍检查编号冲突、内容冲突和跳号。准备成功但后续部署失败的版本保留为未启用的不可变登记,相同制品可复用这些数字;不会删除或重排。`status` 显示 `in_sync`、`behind`、`ahead`、`diverged`、`not_active` 和未启用登记数量。它没有远端写入。首次导入之前,状态比较使用目标环境当前应用版本的源码声明作为基线;跨环境导入的来源修订不会冒充目标环境基线。
|
|
1234
1239
|
|
|
1235
1240
|
如果只希望把正式环境的流程规则同步到已有测试环境,可先读取两边的 `status`,记录实际流程 Head 修订号,再显式执行同步:
|