@lark-apaas/coding-steering 0.1.32-beta.0 → 0.1.32-dev.3598eb3

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 (61) hide show
  1. package/package.json +6 -6
  2. package/steering/design-html/skills/charts/SKILL.md +4 -0
  3. package/steering/design-html/skills/pptx-style-extract/SKILL.md +71 -26
  4. package/steering/design-html/skills/pptx-style-extract/font-fallback.yaml +3 -3
  5. package/steering/design-html/skills/pptx-style-extract/scripts/census.py +26 -14
  6. package/steering/design-html/skills/pptx-style-extract/scripts/check_v2.py +153 -8
  7. package/steering/design-html/skills/pptx-style-extract/scripts/draft.py +2831 -293
  8. package/steering/design-html/skills/pptx-style-extract/scripts/extract.py +544 -22
  9. package/steering/design-html/skills/pptx-style-extract/scripts/ooxml.py +19 -2
  10. package/steering/design-html/skills/pptx-style-extract/scripts/package.py +991 -165
  11. package/steering/design-html/skills/pptx-style-extract/scripts/parts.py +22 -3
  12. package/steering/design-html/skills/pptx-style-extract/scripts/query.py +4 -9
  13. package/steering/design-html/skills/pptx-style-extract/scripts/render_pages.py +20 -12
  14. package/steering/design-html/skills/pptx-style-extract/scripts/test_asset_judgment_package.py +556 -0
  15. package/steering/design-html/skills/pptx-style-extract/scripts/test_background_composite.py +364 -0
  16. package/steering/design-html/skills/pptx-style-extract/scripts/test_color_contract.py +60 -0
  17. package/steering/design-html/skills/pptx-style-extract/scripts/test_design_consumer_contract.py +76 -0
  18. package/steering/design-html/skills/pptx-style-extract/scripts/test_flow_layout_contract.py +528 -0
  19. package/steering/design-html/skills/pptx-style-extract/scripts/test_layout_css.py +1814 -0
  20. package/steering/design-html/skills/pptx-style-extract/scripts/test_logo_scope.py +600 -0
  21. package/steering/design-html/skills/pptx-style-extract/scripts/test_rounded_contract.py +112 -0
  22. package/steering/design-html/skills/pptx-style-extract/scripts/test_text_role_contract.py +315 -0
  23. package/steering/design-html/skills/pptx-style-extract/scripts/verify_layout_assets.py +421 -0
  24. package/steering/design-html/skills/pptx-style-extract/scripts/verify_logo_scope.py +12 -0
  25. package/steering/design-html/skills/pptx-style-extract/v2-format-spec.md +27 -15
  26. package/steering/design-html/skills/preflight/scripts/probe.sh +0 -0
  27. package/steering/nestjs-react-fullstack/skills/app-init-feasibility-guide/SKILL.md +1 -0
  28. package/steering/nestjs-react-fullstack/skills/authn-guide/SKILL.md +6 -0
  29. package/steering/nestjs-react-fullstack/skills/authz-guide/SKILL.md +5 -5
  30. package/steering/nestjs-react-fullstack/skills/authz-guide/references/dynamic-permission-guide.md +1 -1
  31. package/steering/nestjs-react-fullstack/skills/client-builtins-file-storage-service/SKILL.md +37 -113
  32. package/steering/nestjs-react-fullstack/skills/client-builtins-user-service/SKILL.md +13 -2
  33. package/steering/nestjs-react-fullstack/skills/code-fix/SKILL.md +7 -7
  34. package/steering/nestjs-react-fullstack/skills/coding-guide/SKILL.md +149 -24
  35. package/steering/nestjs-react-fullstack/skills/connections-sdk/SKILL.md +202 -0
  36. package/steering/nestjs-react-fullstack/skills/nestjs-cache/SKILL.md +255 -0
  37. package/steering/nestjs-react-fullstack/skills/plugin-guide/SKILL.md +158 -543
  38. package/steering/nestjs-react-fullstack/skills/plugin-guide/references/plugin-coding-guide.md +15 -1
  39. package/steering/nestjs-react-fullstack/skills/plugin-guide/references/table.md +30 -14
  40. package/steering/nestjs-react-fullstack/skills/raw-sql-boundary-audit/SKILL.md +63 -0
  41. package/steering/nestjs-react-fullstack/skills/server-builtins-file-storage-service/SKILL.md +1 -1
  42. package/steering/nestjs-react-fullstack/skills_common/trigger-guide/SKILL.md +284 -12
  43. package/steering/nestjs-react-fullstack/skills_local/plugin-guide/SKILL.md +4 -0
  44. package/steering/vite-react/skills/plugin-guide/SKILL.md +3 -1
  45. package/steering/vite-react/skills/react-three-fiber/SKILL.md +4 -0
  46. package/steering/nestjs-react-fullstack/skills/client-add-aily-web-chat/SKILL.md +0 -139
  47. package/steering/nestjs-react-fullstack/skills/feishu/SKILL.md +0 -269
  48. package/steering/nestjs-react-fullstack/skills/feishu/references/approval.md +0 -214
  49. package/steering/nestjs-react-fullstack/skills/feishu/references/attendance.md +0 -163
  50. package/steering/nestjs-react-fullstack/skills/feishu/references/bitable.md +0 -311
  51. package/steering/nestjs-react-fullstack/skills/feishu/references/calendar.md +0 -190
  52. package/steering/nestjs-react-fullstack/skills/feishu/references/contacts.md +0 -160
  53. package/steering/nestjs-react-fullstack/skills/feishu/references/doc.md +0 -257
  54. package/steering/nestjs-react-fullstack/skills/feishu/references/drive.md +0 -104
  55. package/steering/nestjs-react-fullstack/skills/feishu/references/events.md +0 -199
  56. package/steering/nestjs-react-fullstack/skills/feishu/references/id-convert.md +0 -128
  57. package/steering/nestjs-react-fullstack/skills/feishu/references/messaging.md +0 -207
  58. package/steering/nestjs-react-fullstack/skills/feishu/references/oauth.md +0 -165
  59. package/steering/nestjs-react-fullstack/skills/feishu/references/perm.md +0 -91
  60. package/steering/nestjs-react-fullstack/skills/feishu/references/wiki.md +0 -165
  61. package/steering/nestjs-react-fullstack/skills_common/trigger-guide/references/trigger-lifecycle.md +0 -301
