@lark-base-open/base-database-cli 1.0.0 → 1.1.0
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/CHANGELOG.md +12 -0
- package/README.md +81 -27
- package/config-schema.json +6 -0
- package/dist/agent-guide.d.ts +1 -0
- package/dist/agent-guide.d.ts.map +1 -1
- package/dist/agent-guide.js +3 -2
- package/dist/agent-guide.js.map +1 -1
- package/dist/auth.d.ts +5 -4
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +24 -15
- package/dist/auth.js.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -1
- package/dist/config.js.map +1 -1
- package/dist/database-skill.d.ts +4 -2
- package/dist/database-skill.d.ts.map +1 -1
- package/dist/database-skill.js +27 -11
- package/dist/database-skill.js.map +1 -1
- package/dist/deploy.d.ts +3 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +16 -10
- package/dist/deploy.js.map +1 -1
- package/dist/distribution-commands.d.ts +3 -0
- package/dist/distribution-commands.d.ts.map +1 -0
- package/dist/distribution-commands.js +64 -0
- package/dist/distribution-commands.js.map +1 -0
- package/dist/distribution-npm.d.ts +23 -0
- package/dist/distribution-npm.d.ts.map +1 -0
- package/dist/distribution-npm.js +133 -0
- package/dist/distribution-npm.js.map +1 -0
- package/dist/environment.d.ts +1 -0
- package/dist/environment.d.ts.map +1 -1
- package/dist/environment.js +1 -1
- package/dist/environment.js.map +1 -1
- package/dist/init.d.ts +2 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +4 -2
- package/dist/init.js.map +1 -1
- package/dist/install.d.ts +31 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +150 -0
- package/dist/install.js.map +1 -0
- package/dist/lark-cli.d.ts +6 -1
- package/dist/lark-cli.d.ts.map +1 -1
- package/dist/lark-cli.js +57 -4
- package/dist/lark-cli.js.map +1 -1
- package/dist/preview-receipt.d.ts +5 -4
- package/dist/preview-receipt.d.ts.map +1 -1
- package/dist/preview-receipt.js +12 -3
- package/dist/preview-receipt.js.map +1 -1
- package/dist/profile-name.d.ts +2 -0
- package/dist/profile-name.d.ts.map +1 -0
- package/dist/profile-name.js +10 -0
- package/dist/profile-name.js.map +1 -0
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +18 -10
- package/dist/program.js.map +1 -1
- package/dist/pull.d.ts +2 -0
- package/dist/pull.d.ts.map +1 -1
- package/dist/pull.js +4 -2
- package/dist/pull.js.map +1 -1
- package/dist/skill.d.ts +9 -2
- package/dist/skill.d.ts.map +1 -1
- package/dist/skill.js +128 -11
- package/dist/skill.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/updates.d.ts +20 -0
- package/dist/updates.d.ts.map +1 -0
- package/dist/updates.js +98 -0
- package/dist/updates.js.map +1 -0
- package/package.json +6 -4
- package/skills/lark-base-database/SKILL.md +72 -273
- package/skills/lark-base-database/references/base-capability-routing.md +12 -20
- package/skills/lark-base-database/references/base-sql-unsupported.md +2 -2
- package/skills/lark-base-database/references/database-capability-skill.md +27 -11
- package/skills/lark-base-database/references/development.md +26 -553
- package/skills/lark-base-database/references/faas.md +563 -0
- package/skills/lark-base-database/references/file-transfer.md +62 -199
- package/skills/lark-base-database/references/frontend-design-guide.md +97 -0
- package/skills/lark-base-database/references/notifications.md +48 -0
- package/skills/lark-base-database/references/permission-design.md +32 -38
- package/skills/lark-base-database/references/release.md +51 -43
- package/skills/lark-base-database/references/sql-function.md +17 -4
- package/skills/lark-base-database/references/style-guide.md +6 -8
- package/skills/lark-base-database/references/verification.md +57 -0
- package/skills/lark-base-database/references/workspace.md +159 -0
- package/templates/database-capability/SKILL.md.tmpl +28 -11
- package/templates/database-starter/README.md +1 -1
- package/templates/database-starter/page/src/lib/database-runtime-attachment.test.ts +43 -40
|
@@ -1,60 +1,39 @@
|
|
|
1
1
|
# 文件传输
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
实现附件能力时,先读取操作路由和公共约束,再读取当前操作章节。本文说明 Page 如何编排附件流程;请求体、响应结构和限制的唯一协议说明见[FaaS 与记录协议](faas.md#应用记录-写入协议),SQL 类型见[SQL Function](sql-function.md#sql-类型与结果值)。不因仅需展示附件而实现上传或写入功能。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 操作路由
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
| 目标 | 入口 | 必读章节 |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| 上传文件字节 | `siteRuntime.uploadAttachment()` | [上传](#上传) |
|
|
10
|
+
| 展示缩略图或大图 | `buildAttachmentCoverUrl(context, ref)` | [展示与下载](#展示与下载) |
|
|
11
|
+
| 下载原文件 | `fetchAttachmentDownloadUrl(context, ref)` | [展示与下载](#展示与下载) |
|
|
12
|
+
| 将新文件挂载到单元格或移除引用 | Page 调 FaaS,使用附件增量路由 | [写单元格](#写单元格)和 FaaS 协议 |
|
|
13
|
+
| 写入超时、结果不明 | 保留 token,通过固定 SQL 有界核对 | [超时与结果未知](#超时与结果未知) |
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
## 公共约束
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (code === 'ATTACHMENT_UNAVAILABLE') { /* 走降级 */ }
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## 四条独立路径
|
|
20
|
-
|
|
21
|
-
**文本、选项、人员、日期、关联这些字段 SQL 查出来即可直接渲染;附件 SQL 返回的是凭据,不是内容。**
|
|
22
|
-
|
|
23
|
-
| 操作 | 入口 | 约束来源 |
|
|
24
|
-
|---|---|---|
|
|
25
|
-
| 上传文件 | `siteRuntime.uploadAttachment()` | 页面的 HTTP 代理只收字符串,二进制无法通过;身份 header 须由父页面注入 |
|
|
26
|
-
| 展示缩略图 / 预览 | `buildAttachmentCoverUrl(context, ref)` → `<img src>` | `file_token` 不是 URL;模板拼出的地址浏览器可直接取 |
|
|
27
|
-
| 下载原文件 | `fetchAttachmentDownloadUrl(context, ref)` → `<a download>` | 模板经 `temporary_download_url` 换回明文自证链接,由浏览器原生下载 |
|
|
28
|
-
| 追加 / 移除附件 | 附件增量路由 `append_attachments` / `remove_attachments` | 请求只带本次增删 token;服务端保留读到的其它附件及宽高,但仍有并发覆盖窗口,见「写单元格」 |
|
|
29
|
-
|
|
30
|
-
上传流程在 Page 里封装成一个业务方法;展示与下载直接复用 starter helper。业务组件只调这些收口入口,不在多处重复编排。
|
|
17
|
+
- `file_token` 是附件资源标识,不是可直接访问的 URL,也不是登录凭证。临时下载链接携带授权信息,不持久化、不记录到日志或作为长期公开链接。
|
|
18
|
+
- 表、字段 ID 来自 Catalog;已有附件的记录 ID、FILE.id(即 file_token)来自 SQL。上传成功返回的新 fileToken 供后续挂载使用。不能通过伪造位置声明获取其他附件。
|
|
19
|
+
- 上传依赖父页面 `attachment.upload`;挂载还依赖目标环境的 FaaS runtime 和服务端增量路由。更新 starter 不证明平台已开通。能力不具备时报告具体限制,按用户决定调整需求,不猜网关或回退为旧列表整格覆盖。
|
|
20
|
+
- 上传校验应用权限与绑定关系。不要要求访客取得底层 Base 权限来绕过应用链路问题。
|
|
21
|
+
- 上传成功只证明文件字节已提交,不证明附件已挂载;移除只删除单元格引用,不删除云盘文件,也不承诺释放 Base 附件计数。
|
|
31
22
|
|
|
32
23
|
## 上传
|
|
33
24
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
**上传校验的是应用权限,不需要底表任何权限。** 文件挂在底表上,但鉴权对象是应用。
|
|
25
|
+
父页面负责二进制传输与身份注入,Page 不通过普通 HTTP 代理上传 File/Blob:
|
|
37
26
|
|
|
38
27
|
```ts
|
|
39
28
|
await siteRuntime.uploadAttachment({ baseToken, tableId, file, onProgress })
|
|
40
29
|
// → { fileToken, name, size, mimeType? }
|
|
41
30
|
```
|
|
42
31
|
|
|
43
|
-
|
|
32
|
+
baseToken/tableId 取自 Catalog;file 必须是 File。不传 fieldId,目标字段在挂载时使用。name/size/mimeType 为客户端信息,持久化后的元数据以服务端结果为准。
|
|
44
33
|
|
|
45
|
-
|
|
34
|
+
### 图片宽高
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
### 图片宽高在上传前从本地文件读取
|
|
50
|
-
|
|
51
|
-
当前父页面不返回图片宽高;Channel 类型中的可选 `width` / `height` 不代表运行时会提供。
|
|
52
|
-
Page 应在上传前解码本地 `File`,读取 `naturalWidth` / `naturalHeight`,随后和上传得到的
|
|
53
|
-
`fileToken` 一起保留,用于挂载请求。不要用预览元素的 CSS 尺寸或缩略图档位代替原图尺寸。
|
|
54
|
-
|
|
55
|
-
下面的业务 helper 在 Page 内使用,非图片不传宽高;图片解码失败或尺寸无效时抛错,由上传入口
|
|
56
|
-
提示用户并停止本次上传、挂载,不伪造 `0` 或默认尺寸。`file.type` 为空时先识别文件类型,
|
|
57
|
-
不要把可能的图片直接当作非图片跳过尺寸提取。
|
|
36
|
+
图片上传前从本地 File 解码读取原始宽高,不依赖上传结果中的可选 width/height,也不使用预览元素的 CSS 尺寸。服务端不会补齐省略的宽高,SQL 也不返回旧图片宽高。
|
|
58
37
|
|
|
59
38
|
```ts
|
|
60
39
|
async function readImageDimensions(file: File) {
|
|
@@ -77,199 +56,83 @@ async function readImageDimensions(file: File) {
|
|
|
77
56
|
const dimensions = await readImageDimensions(file)
|
|
78
57
|
const uploaded = await siteRuntime.uploadAttachment({ baseToken, tableId, file, onProgress })
|
|
79
58
|
const newAttachment = { file_token: uploaded.fileToken, ...dimensions }
|
|
80
|
-
//
|
|
59
|
+
// 经业务 FaaS 挂载 newAttachment,不合并页面旧附件列表。
|
|
81
60
|
```
|
|
82
61
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```ts
|
|
86
|
-
const previewUrl = URL.createObjectURL(file) // 组件卸载时 URL.revokeObjectURL(previewUrl)
|
|
87
|
-
```
|
|
62
|
+
非图片省略宽高;类型未知时先识别或提示用户,不能把可能的图片直接当非图片。图片解码失败或尺寸无效时停止上传和挂载,不伪造尺寸。
|
|
88
63
|
|
|
89
|
-
|
|
64
|
+
### 进度与即时展示
|
|
90
65
|
|
|
91
|
-
|
|
66
|
+
onProgress 返回 loaded/total,用于进度反馈;进度可能分片跳变,也可能不回调。分母取回调的 total,不自行假定 file.size。100% 仍可能处于服务端收尾,只有 Promise resolve 才代表上传完成。
|
|
92
67
|
|
|
93
|
-
|
|
94
|
-
|---|---|---|
|
|
95
|
-
| 超过单文件上限 / 大小为 0 / 不是 `File` | `INVALID_ATTACHMENT_TARGET` | 说清是文件本身的问题,重试无用;最好在选完文件后就先拦一次 |
|
|
96
|
-
| `(baseToken, tableId)` 不在本应用绑定内 | `INVALID_ATTACHMENT_TARGET` | 应用开发配置错误,不是用户能解决的,按异常上报 |
|
|
97
|
-
| 单元格已有 100 张 | 写单元格时返回参数错误 | 上传前按当前张数拦住,不要等写入失败 |
|
|
98
|
-
| 父页面版本不支持 | `ATTACHMENT_UNAVAILABLE` | 用它做能力探测与降级 |
|
|
99
|
-
| 上传失败 | `ATTACHMENT_UPLOAD_FAILED`,原始 message 保留 | 可以重试,但**不要自动重试**(见注意事项,上传不幂等) |
|
|
100
|
-
| 首条进度之后,连续 120s 没有新进度 | `ATTACHMENT_UPLOAD_STALLED` | 已判定卡死并中止,提示网络问题并让用户重新触发 |
|
|
68
|
+
当前停滞检测从首条进度事件之后开始:连续 120 秒无新进度可能返回 ATTACHMENT_UPLOAD_STALLED。首条事件前仍可能等待至调用超时;页面应有自己的等待提示与最大等待策略,不自动重传。调用超时不证明父页面已取消上传。
|
|
101
69
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
### 上传进度
|
|
105
|
-
|
|
106
|
-
上传耗时不确定,单文件上限 2 GB,因此**要让用户看到进展**,不要只给一个静态的「上传中」。`onProgress` 提供了这个能力,展示形式不限——百分比文字、进度条、已传分片数都可以,按页面风格选。
|
|
107
|
-
|
|
108
|
-
`onProgress` 的回调节奏与常见的字节流进度不同,直接按平滑增长做动画会出问题:
|
|
109
|
-
|
|
110
|
-
- **按分片跳变。** 40 MiB 的文件只回调三次,5 MiB 直接 0% → 100%,与文件体积无关。
|
|
111
|
-
- **100% 不代表结束**,之后还有约 3 秒收尾,完成信号只有 Promise resolve。
|
|
112
|
-
- **可能一次都不触发**:旧版本父页面不回播进度,初始态要自带可用值。
|
|
113
|
-
- **停滞检测从首条进度事件之后才生效**:首条进度到达前卡死不会返回 `STALLED`,只有约 2 小时的调用上限兜底,且超时不通知父页面取消。需要更紧的首进度兜底时页面自行计时并提示用户,不要替用户自动取消或重试。
|
|
114
|
-
- 百分比的分母取回调给出的 `total`,不取 `file.size`。
|
|
115
|
-
- 并发上传互不干扰。
|
|
70
|
+
刚上传的图片可使用本地 `URL.createObjectURL(file)` 展示,替换或卸载时 revoke。附件位置同步和封面生成都是异步过程,下次打开或刷新也不保证就绪;重新进入页面仍需处理远程封面未就绪状态。
|
|
116
71
|
|
|
117
72
|
## 展示与下载
|
|
118
73
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
| 用途 | 端点 | 页面用法 |
|
|
122
|
-
|---|---|---|
|
|
123
|
-
| 缩略图 / 预览 | `GET box/stream/download/v2/cover/<file_token>` | 拼出 URL 直接给 `<img src>`,由浏览器请求 |
|
|
124
|
-
| 下载原文件 | `POST box/file/temporary_download_url` | 换回自证链接给 `<a download>` |
|
|
125
|
-
|
|
126
|
-
两条都要带**位置声明** `extra`,由 starter 的两个 helper 在 Page 本地拼出。Page 从 SQL Function 取得附件坐标,再调用这两个 helper;不需要独立的应用附件查询接口,也不需要在 append/remove 前先查询附件列表。
|
|
127
|
-
|
|
128
|
-
### 第一步 · 位置声明 `extra`
|
|
74
|
+
从 starter runtime 导入 helper,并准备真实位置:
|
|
129
75
|
|
|
130
76
|
```ts
|
|
131
77
|
const context = await resolveDatabaseContext()
|
|
132
78
|
const ref = { tableId, fieldId, recordId, fileToken }
|
|
133
79
|
```
|
|
134
80
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
它是声明不是凭证:服务端据此核对「这个 token 是否真的挂在这个字段的这条记录上」,**四个值必须如实填**,位置对不上会被拒,且不是抛错,是拿不到内容。
|
|
138
|
-
|
|
139
|
-
#### `baseAppToken` 决定鉴权对象
|
|
140
|
-
|
|
141
|
-
它决定服务端**按哪个对象判权**:带上就按应用判,不带就退化成「访问者对底表有没有权限」。而应用访客按设计**不该有底表权限**(记录读写是应用 owner 代执行的),所以缺了它,访客一律读不到。starter helper 会带上它。
|
|
142
|
-
|
|
143
|
-
用一个「对应用有权限、对其绑定底表无权限(直接读记录报 `91403`)」的真实身份实测:
|
|
144
|
-
|
|
145
|
-
| 操作 | 带 `baseAppToken` | 不带 |
|
|
146
|
-
|---|---|---|
|
|
147
|
-
| 缩略图 `cover` | **200 image/png** | **403** |
|
|
148
|
-
| 下载 `temporary_download_url` | 200 + 链接 | `{"code":4,"message":"Forbidden"}` |
|
|
149
|
-
|
|
150
|
-
### 第二步 A · 缩略图
|
|
151
|
-
|
|
152
|
-
不需要换链接、取字节或包装 Blob,拼出地址赋给 `src` 即可:
|
|
153
|
-
|
|
154
|
-
```ts
|
|
155
|
-
const src = buildAttachmentCoverUrl(context, ref, 360)
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
尺寸向上取到服务端档位 120 / 360 / 720 / 1280,不传时默认 360。
|
|
81
|
+
helper 负责生成 extra,其中 baseAppToken 将鉴权对象指向应用。业务代码不手工拼接 extra,也不移除该字段来尝试底表鉴权。不存在、错位或无权限的附件可能返回错误或无可展示内容。
|
|
159
82
|
|
|
160
|
-
|
|
83
|
+
| 操作 | helper 与结果 | 前置条件 |
|
|
84
|
+
| --- | --- | --- |
|
|
85
|
+
| 封面/大图 | `buildAttachmentCoverUrl(context, ref, 360)` 返回绝对 URL,交给 img | 需要有效应用、附件坐标和 gatewayOrigin;无法构造时返回空字符串 |
|
|
86
|
+
| 原文件下载 | `await fetchAttachmentDownloadUrl(context, ref)` 返回临时链接 | 通过父页面代理取链接,不依赖封面 helper 的 gatewayOrigin |
|
|
161
87
|
|
|
162
|
-
|
|
163
|
-
{src ? <img src={src} loading="lazy" onError={retryLater} /> : null}
|
|
164
|
-
```
|
|
88
|
+
不能因为封面 URL 为空就禁用下载。下载失败应显示 helper 返回的错误;任何动作入口都不能静默无响应。
|
|
165
89
|
|
|
166
|
-
|
|
90
|
+
### 封面与重试
|
|
167
91
|
|
|
168
|
-
|
|
169
|
-
- **封面是服务端异步生成的。** 取不到时返回 `202`(`{"code":90002006,"message":"Cover No Exist"}`),`<img>` 表现为 `onError`。视频尤其慢:35 MB 的录屏在 20 分钟内持续返回 202,约 2 小时后才生成。**202 不表示该格式不受支持**,要留重试(间隔数十秒,更换 cache-bust 参数后重新设置 `src`),重试成本很低,因为字节根本不进 JS。
|
|
170
|
-
|
|
171
|
-
覆盖面实测:png / jpg ✅、**pdf ✅**(回首页 PNG)、**mp4 ✅**(回截帧 JPEG)、**mov ✅**(同上,生成更慢)。用 `dd` 造的填充文件一律 202,无法验证封面生成;测试前先用 `xxd` 确认文件头含 `ftyp`。
|
|
172
|
-
|
|
173
|
-
附带效果:`loading="lazy"` 生效(视口外不发请求)、可用浏览器 HTTP 缓存、不占用 JS 堆、无需管理 Blob 生命周期。
|
|
174
|
-
|
|
175
|
-
### 第二步 B · 下载原文件
|
|
176
|
-
|
|
177
|
-
```ts
|
|
178
|
-
const url = await fetchAttachmentDownloadUrl(context, ref)
|
|
179
|
-
```
|
|
92
|
+
封面尺寸取服务端档位 120/360/720/1280,默认 360;列表可用 360,大图用 1280。除用户明确要求原文件画质外,展示不调用下载端点获取大体积原文件。
|
|
180
93
|
|
|
181
|
-
|
|
94
|
+
封面异步生成;202/90002006 或 img 的 onError 不足以判定文件类型不支持。采用占位图或文件名,并按[工程质量](style-guide.md)设置有限重试:限定次数或总时长,仅在组件可见且仍挂载时调度,替换附件或卸载时取消;超过预算保留手动重试入口。具体预算由体验需求决定,不把某次样本耗时写成平台保证。
|
|
182
95
|
|
|
183
|
-
-
|
|
184
|
-
- 直接交给 `<a href={url} download>` 让浏览器原生下载——有进度条、可续传、**字节不进 JS**,35 MB 的 `.mov` 实测正常
|
|
185
|
-
- 跨源时 `download` 属性的**值**被忽略,文件名由服务端 `content-disposition` 决定,支持中文
|
|
186
|
-
- 落盘要求父页面 iframe 的 sandbox 带 `allow-downloads`;缺了会被浏览器静默拦截,不抛错、无事件,只在 console 留一条 warning
|
|
96
|
+
重试封面可更新 cache-bust 参数,不重新上传文件。网关 origin 来自 runtime 的 ancestorOrigins/referrer 解析,无法取得时不猜域名。支持格式、生成耗时和有效期以目标环境表现为准。
|
|
187
97
|
|
|
188
|
-
|
|
98
|
+
### 原文件下载
|
|
189
99
|
|
|
190
|
-
|
|
100
|
+
临时链接交给浏览器原生下载,文件字节不经 Page JavaScript。文件名由服务端 Content-Disposition 决定,跨源 download 属性不能保证自定义文件名。父页面 iframe 需允许下载;缺少 allow-downloads 时浏览器可能拦截,需区分配置限制与链接获取失败。
|
|
191
101
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
**不落库、不写进 SQL、不长期缓存。** 持久化与传递一律用 `file_token`,要展示时现换。页面停留很久后图片失效属于预期,重走第二步即可。
|
|
195
|
-
|
|
196
|
-
图多的列表页靠页面侧缓解(`loading="lazy"`、分页、先只显示文件名)。
|
|
102
|
+
每次用户下载时获取链接,不将其写入 Base 或长期缓存;链接过期时重新获取。下载端点提供原文件,width/height 不能用来请求缩略图。
|
|
197
103
|
|
|
198
104
|
## 写单元格
|
|
199
105
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
- **追加只提交新增项** `[{file_token, image_width, image_height}]`,图片宽高在上传前从本地 `File` 解码取得(见上文),非图片省略宽高。Page 不需要读取或合并旧列表;服务端保留它读到的已有附件及宽高,再追加新项。该基准可能尚未包含另一请求刚写入的附件,不能据此承诺并发不丢失。
|
|
203
|
-
- **移除只提交待删的 `file_token`**,按 token 匹配并移除**全部**同名实例。SQL 读回的键名是 `id`,提交前要 `.map((s) => ({ file_token: s.id }))`。
|
|
204
|
-
- **无增删项时在调用方短路**:Page/FaaS 组装请求时过滤空字段数组和空记录映射,过滤后无项就不发请求、保留页面状态。平台 Schema 不保证拒绝空输入;合法目标上的 `append []` 仍会读后写回已有列表,不是无副作用操作。`remove []` 不产生实际变更,但也不必发送。
|
|
205
|
-
- **成功响应回显本次操作合并出的列表**,用它更新页面本地状态;它不保证包含其他并发写入,也不保证随后不会被另一请求覆盖。不要立即用 SQL 回读替换它,从库可能还没同步。
|
|
206
|
-
- **append 不按 file_token 去重,也没有幂等键**:重复提交可能产生重复引用。发送前去掉本次新增项中的重复 token;这只能防止本批重复,不能提供跨请求幂等。结果未知时按下一节核对,不自动重试。
|
|
207
|
-
- `batch_update` 对附件字段只用于**整格置空**(传 `[]`)或明确要整格重设的场景:它是整格覆盖,服务端不会补齐省略的宽高,而 SQL 读不回旧图宽高——基于 SQL 列表的重设无法重建宽高,旧图会显示成占位方块。
|
|
106
|
+
普通追加/移除通过业务 FaaS 调用 append_attachments/remove_attachments,路径、JSON 和响应见[FaaS 协议](faas.md#应用记录-写入协议)。保持以下操作语义:
|
|
208
107
|
|
|
209
|
-
|
|
108
|
+
- 追加只提交本次新增项;图片附带本地读取的宽高。正常追加不要求先查询旧列表,不依赖 SQL 重建旧图宽高。
|
|
109
|
+
- 移除只提交目标 file_token,按 token 删除全部同名引用;SQL 的 id 须映射为 file_token。不要直接提交 SQL 返回对象。
|
|
110
|
+
- 请求前过滤空字段数组和空记录映射,全空则本地短路。不能假定 append 空数组无副作用。
|
|
111
|
+
- 成功后使用 data.attachments 更新本次操作的本地状态,不用立即 SQL 回读覆盖它;从库可能尚未同步。业务结果仍需处理 ignored_fields。
|
|
112
|
+
- batch_update 仅用于明确的整格置空或重设;重设旧图无法从 SQL 补回宽高,不用于普通追加/移除。
|
|
210
113
|
|
|
211
|
-
|
|
114
|
+
服务端仍是读取、合并、写回,不保证原子性、去重或并发不丢项。页面按单元格串行可减少本页交错,但不能保护多个访问者同时写入;不同记录或字段不应共用全局上传锁。严格并发一致性的需求须说明当前能力限制,不通过固定等待时间承诺安全。
|
|
212
115
|
|
|
213
116
|
### 超时与结果未知
|
|
214
117
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
1. 通过页面已有的 SQL Function 按记录读取附件 token,核对本次目标:追加项是否存在、移除项是否消失。回读失败或追加 token 暂未出现都不能证明上一请求没执行;读到的状态也不是跨并发请求的最终保证。
|
|
218
|
-
2. 允许延迟后做有界的只读核对。仍不能确认时保留待确认状态并提示用户,禁止盲目重提 append、拿旧列表整格覆盖或重新上传字节生成另一个 token。
|
|
219
|
-
3. 后续确需重做挂载时,沿用已经上传的 token 和宽高,只提交核对后需要补挂的项,并提示重复引用和并发覆盖风险;当前服务端不保证每次操作仅执行一次。移除按 token 匹配当前引用,但它与追加交错仍受同一覆盖窗口限制。
|
|
220
|
-
|
|
221
|
-
## SQL 侧的可读信息
|
|
222
|
-
|
|
223
|
-
SQL 只提供定位信息,不提供内容。`FILE` 子字段的可读范围与 `UNNEST` 用法见 [SQL Function 专项](sql-function.md)。
|
|
224
|
-
|
|
225
|
-
对附件来说要记住的是:SQL 给出的 `id`(即 `file_token`)与 `name`,加上 `record_id`,即 helper 需要的全部业务坐标;`url` 恒为 null,展示与下载一律走上面两节。
|
|
226
|
-
|
|
227
|
-
**读回的形状不能直接提交。** SQL 给的键名是 `id`,增量路由要的是 `file_token`——移除时必须先 `.map((s) => ({ file_token: s.id }))` 再提交;追加则完全不需要读旧列表(见「写单元格」)。若同一个数组还要用于更新页面本地状态,映射只加在提交那一处,本地状态继续用读回的形状——两者形状不同,共用一个变量就会有一侧出错。
|
|
228
|
-
|
|
229
|
-
## 限额
|
|
230
|
-
|
|
231
|
-
| 限额 | 值 | 说明 |
|
|
232
|
-
|---|---|---|
|
|
233
|
-
| 单文件大小 | 2 GB | **父页面当前的实现值**(与 lark-cli 对齐),由父页面在上传前拒绝,不是平台上限 |
|
|
234
|
-
| 单个单元格附件数 | 100 | |
|
|
235
|
-
| 单个 Base 附件总数 | 2000000 | 计数**只增不减**:删除只移除单元格引用,不删云盘文件 |
|
|
236
|
-
|
|
237
|
-
**只有单文件体积这一项会被拒绝,没有任何累计校验。** 传 100 个 19 MB 的文件全部放行。需要控制总量的业务自己在页面侧限制。
|
|
238
|
-
|
|
239
|
-
## 注意事项
|
|
118
|
+
页面区分上传中、已上传待挂载、挂载结果待确认,保留已有 fileToken 和图片宽高。append 与上传都不幂等,结果未知时不自动重提或重新上传。
|
|
240
119
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- **上传成功不等于写入成功**。拿到 `fileToken` 只是文件进了云盘,还没进单元格;两步之间失败会留下孤儿文件。
|
|
245
|
-
- **`uploadAttachment` 不是幂等的**。同一个文件调两次会得到两个不同的 `fileToken` 和两份云盘文件。所以上传失败**不要自动重试**——除非能确认上一次确实没成功;无法判断时交给用户重新触发。文件越大中断概率越高,这条越要紧。
|
|
246
|
-
- **删除附件只移除单元格里的引用,不删云盘文件**,也不释放单 Base 的附件计数。三条路径(页面整格覆盖、官方 `remove_attachments`、CLI 的 remove)行为一致。不要向用户承诺「删除可释放空间」。
|
|
120
|
+
1. 使用固定 SQL Function 按记录核对目标 token。未立即读到不证明上一请求失败;读到也不保证不会被并发写入覆盖。
|
|
121
|
+
2. 延迟后进行有限次数或有限时长的只读核对。仍不能确认时保留待确认状态并提示用户,不拿旧列表整格覆盖。
|
|
122
|
+
3. 后续明确需要补挂时复用已有 token 与宽高,只处理已核对的目标,并说明可能重复引用和并发覆盖。没有可靠去重原语时不承诺只执行一次。
|
|
247
123
|
|
|
248
|
-
##
|
|
124
|
+
## 限制与错误处理
|
|
249
125
|
|
|
250
|
-
|
|
|
251
|
-
|
|
252
|
-
|
|
|
253
|
-
|
|
|
254
|
-
|
|
|
255
|
-
|
|
|
256
|
-
|
|
|
257
|
-
|
|
|
258
|
-
|
|
|
259
|
-
| 点下载没反应,console 有 warning | 父页面 iframe sandbox 缺 `allow-downloads` |
|
|
260
|
-
| 点下载没反应,console 也没有输出 | 拿不到网关 origin 时静默 return 了,动作入口要给提示 |
|
|
261
|
-
| 一处在上传,其他行的上传按钮全点不动 | 串行化做成了全局标志,只需按单元格串行 |
|
|
262
|
-
| 追加后旧附件不见了 / 少了几张 | 追加走了 `batch_update` 整格覆盖;必须走 `append_attachments` 增量路由,见「写单元格」 |
|
|
263
|
-
| 追加后旧图片全部变为占位方块 | 同上:整格覆盖把旧项重写成无宽高,改用增量路由 |
|
|
264
|
-
| 提交报「参数无效」,payload 里的键是 `id` / `name` | 把 SQL 读回的形状直接提交了,增量路由要 `file_token`,见「SQL 侧的可读信息」 |
|
|
265
|
-
| 移除一张后整格没变化 | 同上;移除 payload 漏了 `id → file_token` 映射 |
|
|
266
|
-
| 同一张图在单元格里出现两份 | `append_attachments` 不按 token 去重;超时后重新提交前先读取确认 |
|
|
267
|
-
| `f.url` 拿到 null | SQL 层不提供链接,见上表 |
|
|
268
|
-
| 刚上传的图不显示,刷新后正常 | 写完立刻去取封面了。改成用本地 blob 展示 |
|
|
269
|
-
| 换下载链接报 `[object Object]`,看不出原因 | 通道层 reject 的是 `{code,msg}` 普通对象不是 `Error`,`String(error)` 取不到内容;改成读 `code` |
|
|
126
|
+
| 条件/错误 | 处理 |
|
|
127
|
+
| --- | --- |
|
|
128
|
+
| INVALID_ATTACHMENT_TARGET | 区分文件类型/大小与应用绑定配置;修正对应输入,不重复发送同一错误请求 |
|
|
129
|
+
| ATTACHMENT_UNAVAILABLE | 父页面不支持上传,报告环境能力限制 |
|
|
130
|
+
| ATTACHMENT_UPLOAD_FAILED / STALLED | 显示进度或网络问题;检查是否已上传,不自动重传 |
|
|
131
|
+
| 位置不匹配、403 或没有封面 | 核对坐标与应用鉴权;封面未就绪按有限重试处理 |
|
|
132
|
+
| 下载操作无响应 | 核对代理错误及 iframe 下载设置;不因缺 gatewayOrigin 直接禁用下载 |
|
|
133
|
+
| 单元格已满或出现 ignored_fields | 不报告全部成功;指出未写入项及原因 |
|
|
134
|
+
| property.capture 字段 | 上传挂载可能被忽略;读取和移除按对应协议处理 |
|
|
270
135
|
|
|
271
|
-
|
|
136
|
+
当前约束包括单文件 2 GB、单元格 100 个附件、Base 附件计数上限 2,000,000;单文件检查属于父页面实现,不代表平台所有接口的统一上限,也不提供累计体积限制。业务需要累计限额时另行控制。附件不能跨 Base 复用;移除引用不释放云盘文件或累计计数。限制变化时以目标环境契约核实,不反复试探上限。
|
|
272
137
|
|
|
273
|
-
|
|
274
|
-
- [SQL Function 专项](sql-function.md) — `FILE` 子字段读取
|
|
275
|
-
- [风格手册](style-guide.md) — 附件展示的视觉规范
|
|
138
|
+
错误对象可能为 `{code,msg}`,不要用 String(error) 丢失诊断信息。只展示必要的安全摘要,不记录临时下载授权链接或用户凭证。
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# 前端设计风格指导
|
|
2
|
+
|
|
3
|
+
首次实现页面、整体视觉改版或视觉评审前完整读取;局部视觉修改读取相关章节并沿用现有设计系统。本文统一适用于一方托管和三方搭建,不依赖宿主身份或构建期注入。只修改数据逻辑时不重做视觉方案。
|
|
4
|
+
|
|
5
|
+
目标是让界面适合具体业务,并以一致的排版、组件、状态反馈和细节保持产品质量。用户已有品牌、设计稿与明确偏好优先;可访问性与安全要求见[工程质量](style-guide.md)。下列数值与选型是默认出发点,不是平台限制。
|
|
6
|
+
|
|
7
|
+
## 设计方案
|
|
8
|
+
|
|
9
|
+
先在内部规划中确定使用者、主要任务与业务特征,再作以下决策;默认不单独创建设计文档,用户要求时提供:
|
|
10
|
+
|
|
11
|
+
1. **色彩**:定义页面背景、内容表面、主次文本、边框、品牌色和独立的成功/警告/危险色。以命名设计变量维护中性色阶,避免逐组件取色。
|
|
12
|
+
2. **排版**:确定标题、正文、辅助文字的字号、字重、行高与数字格式。
|
|
13
|
+
3. **布局与密度**:高频列表与工作台优先信息效率,表单与登记页优先阅读和输入空间;相同任务采用一致密度。
|
|
14
|
+
4. **业务辨识度**:用业务内容、导航结构、品牌色或关键状态表达建立特征。需要视觉强调时集中在少数位置,不让装饰占用核心操作区域。
|
|
15
|
+
5. **交互与动效**:确定控件状态、焦点、过渡时长和响应式策略,落实为可复用组件与设计变量。
|
|
16
|
+
|
|
17
|
+
方案应能解释如何服务当前任务。不要为了与其他应用不同而牺牲已有用户习惯,也不要仅替换 starter 文案就完成视觉交付。
|
|
18
|
+
|
|
19
|
+
## 场景与布局
|
|
20
|
+
|
|
21
|
+
| 页面任务 | 布局重点 | 默认视觉取向 |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| 工作台 | 待办与关键结论前置,再展示快捷入口和动态 | 清晰、紧凑、可预期 |
|
|
24
|
+
| 列表与台账 | 搜索筛选 → 数据 → 行内或批量动作 | 统一列对齐与行密度 |
|
|
25
|
+
| 表单与登记 | 语义分组或分步,主操作始终可达 | 单列优先,适当留白 |
|
|
26
|
+
| 详情 | 标题、状态、关键属性 → 分区内容 → 关联数据 | 稳定层级与对象定位 |
|
|
27
|
+
| 看板与报表 | 指标结论 → 趋势与对比 → 明细 | 以读数为主,主题按使用环境选择 |
|
|
28
|
+
| 门户与展示 | 品牌和核心内容前置 | 可用较大的标题、留白与非对称布局 |
|
|
29
|
+
|
|
30
|
+
工具页不默认使用大幅 hero、装饰插画或营销式首屏。并列内容可用网格,顺序内容用步骤或时间轴,层级内容用分组;结构必须反映真实信息关系,不把所有区块放入同一种白色阴影卡片。
|
|
31
|
+
|
|
32
|
+
## 排版与间距
|
|
33
|
+
|
|
34
|
+
以下作为默认层级,按用户品牌、中文可读性及目标设备调整:
|
|
35
|
+
|
|
36
|
+
| 层级 | 字号 | 字重 | 适用 |
|
|
37
|
+
| --- | --- | --- | --- |
|
|
38
|
+
| Display | 32–56px,使用 clamp | 700–800 | 表达页首屏或关键数字 |
|
|
39
|
+
| Heading | 20–28px | 600–700 | 页面和区块标题 |
|
|
40
|
+
| Card title | 15–17px | 600 | 卡片与表单分组 |
|
|
41
|
+
| Body | 13–15px | 400 | 表格和正文;长正文可增大 |
|
|
42
|
+
| Caption | 12px 起 | 400–500 | 辅助说明,不承载唯一关键信息 |
|
|
43
|
+
|
|
44
|
+
- 层级由字号、字重、对比度和间距共同形成,不能只放大标题。行高以内容可读性为准。
|
|
45
|
+
- 中文强调使用字重,不默认使用斜体或负字距。金额、编号和统计数字使用 `font-variant-numeric: tabular-nums`。
|
|
46
|
+
- 默认系统字体栈;特殊字体经允许的依赖或资源打包进入产物,仅加载所需字重,不引入运行时外链字体 CDN。
|
|
47
|
+
- 间距以 4px 基数和 8px 节奏组织;组间距大于组内间距。表格行高可从紧凑 40px、常规 48px、舒展 56px 选择,相同场景一致。
|
|
48
|
+
|
|
49
|
+
## 表格、表单与按钮
|
|
50
|
+
|
|
51
|
+
- 表格文本左对齐、数字右对齐;状态使用文字与语义色,不能只用颜色区分。操作列置于行尾,次要动作按需收纳。
|
|
52
|
+
- 空值表达一致,例如“-”;长内容截断时提供键盘和触屏可用的完整查看方式,不仅依赖 hover。
|
|
53
|
+
- 行分隔使用细线或斑马纹,避免冗余边框;列表同时设计加载、空、失败、部分数据和无权限状态。
|
|
54
|
+
- 表单标签明确且与控件关联,占位符只提供示例。必填与错误提示一致,提交失败定位首个错误字段。
|
|
55
|
+
- 主按钮、次按钮与文字按钮层级清晰,同一操作区域突出一个主要动作;危险动作写明对象和后果,不作为默认焦点。
|
|
56
|
+
- 提交期间阻止重复操作;成功反馈对应真实业务结果,部分成功明确哪些操作需要继续处理。
|
|
57
|
+
|
|
58
|
+
## 控件与组件体系
|
|
59
|
+
|
|
60
|
+
控件应纳入本应用设计变量和状态体系,同时优先保留可靠交互与可访问性:
|
|
61
|
+
|
|
62
|
+
- 文本输入、textarea、checkbox、radio、range 等可用原生元素配统一边框、焦点和 accent-color。
|
|
63
|
+
- 下拉、菜单、弹窗、Tooltip 等优先复用 starter 的组件模式,按需使用 Radix 无头原语、Tailwind token 与 CVA 变体。日期选择可使用 react-day-picker 配 Popover,不手写复杂日历或定位内核。
|
|
64
|
+
- 移动端原生日期选择器等有明确体验收益时可以保留;同类使用场景保持一致。不要为视觉统一损害键盘或触屏体验。
|
|
65
|
+
- 修改既有项目沿用组件库和主题;新建默认不为单个控件引入第二套完整组件库。确需替换时统一全站主题和设计变量。
|
|
66
|
+
- 图标沿用 starter 的 lucide-react 线性风格,不混用不一致的图标库与 emoji。
|
|
67
|
+
|
|
68
|
+
## 设计变量与主题
|
|
69
|
+
|
|
70
|
+
颜色、字体层级、间距、圆角、阴影、控件高度、过渡时长收敛为 CSS variables 或现有主题 token,组件复用同一套值。禁止为了微小局部差异不断增加近似值。
|
|
71
|
+
|
|
72
|
+
默认浅色主题;用户品牌或使用环境需要暗色时在 token 层实现。仅要求一种主题时不额外实现主题切换。确保文本、边框、焦点和各类状态在所选主题下可辨认;状态色不挪作无关装饰。
|
|
73
|
+
|
|
74
|
+
## 响应式与动效
|
|
75
|
+
|
|
76
|
+
- 保留 viewport 配置,使用流式宽度、max-width、fr、min 与 clamp,避免固定页面宽度。
|
|
77
|
+
- 窄屏重新组织网格和导航;宽表放入独立横向滚动区域,页面整体不溢出。
|
|
78
|
+
- 触控目标默认至少 44×44px;固定控件考虑安全区,hover 有触屏替代反馈。
|
|
79
|
+
- 桌面高频业务保持信息密度,移动端保证核心任务可完成;不能仅缩小桌面页面。
|
|
80
|
+
- 工具页面动效用于反馈和状态过渡,默认 150–250ms;表达页才按内容需要增加入场编排。统一缓动并尊重 prefers-reduced-motion。
|
|
81
|
+
|
|
82
|
+
## 界面文案
|
|
83
|
+
|
|
84
|
+
按钮描述动作结果,例如“保存修改”“删除 3 条记录”。同一概念和动作全站同名。空状态说明内容和下一步,错误说明可恢复动作,不使用只有“出错了”的提示。
|
|
85
|
+
|
|
86
|
+
金额、日期和数字格式按业务及目标时区统一;不同时间精度有实际用途时可采用对应格式。页面不出现 SDK、SQL、binding、发布环境等与使用者任务无关的内部实现信息。避免营销口号、填充词、starter 残留文案及假成功状态。
|
|
87
|
+
|
|
88
|
+
## 交付前自检
|
|
89
|
+
|
|
90
|
+
- 设计方案能在代码中对应到实际 token、排版、密度与组件,而不是仅有文字说明。
|
|
91
|
+
- 首屏内容和主要动作适合当前业务,无无关 hero、装饰卡片或过量渐变。
|
|
92
|
+
- 表格对齐、表单错误、按钮层级和日期数字格式一致;图表选择与比较任务匹配,避免无必要的 3D、仪表盘或过多饼图分类。
|
|
93
|
+
- 焦点、键盘、弹窗、空态、错误和部分成功均有实现;关键文本对比度充分。
|
|
94
|
+
- 桌面和窄屏核心任务可达,无页面级横向溢出;减少动效设置有效。
|
|
95
|
+
- 用户提供的品牌和已有界面得到保留。未做浏览器验证的项目明确列为未验证,不将静态自检报告为真实交互通过。
|
|
96
|
+
|
|
97
|
+
完成实现后进入[发布与交付](release.md);用户要求视觉验收时使用[诊断与验收](verification.md)规定的检查范围。
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# 原生通知集成
|
|
2
|
+
|
|
3
|
+
需求包含原生 workflow 向使用者发送 应用 业务通知时读取。通知应属于用户明确要求的流程;先确认接收人范围、触发条件和业务动作。workflow JSON 按[原生能力路由](base-capability-routing.md)读取当前 CLI 文档,不推测 steps 协议。
|
|
4
|
+
|
|
5
|
+
## 入口策略
|
|
6
|
+
|
|
7
|
+
按用户明确要求优先判定,默认保持 应用 业务对象的操作入口:
|
|
8
|
+
|
|
9
|
+
| 策略 | 条件 | 入口要求 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `base_action` | 用户明确要求进入多维表格 | 可使用 Base URL 或 `recordLink`,不称为 应用 入口 |
|
|
12
|
+
| `informational` | 用户明确要求纯展示、无需点击入口 | 可用 `btn_list=[]`,记录该要求;说明平台仍可能提供默认 Base 跳转 |
|
|
13
|
+
| `site_action` | 其余与 应用 业务对象关联的通知 | 显式 `openLink`,进入 Page 已实现的业务路由并定位对象 |
|
|
14
|
+
|
|
15
|
+
正文已包含业务信息,不构成选择 informational 的依据。访客通知默认进入该登记详情,考试通知进入相应考试详情或答题页;这些是规则示例,不改变用户明确的入口要求。不能用 应用 首页冒充对象详情。
|
|
16
|
+
|
|
17
|
+
`site_action` 使用本次 deploy 返回的顶层 `baseAppUrl`,保留已有查询参数,增加 Page 实际实现的功能定位参数与 workflow 上下文中的最小稳定对象标识。不能使用内部 `staticUrl`、Base URL/recordLink、管理后台或根据 应用 appToken 猜测地址。
|
|
18
|
+
|
|
19
|
+
`btn_list=[]` 仅表示没有显式按钮,不保证整卡不可点击。用户要求任何点击都不能进入 Base 时,先发现可满足要求的方案;没有相应能力则报告限制,不用 informational 规避要求。
|
|
20
|
+
|
|
21
|
+
## Preview 收尾
|
|
22
|
+
|
|
23
|
+
1. 开发 Page 时先实现通知对应路由与对象定位;记下目标 workflow、动作节点、入口策略、按钮字段路径、环境无关的功能参数和原始启停状态。
|
|
24
|
+
2. 新 workflow 延后到 Preview 发布成功、且新建 Base 示例验证通过后创建,避免示例记录触发真实通知。当前 CLI 的新建 workflow 默认禁用;创建前仍检查当前 `+workflow-create --help`,传入稳定的本次 `client_token`。
|
|
25
|
+
3. 取得最终 `baseAppUrl` 后构造完整定义并 create,再 get 核验。已有 workflow 先 get 当前定义和使用范围;正在服务生产用户的流程按[生产入口切换](#生产入口切换)保留原链接,其他流程只修改本次授权字段,用完整 read-modify-write update 后 get。不把旧样例或部分响应当完整配置。
|
|
26
|
+
4. 逐个核对通知动作的入口策略、按钮链接、功能参数、对象标识及状态。site_action 必须定位到真实业务路由;其他策略需有明确需求依据。
|
|
27
|
+
5. 按下表决定启停,必要时启用后再次 get。记录实际结果后返回[发布与交付](release.md),不能把 应用 发布成功等同通知完成。
|
|
28
|
+
|
|
29
|
+
## 状态与失败处理
|
|
30
|
+
|
|
31
|
+
| 情况 | 动作 |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| 本次新建且仍禁用 | 配置核验通过且用户要求通知生效时 enable → get;否则保持禁用 |
|
|
34
|
+
| 已有且禁用,仅修改链接/定义 | 保持禁用;没有启用授权不调用 enable |
|
|
35
|
+
| 已有且启用,仅修改链接/定义 | 保留原状态,核对本次配置;不为“确保生效”重复 enable |
|
|
36
|
+
| 创建、启用或更新结果未知 | 先 get/list 确认现状,沿用本次请求身份,不盲目重复创建 |
|
|
37
|
+
| 配置未通过且仍禁用 | 保持禁用,修正可修复内容或报告 partial/blocked |
|
|
38
|
+
| 已启用后校验失败 | 有针对该 workflow 的停用/补偿授权才 disable → get;否则报告影响并请求该动作授权 |
|
|
39
|
+
|
|
40
|
+
不得未经授权关闭用户已有 workflow。只要有未通过的入口或状态检查,不能报告通知完成;保存脱敏错误和失败节点。修改多个 workflow 时分别保留成功和失败结果,不整体重试已成功操作。
|
|
41
|
+
|
|
42
|
+
## 生产入口切换
|
|
43
|
+
|
|
44
|
+
应用 Prod 发布成功后,使用本次返回的生产 `baseAppUrl`,按 Preview 清单逐一 get → 必要的完整 update → get。site_action 只替换环境入口,保留功能定位参数、动态对象参数、其他步骤和启停状态;最终链接不含 `mode=edit`。已有链接正确时仍回读核对,不做无变化写入。其他策略保留入口意图并复核状态。
|
|
45
|
+
|
|
46
|
+
已有生产 应用 的 Preview 迭代不得把正在服务生产用户的 workflow 链接改为 owner-only Preview。先核对原链接与使用范围:保留生产入口,将新 Preview 的功能参数列入待切换清单;需要独立通知测试时,仅在用户授权的隔离测试流程中执行。
|
|
47
|
+
|
|
48
|
+
任一切换失败时分别报告 应用 发布与通知切换状态;修复后只恢复失败步骤。发布 应用 不会自动迁移外部 workflow,也不授权发送额外测试通知。
|