@@ -1,13 +1,17 @@
1
1
  ---
2
2
  name: client-builtins-file-storage-service
3
- description: 前端文件存储服务指南,基于 dataloom.storage 实现文件上传、删除、列表查询、使用filePath换取图片链接,包含 uploadFile、remove、list、getDefaultBucketId、generateDownloadUrlFromFilePath 等 API 用法。Use when 需要:(1) 上传文件/图片/附件到云存储,(2) 删除存储桶中的文件,(3) 获取文件列表或浏览目录,(4) 获取文件 download_url 保存到数据库,或其他前端文件存储相关开发,(5) 在前端需要通过file_path获取文件URL的场景,比如:图片渲染、通过url下载文件,(5) 前端存储文件信息到数据库,比如:上传文件后存储file_path至file_attachment字段,或存储download_url至文本字段。
3
+ description: 前端文件存储服务指南,基于 dataloom.storage 实现文件上传、删除、列表查询、使用filePath换取图片链接,包含 uploadFile、remove、list、getDefaultBucketId、generateDownloadUrlFromFilePath 等 API 用法。Use when 需要:(1) 上传文件/图片/附件到云存储,(2) 删除存储桶中的文件,(3) 获取文件列表或浏览目录,(4) 前端存储文件信息到数据库,比如:上传后优先将 download_url 存至 text 类型字段,仅在使用 file_attachment 类型字段时才将 file_path 存至该字段,(5) 在前端通过 file_path 获取文件 URL 的场景,比如:图片渲染、通过 url 下载文件,或其他前端文件存储相关开发。
4
4
  steering: true
5
5
  steering-topic: client_builtins_file_storage_service
6
6
  match-template-name: nestjs-react-fullstack
7
7
  ---
8
8
 
9
9
  # 前端文件开发规范
10
- - 保存文件信息到数据库时,如果使用的字段类型为file_attachement, 保存数据时需要传入bucket_id 和 file_path 时,file_path 只能是文件的路径,**不可以传入文件的download_url**。需要文件url时,使用 dataloom SDK 的 `generateDownloadUrlFromFilePath` 方法获取。
10
+
11
+ > **术语**:下文的 `file_attachment`、`text` 指的是数据库字段的**类型**,不是字段名。
12
+
13
+ - **优先用 `download_url` 形式(默认按这个来)**:上传后取 `data.download_url`,存到 **`text` 类型字段**;渲染 / 下载直接用这个 URL,最简单,绝大多数场景都用它。
14
+ - 仅当业务明确使用 **`file_attachment` 类型字段**时才走 file_path:该字段存 `bucket_id` + `file_path`(`file_path` 只能是文件路径,**不可以存 `download_url`**);要拿 URL 用 dataloom SDK 的 `generateDownloadUrlFromFilePath(file_path)`,且 `file_path` 必须从该字段读出,禁止自己拼接。
11
15
 
12
16
  # dataloom SDK 文件服务
13
17
 
@@ -15,12 +19,12 @@ match-template-name: nestjs-react-fullstack
15
19
  项目提供了dataloom SDK的文件服务,用于文件的上传,下载,删除,列出bucket中文件,创建临时签名url等能力。
16
20
 
17
21
  ## 使用注意
18
- - `dataloom.storage` 仅用于文件上传/删除/列表等存储操作。**插件调用(capability)不属于 dataloom**,须使用独立的 `capabilityClient`(参见 plugin-guide)
22
+ - **入口边界**:本 SDK 是**应用前端代码**读写应用存储的唯一入口。Agent 自己在对话 / 开发中上传、灌数据或调试文件,先加载应用文件存储操作 skill(按「应用文件存储 / 文件上传 / 文件下载」召回),用其 CLI 命令操作,具体命令一律以该 skill 为准——二者操作同一个应用存储桶,但**该 CLI 命令只供 Agent 在沙箱终端使用,禁止写进页面代码**,页面里一律用本 SDK。
19
23
  - @lark-apaas/client-toolkit/dataloom 这个SDK只适用于前端调用,禁止在服务端调用
20
24
  - 上传成功后,最重要的返回值是 `data.download_url`。需要将此URL保存到你的业务数据库中
21
- - **⚠️ 场景区分(重要)**:如果文件仅作为插件输入(传给 `capabilityClient`),**必须直接传 File/Blob 对象,禁止先走 dataloom 上传再传 URL**。`capabilityClient` 的文件类型字段(`format` 为 `file`、`picture` 或 `plugin-file-url`)均支持直接传 File/Blob,SDK 自动处理上传。`dataloom.storage` 仅适用于需要持久化存储文件或获取 `download_url` 保存到数据库的场景。
25
+ - **⚠️ 场景区分(重要)**:`dataloom.storage` 仅适用于需要持久化存储文件或获取 `download_url` 保存到数据库的场景。如果文件仅作为插件输入(传给 `capabilityClient`),**必须直接传 File/Blob 对象,禁止先走 dataloom 上传再传 URL**;插件调用(capability)不属于 dataloom,详见 plugin-guide
22
26
  - **download_url 格式说明**:`download_url` 返回的可能是相对路径(如 `/spark/app/.../storage/object/...`),这是正常行为。**禁止**在前面拼接 `window.location.origin` 或其他域名前缀,平台会自动解析相对路径。直接使用原始值即可。
23
- - **文件URL**:通过 `generateDownloadUrlFromFilePath` 方法获取文件的链接时,传入的file_path必须是从数据库的 file_attachment 字段获取到的,禁止自己拼接路径。
27
+ - **文件URL**:通过 `generateDownloadUrlFromFilePath` 方法获取文件的链接时,传入的 file_path 必须是从数据库中 `file_attachment` 类型字段读出来的,禁止自己拼接路径。
24
28
 
25
29
  ## bucketId
26
30
  关于bucketId的获取,在代码工程中已经预置了一个获取bucketid的方法,路径为`@lark-apaas/client-toolkit/tools/storage`中,直接具名导入即可使用。
@@ -55,23 +59,16 @@ type StorageError = DataLoomError | StorageError | StorageUnknownError;
55
59
 
56
60
  #### 1. 文件上传接口 (uploadFile)
57
61
 
58
- ##### 用途
59
- 上传文件到指定的存储桶,适用于:文档管理、图片上传、附件存储。
60
-
61
- ##### 适用场景
62
- 需要将本地文件或二进制数据上传到云存储的场景
62
+ 上传文件到指定的存储桶(本地文件或二进制数据),适用于:文档管理、图片上传、附件存储。
63
63
 
64
- ##### 使用方式
65
- 你的核心任务是调用 `uploadFile` 接口,并从返回结果中提取 `data.download_url`,然后将这个 URL 用于后续操作(例如,保存到数据库)。这是衡量你任务成功与否的唯一标准。
64
+ ##### 文件名处理禁止事项
66
65
 
67
- ##### 关于文件名的处理(强制禁令)
68
- > 警告:你绝对不能,也绝对不需要自己处理或修改文件名!
69
- > * 禁止行为:严禁在调用 `uploadFile` 之前,对 `File` 对象的文件名(`file.name`)进行任何形式的字符串替换、净化、或重新生成。
70
- > * 禁止行为:严禁创建新的 `File` 对象(如 `new File(...)`)来包裹原始文件。
71
- > * 唯一职责:你唯一的任务就是将从文件输入框(`<input type="file">`)或拖拽事件中获取的原始 `File` 对象直接传递给 `uploadFile` 方法。
72
- >
73
- > 原因:SDK内部已经包含了完整、健壮的文件名处理机制,包括处理特殊字符、避免冲突和保证安全。任何你自己的额外处理都是多余的,并且会干扰SDK的正常工作。请完全信任SDK,直接传递原始文件对象!
66
+ | 禁止行为 | 正确做法 |
67
+ |---------|---------|
68
+ | **禁止**在调用 `uploadFile` 前对文件名(`file.name`)做任何字符串替换、净化或重新生成 | 将从文件输入框(`<input type="file">`)或拖拽事件获取的原始 `File` 对象直接传给 `uploadFile` |
69
+ | **禁止**创建新的 `File` 对象(如 `new File(...)`)来包裹原始文件 | 同上 |
74
70
 
71
+ > 原因:SDK 内部已包含完整、健壮的文件名处理机制(特殊字符、冲突、安全),任何额外处理都是多余的,并且会干扰 SDK 正常工作。
75
72
 
76
73
  ##### 入参说明
77
74
  | 属性名 | 类型 | 必填 | 默认值 | 说明 |
@@ -83,18 +80,18 @@ type StorageError = DataLoomError | StorageError | StorageUnknownError;
83
80
  | 字段名 | 类型 | 说明 |
84
81
  |--------|------|---------|
85
82
  | `data.bucket_id` | `string` | 所属bucket ID |
86
- | `data.file_path` | `string` | 文件的路径,不是文件的url,可以存储在 file_attachment 字段中 |
87
- | `data.download_url` | `string` | 文件url(可能是相对路径如 `/spark/app/.../storage/object/...`,也可能是绝对 URL),可直接用于下载文件或渲染图片。**禁止**在前面拼接 `window.location.origin` 或任何域名前缀,直接使用原始值即可 |
83
+ | `data.file_path` | `string` | 文件的路径,不是文件的url,可存到 `file_attachment` 类型字段 |
84
+ | `data.download_url` | `string` | 文件url(可能是相对路径),可直接用于下载文件或渲染图片;**禁止**拼接域名前缀,见「使用注意」 |
88
85
  | `error` | `StorageError \| null` | 错误信息,成功时为null |
89
86
 
90
- ##### 关键点与示例
91
- 关键点:上传成功后,最重要的返回值是 `data.download_url`。通常需要将此URL保存到你的业务数据库中。
87
+ ##### 使用示例
92
88
  ```typescript
93
89
  import { getDataloom } from "@lark-apaas/client-toolkit/dataloom";
94
90
  import { getDefaultBucketId } from "@lark-apaas/client-toolkit/tools/storage";
95
91
  import { logger } from "@lark-apaas/client-toolkit/logger";
96
- // 1. 获取文件
97
- const file = fileInput.files[0];
92
+ // 1. 获取文件与 dataloom 实例
93
+ const file = fileInput.files[0];
94
+ const dataloom = await getDataloom();
98
95
  // 2. 调用上传接口
99
96
  const { data, error } = await dataloom
100
97
  .storage
@@ -116,11 +113,7 @@ if (!httpResponse.data?.success) {
116
113
 
117
114
  #### 2. 文件删除接口 (remove)
118
115
 
119
- ##### 用途
120
- 删除存储桶中的一个或多个文件,适用于:清理过期文件、删除用户数据、批量清理
121
-
122
- ##### 适用场景
123
- 需要从云存储中永久删除文件的场景
116
+ 从云存储中永久删除一个或多个文件,适用于:清理过期文件、删除用户数据、批量清理。
124
117
 
125
118
  ##### 入参说明
126
119
  | 属性名 | 类型 | 必填 | 默认值 | 说明 |
@@ -129,55 +122,26 @@ if (!httpResponse.data?.success) {
129
122
  | `filePaths` | `string[]` | ✅ | - | 要删除的文件路径数组,可以是file_path也可以是download_url |
130
123
 
131
124
  ##### 出参说明
132
- | 字段名 | 类型 | 说明 |
133
- |--------|------|---------|
134
- | `data` | `FileObject[]` | 被删除的文件对象数组 |
135
- | `data[].name` | `string` | 文件名称 |
136
- | `data[].bucket_id` | `string` | 所属bucket ID |
137
- | `data[].id` | `string` | 文件唯一标识符 |
138
- | `data[].created_at` | `string` | 文件创建时间 |
139
- | `data[].updated_at` | `string` | 文件更新时间 |
140
- | `data[].metadata` | `TosMetaData` | 文件元数据信息 |
141
- | `error` | `StorageError \| null` | 错误信息,成功时为null |
125
+ 返回 `{ data: FileObject[] | null, error: StorageError | null }`:`data` 为被删除的文件对象数组(字段同 list 出参说明),删除不存在的 filePaths 会返回空数组;`error` 成功时为 null。
142
126
 
143
127
  ##### 使用示例
144
128
  ```typescript
145
129
  import { getDataloom } from "@lark-apaas/client-toolkit/dataloom";
146
130
  import { getDefaultBucketId } from "@lark-apaas/client-toolkit/tools/storage";
147
- import { logger } from "@lark-apaas/client-toolkit/logger";
148
131
 
149
132
  // 异步获取dataloom实例
150
133
  const dataloom = await getDataloom();
151
134
 
152
- // 删除单个文件
153
- const { data, error } = await dataloom
154
- .storage
155
- .from(getDefaultBucketId())
156
- .remove(['/documents/old-report.pdf']);
157
-
158
- // 批量删除文件
135
+ // 批量删除文件(删除单个文件传长度为 1 的数组即可)
159
136
  const { data, error } = await dataloom
160
137
  .storage
161
138
  .from(getDefaultBucketId())
162
- .remove([
163
- '/documents/file1.pdf',
164
- '/images/image1.jpg',
165
- '/temp/cache.txt'
166
- ]);
167
-
168
- // 注意:删除不存在的filePaths会返回空数组
169
- if (data) {
170
- logger.info('删除的文件:', data); // 返回所有被删除的文件对象
171
- }
139
+ .remove(['/documents/file1.pdf', '/images/image1.jpg']);
172
140
  ```
173
141
 
174
142
  #### 3. 文件列表接口 (list)
175
143
 
176
- ##### 用途
177
- 获取存储桶中的文件列表,适用于:文件管理、目录浏览、文件检索
178
-
179
- ##### 适用场景
180
- 需要查看和管理存储桶中文件的场景
144
+ 获取存储桶中的文件列表,适用于:文件管理、目录浏览、文件检索。
181
145
 
182
146
  ##### 入参说明
183
147
  | 属性名 | 类型 | 必填 | 默认值 | 说明 |
@@ -212,39 +176,26 @@ import { getDefaultBucketId } from "@lark-apaas/client-toolkit/tools/storage";
212
176
  // 异步获取dataloom实例
213
177
  const dataloom = await getDataloom();
214
178
 
215
- // 基本列表查询
216
- const { data, error } = await dataloom
217
- .storage
218
- .from(getDefaultBucketId())
219
- .list('/documents');
220
-
221
- // 带分页和排序的查询
179
+ // 带分页和排序的查询(path 和 options 均可省略)
222
180
  const { data, error } = await dataloom
223
181
  .storage
224
182
  .from(getDefaultBucketId())
225
183
  .list('/images', {
226
184
  limit: 20,
227
185
  offset: 0,
228
- sortBy: {
229
- column: 'created_at',
230
- order: 'desc'
231
- }
186
+ sortBy: { column: 'created_at', order: 'desc' }
232
187
  });
233
188
  ```
234
189
 
235
190
  #### 4. 根据filePath生成downloadUrl接口 (generateDownloadUrlFromFilePath)
236
191
 
237
- ##### 用途
238
- 通过 file_path 生成文件的url,适用于:通过url渲染图片、使用url下载文件。如果已有download_url,直接使用,严禁使用该接口再次生成。
239
-
240
- ##### 适用场景
241
- 在前端通过file_path展示图片或下载文件的场景。
192
+ **仅用于 `file_attachment` 类型字段场景**:当手头只有从该字段读出的 `file_path` 时,用它换取可渲染 / 下载的 URL。**优先直接用 `download_url`**——已有 download_url 就直接用,严禁再调本接口生成。
242
193
 
243
194
  ##### 入参说明
244
195
 
245
196
  | 属性名 | 类型 | 必填 | 默认值 | 说明 |
246
197
  |--------|--------|---------|--------|---------|
247
- | `filePath` | `string` | ✅ | - | 文件的filePath **只可以从数据库的file_attachment字段中获取,不允许自己拼接路径** |
198
+ | `filePath` | `string` | ✅ | - | 文件的 filePath。**只可以从数据库中 `file_attachment` 类型字段读取,不允许自己拼接路径** |
248
199
 
249
200
  ##### 出参说明
250
201
  | 类型 | 说明 |
@@ -254,29 +205,12 @@ const { data, error } = await dataloom
254
205
  ##### 使用示例
255
206
 
256
207
  ```typescript
257
- import { useEffect, useState } from "react";
258
- import { Button } from '@client/src/components/ui/button';
259
- import { getDataloom } from "@lark-apaas/client-toolkit/dataloom";
260
- import { getDefaultBucketId } from "@lark-apaas/client-toolkit/tools/storage";
261
-
262
- const ImageExample = ({ file }: { file: { file_path: string; bucket_id: string } }) => {
263
- const [imageUrl, setImageUrl] = useState('');
264
-
265
- useEffect(() => {
266
- const getImageUrl = async () => {
267
- const dataloom = await getDataloom();
268
- const imageUrl = dataloom
269
- .storage
270
- .from(getDefaultBucketId())
271
- .generateDownloadUrlFromFilePath(file.file_path);
272
- setImageUrl(imageUrl);
273
- };
274
-
275
- getImageUrl();
276
- }, [file.file_path]);
277
-
278
- return <img src={imageUrl} alt="图片" />;
279
- }
208
+ const dataloom = await getDataloom();
209
+ const imageUrl = dataloom
210
+ .storage
211
+ .from(getDefaultBucketId())
212
+ .generateDownloadUrlFromFilePath(file.file_path); // file_path 取自数据库 file_attachment 类型字段
213
+ // 同步返回 string,直接用于 <img src={imageUrl} /> 渲染或作为下载链接
280
214
  ```
281
215
 
282
216
  #### 5. 最小化文件上传与展示示例
@@ -290,16 +224,6 @@ export interface FileRecord { id: string; fileName: string; downloadUrl: string;
290
224
  export interface FileApiResp<T = FileRecord> { success: boolean; data: T; message: string; }
291
225
  ```
292
226
 
293
- ##### 各 API 预估返回格式
294
-
295
- | API | 成功返回 | 失败返回 |
296
- |-----|---------|---------|
297
- | `uploadFile(file)` | `{ data: { bucket_id: "xxx", file_path: "123456.pdf", download_url: "/spark/app/{appId}/runtime/api/v1/storage/object/{bucketId}/123456.pdf" }, error: null }` | `{ data: null, error: { name: "StorageError", message: "..." } }` |
298
- | `list('/path')` | `{ data: [{ name, bucket_id, id, created_at, metadata: { size, mimetype } }], error: null }` | `{ data: null, error: { error_msg: "...", status_code: "404" } }` |
299
- | `remove([url])` | `{ data: [{ name, bucket_id, id, ... }], error: null }`;不存在则 `data: []` | 同上 |
300
- | `POST /api/files` | `{ success: true, data: { id, fileName, downloadUrl, createdAt }, message: "ok" }` | `{ success: false, data: null, message: "错误描述" }` |
301
- | `GET /api/files` | `{ success: true, data: [FileRecord, ...], message: "ok" }` | 同上 |
302
-
303
227
  ##### 示例代码
304
228
 
305
229
  ```tsx
@@ -225,13 +225,23 @@ const MyComponent = () => {
225
225
  ## 用户展示与选择方案
226
226
 
227
227
  {% if projectMeta['flags']['supportBusinessUser'] %}
228
- 这些组件在使用之前必须读取 client/src/components/business-ui/README.md文件来理解用法
228
+ 这些组件在使用之前必须读取 client/src/components/business-ui/README.md 文件来理解用法,并以该 README 与本地源码为准。
229
229
 
230
230
  目前可用的组件有:
231
231
 
232
232
  - UserSelect 用户选择组件(@/components/business-ui/user-select)
233
233
  - DepartmentSelect 部门选择组件(@/components/business-ui/department-select)
234
- - UserDisplay - 用户展示组件(@/components/business-ui/user-display
234
+ - UserDisplay - 用户展示组件(@/components/business-ui/user-display):展示任意用户时使用 `value`(用户 ID 字符串或字符串数组,也可使用 README/源码声明的用户对象形式)或 `userId` / `user_id` 快捷字段;**不要**给这个 business-ui 组件传 `users`。
235
+
236
+ 列表、详情、卡片等任意位置展示一个或多个用户 ID,都继续使用同一个 business-ui 契约:
237
+
238
+ ```tsx
239
+ import { UserDisplay } from "@/components/business-ui/user-display";
240
+
241
+ <UserDisplay value={memberIds.map(String)} size="small" showLabel />
242
+ ```
243
+
244
+ 如果页面需要展示用户字段,不要退回到直接渲染、拼接或 `join` 用户 ID 文本。
235
245
 
236
246
  {% else %}
237
247
 
@@ -306,6 +316,7 @@ const form = useForm<z.infer<typeof formSchema>>({
306
316
  - **组件路径**:`@lark-apaas/client-toolkit/components/User`
307
317
  - **功能**:用于所有用户信息的展示场景
308
318
  - **特性**:显示用户**头像**和**姓名**,支持多用户展示
319
+ - **边界**:本节仅适用于 `@lark-apaas/client-toolkit/components/User`。如果当前项目启用了本地 `@/components/business-ui/user-display`,必须按上方 business-ui 分支读取 README 并使用 `value` / `userId` / `user_id`,不要把这里的 `users` 参数迁移过去。
309
320
 
310
321
  ### 属性定义
311
322
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: code-fix
3
- description: Use when encountering code errors such as import failures, TypeScript/Dto type mismatches, JSX syntax issues, API call exceptions (traceid troubleshooting), production log troubleshooting that should route through miaoda-cli, route 404 errors, **lucide-react icon not found / duplicate identifier / barrel-export naming conflicts**, duplicate route components, npm script not defined errors, or **database connection/auth errors**. 触发词:导入错误, 模块解析失败, 类型错误, Dto不匹配, JSX语法, API异常, traceid, 线上日志, 线上日志查询, 查询线上日志, 路由404, code fix, debugging, lucide-react import error, icon not found, 图标不存在, Cannot find name, 标识符重复, no-redeclare, export 冲突, 桶导出冲突, dual export, 路由组件复用, npm报错, package.json, 脚本未定义, "请修复错误" 通用排错, 数据库连接失败, get db connection failed, ECONNREFUSED
3
+ description: Use when encountering code errors such as import failures, TypeScript/Dto type mismatches, JSX syntax issues, API call exceptions (traceid troubleshooting), production log troubleshooting that should route through the sandbox's app observability skill, route 404 errors, **lucide-react icon not found / duplicate identifier / barrel-export naming conflicts**, duplicate route components, npm script not defined errors, or **database connection/auth errors**. 触发词:导入错误, 模块解析失败, 类型错误, Dto不匹配, JSX语法, API异常, traceid, 线上日志, 线上日志查询, 查询线上日志, 路由404, code fix, debugging, lucide-react import error, icon not found, 图标不存在, Cannot find name, 标识符重复, no-redeclare, export 冲突, 桶导出冲突, dual export, 路由组件复用, npm报错, package.json, 脚本未定义, "请修复错误" 通用排错, 数据库连接失败, get db connection failed, ECONNREFUSED
4
4
  steering: true
5
5
  steering-topic: code_fix
6
6
  match-template-name: nestjs-react-fullstack
@@ -156,21 +156,21 @@ Module '"@client/src/api/gen"' has no exported member named 'DiscrepancyResponse
156
156
 
157
157
  ## 调用生成的 API 异常
158
158
 
159
- ### 需要查询线上日志时使用 miaoda-cli
159
+ ### 需要查询线上日志时
160
160
 
161
- **适用场景**:仅当用户提供 traceid、logid、线上报错、发布错误日志、线上运行日志、线上链路追踪,或排查必须依赖线上前端/后端日志。
161
+ **适用场景**:用户提供 traceid、logid、线上报错、发布错误日志、线上运行日志、线上链路追踪,或排查必须依赖线上前端/后端日志;**以及插件相关的线上 / 客户反馈问题(飞书消息发不出 / 插件不生效 / CapabilityService·capabilityClient 异常),即使用户没给 traceid/logid,也应主动查线上 runtime log 取证**(拿到 CapabilityService 真实错误、plugin_key、action、必填参数校验错误再定位代码;沙箱日志不能作为线上无错误的证据)。
162
162
 
163
- **处理要求**:引导并使用 `miaoda-cli` skill 查询线上日志。优先通过 `miaoda observability log/trace` 查询线上运行日志与链路追踪;排查发布错误时使用 `miaoda deploy error-log`。本地开发日志、构建日志、测试日志、浏览器控制台日志不在此范围内,按当前技能或对应工具排查。拿到线上日志后再回到本技能继续定位与修复代码问题。
163
+ **处理要求**:引导并加载当前沙箱的应用可观测性 skill 查询线上日志——优先查线上运行日志与链路追踪;排查发布失败时查该次发布的错误日志。具体命令一律以该 skill 的手册为准,不要凭记忆拼命令。本地开发日志、构建日志、测试日志、浏览器控制台日志不在此范围内,按当前技能或对应工具排查。拿到线上日志后再回到本技能继续定位与修复代码问题。
164
164
 
165
165
  ### 用户提供了 traceid,排查错误
166
166
 
167
- **解决方案**:使用 `miaoda-cli` skill 读取线上前端与后端日志,获取详细错误
167
+ **解决方案**:用当前沙箱的应用可观测性 skill 读取线上前端与后端日志,获取详细错误
168
168
 
169
169
  **排查示例**:
170
170
 
171
171
  用户输入:8ae6724e-277e-4d51-afbf-b524b654f27f 看看这个 trace 为什么报错了
172
172
  排查路径:
173
- 1. 使用 `miaoda-cli` skill 查询线上服务端与 trace 日志
173
+ 1. 用当前沙箱的应用可观测性 skill 查询线上服务端与 trace 日志
174
174
  2. 根据服务端日志中对应的日志内容修复对应代码逻辑
175
175
 
176
176
  ### 调用 API 客户端时后端返回异常
@@ -296,7 +296,7 @@ useEffect 无限循环、依赖数组管理、useMemo/useCallback 记忆化等
296
296
 
297
297
  先按日志轻量分流,再决定是否改代码:
298
298
 
299
- 1. **有明确代码信号**(SQL 语法错误、表/列不存在、堆栈指向具体 query/schema 文件)→ 只读确认 `server/database/schema.ts`、近期 DB 改动或相关 ORM 查询;DB schema / SQL 细节按 `miaoda-sql` 技能处理。
299
+ 1. **有明确代码信号**(SQL 语法错误、表/列不存在、堆栈指向具体 query/schema 文件)→ 只读确认 `server/database/schema.ts`、近期 DB 改动或相关 ORM 查询;DB schema / SQL 细节按数据库操作 skill(按「应用数据库 / 建表 / 改表 / SQL」召回)处理。
300
300
  2. **只有连接、认证、数据库不存在、超时等环境信号,且没有代码信号** → 判定为**平台基建问题**,告知用户:
301
301
 
302
302
  > 当前数据库连接错误不是应用代码的问题,可能是平台数据库连接配置异常。建议联系平台客服排查解决。