@lark-base-open/base-database-cli 1.3.9 → 1.4.3
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 +75 -0
- package/README.md +119 -15
- package/THIRD_PARTY_LICENSES.json +1662 -0
- package/config-schema.json +64 -3
- package/data/template-hmr-scripts.json +9 -0
- package/data/template-index-html/17e698eef687ece8f1628e3e2c4801da5e7233faa87076b3424acde8df57b825.html +24 -0
- package/dist/agent-tools-guide.d.ts +29 -0
- package/dist/agent-tools-guide.d.ts.map +1 -0
- package/dist/agent-tools-guide.js +169 -0
- package/dist/agent-tools-guide.js.map +1 -0
- package/dist/agent-tools-skill.d.ts +16 -0
- package/dist/agent-tools-skill.d.ts.map +1 -0
- package/dist/agent-tools-skill.js +183 -0
- package/dist/agent-tools-skill.js.map +1 -0
- package/dist/agent-tools.d.ts +20 -0
- package/dist/agent-tools.d.ts.map +1 -0
- package/dist/agent-tools.js +137 -0
- package/dist/agent-tools.js.map +1 -0
- package/dist/ai-functions.d.ts +10 -0
- package/dist/ai-functions.d.ts.map +1 -1
- package/dist/ai-functions.js +264 -212
- package/dist/ai-functions.js.map +1 -1
- package/dist/app-builder/core.d.mts +37 -0
- package/dist/app-builder/core.d.mts.map +1 -0
- package/dist/app-builder/core.mjs +673 -0
- package/dist/app-builder/core.mjs.map +1 -0
- package/dist/app-builder/package.json +1 -0
- package/dist/app-builder/schema.d.ts +4 -0
- package/dist/app-builder/schema.d.ts.map +1 -0
- package/dist/app-builder/schema.js +72 -0
- package/dist/app-builder/schema.js.map +1 -0
- package/dist/archive.d.ts +22 -2
- package/dist/archive.d.ts.map +1 -1
- package/dist/archive.js +311 -74
- package/dist/archive.js.map +1 -1
- package/dist/auth.d.ts +2 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +13 -8
- package/dist/auth.js.map +1 -1
- package/dist/build-server.d.ts +25 -0
- package/dist/build-server.d.ts.map +1 -0
- package/dist/build-server.js +32 -0
- package/dist/build-server.js.map +1 -0
- package/dist/business-update-notice.d.ts +37 -0
- package/dist/business-update-notice.d.ts.map +1 -0
- package/dist/business-update-notice.js +24 -0
- package/dist/business-update-notice.js.map +1 -0
- package/dist/check.d.ts +11 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +85 -15
- package/dist/check.js.map +1 -1
- package/dist/cloud-build-diagnostic.d.ts +9 -0
- package/dist/cloud-build-diagnostic.d.ts.map +1 -0
- package/dist/cloud-build-diagnostic.js +65 -0
- package/dist/cloud-build-diagnostic.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +41 -11
- package/dist/config.js.map +1 -1
- package/dist/contract-extractor.d.ts +21 -0
- package/dist/contract-extractor.d.ts.map +1 -0
- package/dist/contract-extractor.js +260 -0
- package/dist/contract-extractor.js.map +1 -0
- package/dist/contract-worker.d.ts +12 -0
- package/dist/contract-worker.d.ts.map +1 -0
- package/dist/contract-worker.js +90 -0
- package/dist/contract-worker.js.map +1 -0
- package/dist/dependency-policy.d.ts.map +1 -1
- package/dist/dependency-policy.js +6 -1
- package/dist/dependency-policy.js.map +1 -1
- package/dist/deploy.d.ts +20 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +181 -52
- package/dist/deploy.js.map +1 -1
- package/dist/dev-bootstrap.d.ts +5 -0
- package/dist/dev-bootstrap.d.ts.map +1 -0
- package/dist/dev-bootstrap.js +185 -0
- package/dist/dev-bootstrap.js.map +1 -0
- package/dist/dev-events.d.ts +24 -0
- package/dist/dev-events.d.ts.map +1 -0
- package/dist/dev-events.js +67 -0
- package/dist/dev-events.js.map +1 -0
- package/dist/dev-pairing.d.ts +4 -0
- package/dist/dev-pairing.d.ts.map +1 -0
- package/dist/dev-pairing.js +54 -0
- package/dist/dev-pairing.js.map +1 -0
- package/dist/dev-url.d.ts +4 -0
- package/dist/dev-url.d.ts.map +1 -0
- package/dist/dev-url.js +29 -0
- package/dist/dev-url.js.map +1 -0
- package/dist/dev-vite.d.ts +9 -0
- package/dist/dev-vite.d.ts.map +1 -0
- package/dist/dev-vite.js +237 -0
- package/dist/dev-vite.js.map +1 -0
- package/dist/dev-watch.d.ts +33 -0
- package/dist/dev-watch.d.ts.map +1 -0
- package/dist/dev-watch.js +246 -0
- package/dist/dev-watch.js.map +1 -0
- package/dist/dev.d.ts +24 -0
- package/dist/dev.d.ts.map +1 -0
- package/dist/dev.js +244 -0
- package/dist/dev.js.map +1 -0
- package/dist/development-pairing.generated.d.ts +12 -0
- package/dist/development-pairing.generated.d.ts.map +1 -0
- package/dist/development-pairing.generated.js +13 -0
- package/dist/development-pairing.generated.js.map +1 -0
- package/dist/diagnostic-platforms.d.ts +3 -0
- package/dist/diagnostic-platforms.d.ts.map +1 -0
- package/dist/diagnostic-platforms.js +3 -0
- package/dist/diagnostic-platforms.js.map +1 -0
- package/dist/diagnostic-schema.d.ts +151 -0
- package/dist/diagnostic-schema.d.ts.map +1 -0
- package/dist/diagnostic-schema.js +129 -0
- package/dist/diagnostic-schema.js.map +1 -0
- package/dist/diagnostics.d.ts +78 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +333 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/distribution-commands.d.ts.map +1 -1
- package/dist/distribution-commands.js +6 -2
- package/dist/distribution-commands.js.map +1 -1
- package/dist/distribution-npm.d.ts +2 -2
- package/dist/distribution-npm.d.ts.map +1 -1
- package/dist/distribution-npm.js +14 -1
- package/dist/distribution-npm.js.map +1 -1
- package/dist/environment-variables.d.ts.map +1 -1
- package/dist/environment-variables.js +2 -1
- package/dist/environment-variables.js.map +1 -1
- package/dist/function-contracts.d.ts +40 -0
- package/dist/function-contracts.d.ts.map +1 -0
- package/dist/function-contracts.js +357 -0
- package/dist/function-contracts.js.map +1 -0
- package/dist/function-description.d.ts +11 -4
- package/dist/function-description.d.ts.map +1 -1
- package/dist/function-description.js +22 -12
- package/dist/function-description.js.map +1 -1
- package/dist/function-input-types.d.ts +6 -4
- package/dist/function-input-types.d.ts.map +1 -1
- package/dist/function-input-types.js +97 -135
- package/dist/function-input-types.js.map +1 -1
- package/dist/function-params.d.ts +53 -0
- package/dist/function-params.d.ts.map +1 -0
- package/dist/function-params.js +184 -0
- package/dist/function-params.js.map +1 -0
- package/dist/function-schema.d.ts +14 -0
- package/dist/function-schema.d.ts.map +1 -1
- package/dist/function-schema.js +99 -9
- package/dist/function-schema.js.map +1 -1
- package/dist/init-journal.d.ts +1 -0
- package/dist/init-journal.d.ts.map +1 -1
- package/dist/init-journal.js +21 -7
- package/dist/init-journal.js.map +1 -1
- package/dist/init.d.ts +1 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +55 -5
- package/dist/init.js.map +1 -1
- package/dist/lark-cli-error.d.ts +13 -2
- package/dist/lark-cli-error.d.ts.map +1 -1
- package/dist/lark-cli-error.js +54 -13
- package/dist/lark-cli-error.js.map +1 -1
- package/dist/lark-cli-passthrough.d.ts +9 -0
- package/dist/lark-cli-passthrough.d.ts.map +1 -0
- package/dist/lark-cli-passthrough.js +101 -0
- package/dist/lark-cli-passthrough.js.map +1 -0
- package/dist/lark-cli.d.ts +5 -2
- package/dist/lark-cli.d.ts.map +1 -1
- package/dist/lark-cli.js +96 -29
- package/dist/lark-cli.js.map +1 -1
- package/dist/legacy-function-input-renderer.d.ts +6 -0
- package/dist/legacy-function-input-renderer.d.ts.map +1 -0
- package/dist/legacy-function-input-renderer.js +175 -0
- package/dist/legacy-function-input-renderer.js.map +1 -0
- package/dist/link-guard-check.d.ts +12 -0
- package/dist/link-guard-check.d.ts.map +1 -0
- package/dist/link-guard-check.js +138 -0
- package/dist/link-guard-check.js.map +1 -0
- package/dist/managed-agent-docs.d.ts +14 -0
- package/dist/managed-agent-docs.d.ts.map +1 -0
- package/dist/managed-agent-docs.js +172 -0
- package/dist/managed-agent-docs.js.map +1 -0
- package/dist/mutation-schema.d.ts +6 -0
- package/dist/mutation-schema.d.ts.map +1 -1
- package/dist/mutation-schema.js +6 -0
- package/dist/mutation-schema.js.map +1 -1
- package/dist/mutation.d.ts +4 -1
- package/dist/mutation.d.ts.map +1 -1
- package/dist/mutation.js +17 -2
- package/dist/mutation.js.map +1 -1
- package/dist/npm.d.ts +1 -0
- package/dist/npm.d.ts.map +1 -1
- package/dist/npm.js +28 -0
- package/dist/npm.js.map +1 -1
- package/dist/preview-receipt.d.ts +0 -2
- package/dist/preview-receipt.d.ts.map +1 -1
- package/dist/preview-receipt.js +0 -28
- package/dist/preview-receipt.js.map +1 -1
- package/dist/process.d.ts +1 -0
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +25 -0
- package/dist/process.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +239 -26
- package/dist/program.js.map +1 -1
- package/dist/project-build.d.ts +2 -1
- package/dist/project-build.d.ts.map +1 -1
- package/dist/project-build.js +53 -16
- package/dist/project-build.js.map +1 -1
- package/dist/project-capabilities.d.ts +8 -0
- package/dist/project-capabilities.d.ts.map +1 -0
- package/dist/project-capabilities.js +47 -0
- package/dist/project-capabilities.js.map +1 -0
- package/dist/project-context.d.ts +66 -0
- package/dist/project-context.d.ts.map +1 -1
- package/dist/project-context.js +68 -6
- package/dist/project-context.js.map +1 -1
- package/dist/project-layout.d.ts +11 -0
- package/dist/project-layout.d.ts.map +1 -1
- package/dist/project-layout.js +63 -1
- package/dist/project-layout.js.map +1 -1
- package/dist/public-exports.d.ts +5 -0
- package/dist/public-exports.d.ts.map +1 -0
- package/dist/public-exports.js +76 -0
- package/dist/public-exports.js.map +1 -0
- package/dist/public-sql-error.d.ts +3 -1
- package/dist/public-sql-error.d.ts.map +1 -1
- package/dist/public-sql-error.js +5 -2
- package/dist/public-sql-error.js.map +1 -1
- package/dist/pull.d.ts +1 -0
- package/dist/pull.d.ts.map +1 -1
- package/dist/pull.js +103 -20
- package/dist/pull.js.map +1 -1
- package/dist/sdk-codegen.d.ts +16 -0
- package/dist/sdk-codegen.d.ts.map +1 -0
- package/dist/sdk-codegen.js +181 -0
- package/dist/sdk-codegen.js.map +1 -0
- package/dist/sdk-install.d.ts +4 -0
- package/dist/sdk-install.d.ts.map +1 -0
- package/dist/sdk-install.js +33 -0
- package/dist/sdk-install.js.map +1 -0
- package/dist/skill-frontmatter.d.ts +5 -0
- package/dist/skill-frontmatter.d.ts.map +1 -0
- package/dist/skill-frontmatter.js +28 -0
- package/dist/skill-frontmatter.js.map +1 -0
- package/dist/skill.d.ts +2 -1
- package/dist/skill.d.ts.map +1 -1
- package/dist/skill.js +18 -12
- package/dist/skill.js.map +1 -1
- package/dist/source-format.d.ts +10 -0
- package/dist/source-format.d.ts.map +1 -0
- package/dist/source-format.js +49 -0
- package/dist/source-format.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/unified-functions.d.ts +22 -0
- package/dist/unified-functions.d.ts.map +1 -0
- package/dist/unified-functions.js +114 -0
- package/dist/unified-functions.js.map +1 -0
- package/dist/updates.d.ts +13 -1
- package/dist/updates.d.ts.map +1 -1
- package/dist/updates.js +65 -29
- package/dist/updates.js.map +1 -1
- package/dist/workspace-fingerprint.d.ts.map +1 -1
- package/dist/workspace-fingerprint.js +5 -0
- package/dist/workspace-fingerprint.js.map +1 -1
- package/package.json +17 -5
- package/skills/lark-base-database/SKILL.md +21 -55
- package/skills/lark-base-database/references/agent-tool-design.md +181 -0
- package/skills/lark-base-database/references/agent-tools.md +101 -0
- package/skills/lark-base-database/references/ai-function.md +80 -186
- package/skills/lark-base-database/references/database-function-limitations.md +12 -4
- package/skills/lark-base-database/references/database-function.md +49 -21
- package/skills/lark-base-database/references/development.md +81 -109
- package/skills/lark-base-database/references/environment-variables.md +2 -2
- package/skills/lark-base-database/references/faas.md +43 -16
- package/skills/lark-base-database/references/file-transfer.md +10 -33
- package/skills/lark-base-database/references/frontend-design-guide.md +1 -1
- package/skills/lark-base-database/references/legacy-ai-function.md +120 -0
- package/skills/lark-base-database/references/legacy-development.md +156 -0
- package/skills/lark-base-database/references/legacy-file-transfer.md +68 -0
- package/skills/lark-base-database/references/mutations.md +38 -29
- package/skills/lark-base-database/references/notifications.md +1 -1
- package/skills/lark-base-database/references/permission-design.md +11 -5
- package/skills/lark-base-database/references/release.md +22 -7
- package/skills/lark-base-database/references/verification.md +55 -16
- package/skills/lark-base-database/references/workspace-migration.md +86 -0
- package/skills/lark-base-database/references/workspace.md +55 -44
- package/templates/database-starter/README.md +2 -0
- package/templates/database-starter/database-functions/README.md +2 -2
- package/templates/database-starter/mutations/README.md +2 -2
- package/templates/database-starter/page/README.md +5 -4
- package/templates/database-starter/page/src/examples/ai-function/TextStreamOperation.tsx +6 -6
- package/templates/database-starter/page/src/lib/attachment-image.tsx +19 -5
- package/templates/database-starter/page/src/lib/database-runtime-attachment.test.ts +124 -5
- package/templates/database-starter/page/src/lib/database-runtime.test.ts +2 -2
- package/templates/database-starter/page/src/lib/database-runtime.ts +77 -13
- package/templates/database-starter/server-functions/scripts/run-tsc.mjs +3 -2
- package/templates/database-starter-v2/README.md +25 -0
- package/templates/database-starter-v2/base-app.config.ts +10 -0
- package/templates/database-starter-v2/database-functions/README.md +1 -0
- package/templates/database-starter-v2/gitignore +6 -0
- package/templates/database-starter-v2/mutations/README.md +1 -0
- package/templates/database-starter-v2/package-lock.json +2239 -0
- package/templates/database-starter-v2/package.json +18 -0
- package/templates/database-starter-v2/page/index.html +2 -0
- package/templates/database-starter-v2/page/package.json +25 -0
- package/templates/database-starter-v2/page/src/App.tsx +12 -0
- package/templates/database-starter-v2/page/src/generated/README.md +1 -0
- package/templates/database-starter-v2/page/src/index.css +1 -0
- package/templates/database-starter-v2/page/src/lib/date-time.ts +61 -0
- package/templates/database-starter-v2/page/src/main.tsx +6 -0
- package/templates/database-starter-v2/page/tsconfig.json +19 -0
- package/templates/database-starter-v2/page/vite.config.ts +3 -0
- package/templates/database-starter-v2/prettierignore +3 -0
- package/templates/database-starter-v2/server/functions/README.md +1 -0
- package/templates/database-starter-v2/server/functions/hello/contract.ts +5 -0
- package/templates/database-starter-v2/server/functions/hello/index.ts +7 -0
- package/templates/database-starter-v2/server/functions/hello/meta.json +1 -0
- package/templates/database-starter-v2/server/generated/runtime-profile.ts +5 -0
- package/templates/database-starter-v2/server/package.json +17 -0
- package/templates/database-starter-v2/server/tsconfig.json +14 -0
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Database Function 专项
|
|
2
2
|
|
|
3
|
+
Page 示例按[Function 调用契约](development.md#function-调用契约)分流:本文件的命名对象与 SDK import 示例用于 workspace;无 SDK 的命名 classic 使用自身 helper 导入,位置 classic 使用[位置参数示例](legacy-development.md#位置参数-helper)。外部 Agent 始终按发现 Schema 传命名对象。
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
Database Function 通过固定查询语句读取 Base 数据,定义位于 `database-functions/<functionId>/`。
|
|
4
7
|
|
|
5
8
|
Database Function 只支持本文明确列出的只读查询语法和函数,不从通用关系型数据库的语法或函数推断其能力。
|
|
@@ -109,11 +112,11 @@ Database Function 只支持本文明确列出的只读查询语法和函数,
|
|
|
109
112
|
|
|
110
113
|
## 函数能力描述
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
本节本地校验针对 SQL/Mutation/FaaS,各自 `meta.json` 的顶层填写 `description`。AI 配置校验见 [AI Function](ai-function.md),外部 Agent 的统一发现范围见[站点 Skill](agent-tools.md)。
|
|
113
116
|
|
|
114
|
-
|
|
117
|
+
描述应让外部 Agent 在相邻函数间选对函数:写清用途、何时用、何时不用及此时改用哪个相邻函数,并明确只读、写入或外部调用等副作用,例如「员工查看本人各周期订阅及转账状态;查看全员汇总时改用 listAllSubscriptions(只读)」。写法与示例见[面向 Agent 的函数与参数设计](agent-tool-design.md)。描述要符合真实实现,不能代替权限控制。
|
|
115
118
|
|
|
116
|
-
|
|
119
|
+
函数与参数的硬性校验、描述长度提示及恢复原则统一见[平台检查与提示](agent-tool-design.md#平台检查与提示)。`pull` 保留既有源码;恢复后补齐业务声明,再运行 check。
|
|
117
120
|
|
|
118
121
|
## Function 文件与参数
|
|
119
122
|
|
|
@@ -123,7 +126,7 @@ database-functions/<functionId>/
|
|
|
123
126
|
└── meta.json
|
|
124
127
|
```
|
|
125
128
|
|
|
126
|
-
`main.sql` 只包含一条固定 `SELECT`。`meta.json` 包含非空 `name
|
|
129
|
+
`main.sql` 只包含一条固定 `SELECT`。`meta.json` 包含非空 `name`、推荐提供的函数级 `description`(软提示,见[函数能力描述](#函数能力描述);参数的 `description` 仍为必填)和参数声明。写参数声明前先读[面向 Agent 的函数与参数设计](agent-tool-design.md)。
|
|
127
130
|
|
|
128
131
|
查询使用位置参数 `$1`、`$2`……;`meta.params` 按相同顺序声明:
|
|
129
132
|
|
|
@@ -138,20 +141,26 @@ LIMIT $3
|
|
|
138
141
|
```json
|
|
139
142
|
{
|
|
140
143
|
"name": "搜索任务",
|
|
141
|
-
"description": "
|
|
144
|
+
"description": "成员按关键词和状态搜索任务列表;只看本人任务时改用 listMyTasks(只读)",
|
|
142
145
|
"meta": {
|
|
143
146
|
"params": [
|
|
144
|
-
{ "kind": "TEXT", "description": "
|
|
145
|
-
{ "kind": "TEXT", "description": "
|
|
146
|
-
{ "kind": "INT", "description": "
|
|
147
|
+
{ "name": "keyword", "kind": "TEXT", "description": "任务名称关键词,前后加 % 表示包含匹配,例如 %评审%" },
|
|
148
|
+
{ "name": "status", "kind": "TEXT", "enum": ["待处理", "进行中", "已完成"], "description": "任务状态选项名,按用户明确选择填写" },
|
|
149
|
+
{ "name": "limit", "kind": "INT", "description": "返回条数,1 到 50,默认传 20" }
|
|
147
150
|
]
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
153
|
```
|
|
151
154
|
|
|
152
|
-
`$n
|
|
155
|
+
`$n` 与 `meta.params[n-1]` 必须连续、一一对应。每项包含:
|
|
153
156
|
|
|
154
|
-
|
|
157
|
+
- `name`:按[平台检查与提示](agent-tool-design.md#平台检查与提示)声明唯一参数名。外部 Agent 按名称传 `{"params":{"keyword":…}}`,服务端按声明顺序映射到 `$1`、`$2`……;Page 的对象/位置分支见[Function 调用契约](development.md#function-调用契约)。
|
|
158
|
+
- `kind`:必填,参数类型,见下文。
|
|
159
|
+
- `description`:写业务含义、单位与取值来源;硬性校验与软提示同[平台检查与提示](agent-tool-design.md#平台检查与提示)。
|
|
160
|
+
- `enum`:可选,作者限定的固定选项,非空、不重复、不含 `null`、最多 100 项;值的 JSON 类型与 `kind` 一致(`TEXT` 为字符串,`INT` 为整数,`DOUBLE` 为数字,`BOOL` 为布尔),`TEXT[]` 等数组参数约束每个元素,其他 `kind` 不支持 `enum`。保存时服务端用 Catalog 校验选项值属于绑定字段,动态取值写进 `description`。
|
|
161
|
+
`deploy` 结果的 `functionHints` 出现“绑定选项字段”(`bound to option field`)提示时,判断选项是否由作者限定且固定:固定则依据提示核实选项并写入 `enum`,再重新 `deploy`;会变化则不写 `enum`,在 `description` 写清获取有效值的步骤。提示标记 `truncated` 或域不完整时,先取得并核实作者所需的完整选项,不能把提示中的样本当作全部选项。
|
|
162
|
+
|
|
163
|
+
参数 `kind` 只使用 `TEXT`、`INT`、`DOUBLE`、`BOOL`、`TIMESTAMP`、`INTERVAL`,或为其中任一类型追加一个 `[]` 表示一维数组,例如 `TEXT[]`。命名路由按 `nullable` 声明:省略或 true 时标量、整个数组及元素可为 null,false 时三者均拒绝 null;数值 minimum/maximum 同时保留。旧位置路由保持自身已有兼容语义,不能以位置类型推断命名路由;不支持多维数组,也不接受 `OPTION`、`USER`、`CHAT`、`FILE`、`LOCATION`、`URL`、`AUTONUMBER` 等对象类型。SingleSelect 的动态展示名参数仍声明为 `TEXT`,但 SQL 必须显式写 `(option_field).name = $n`;按 ID 筛选则写 `(option_field).id = $n`。
|
|
155
164
|
|
|
156
165
|
`TIMESTAMP` 参数接受 RFC 3339 字符串、Base 执行时区下的无偏移 `YYYY-MM-DD HH:mm:ss.SSS` 字符串,或 JavaScript safe integer 范围内的 Unix epoch 毫秒整数。无偏移字符串遇到夏令时不存在或重复的当地时间会被拒绝,此时改传带偏移的 RFC 3339 或 epoch 毫秒。`INTERVAL` 参数只接受一个数字和一个单位组成的固定时长字符串。单位支持 `ms`、`millisecond(s)`、`second(s)`、`sec(s)`、`minute(s)`、`min(s)`、`hour(s)`、`day(s)`、`week(s)`,不区分大小写;数字可带符号或小数,但结果必须能无损换算为整数毫秒,例如 `250 ms`、`1.5 seconds`、`2 hours`。不接受复合形式 `1 day 02:03:04`、时钟形式 `02:03:04`,也不支持月、年等日历单位。数组参数的每个非 `null` 元素遵循相同规则。`INT` 必须处于 JavaScript safe integer 范围。CLI 不做类型推断,以 `meta.params[].kind` 为唯一声明。
|
|
157
166
|
|
|
@@ -166,15 +175,25 @@ WHERE f."分组" = ANY($1)
|
|
|
166
175
|
LIMIT 30
|
|
167
176
|
```
|
|
168
177
|
|
|
169
|
-
对应参数声明为 `{"kind":"TEXT[]"}
|
|
178
|
+
对应参数声明为 `{"name":"groups","kind":"TEXT[]","description":"要筛选的跟进分组名称列表;空数组不选中记录"}`,Page 例如调用 `params: { groups: ["重点", "普通"] }`;外部 Agent 按名称传 `{"params":{"groups":["重点","普通"]}}`。本例左侧为 `TEXT`,右侧为一维 `TEXT[]` 位置参数;其他形态按[生成参考](base-sql-errors.generated.md)判定。空数组不会选中记录。数组含 `null` 时不保证 PostgreSQL 三值语义,具体结果与预处理规则见[NULL 与数值边界](database-function-limitations.md#null-与数值边界)。成员判断与数组展开的区别及修法以[生成参考](base-sql-errors.generated.md)为准。
|
|
179
|
+
|
|
180
|
+
6.0 多选按名称筛选使用 `(多选字段).name @> $n`,将 `$n` 声明为 `TEXT[]`。数组作为一个参数传入,例如声明 `{"name":"tags","kind":"TEXT[]","description":"要包含的多选选项名称列表"}`,Page 传 `params: { tags: ["选项名"] }`,不拆成多个标量;空数组不要求任何选项,但仍只匹配多选值非 NULL 的行。整体 NULL 参数或含 NULL 成员的参数数组不匹配任何行。单个非 NULL 名称也可使用 `(多选字段).name @> ARRAY[$n]`,其中 `$n` 声明为 `TEXT`;该写法传 NULL 会被拒绝。
|
|
170
181
|
|
|
171
|
-
|
|
182
|
+
|
|
183
|
+
<!-- example: sql-named-array -->
|
|
184
|
+
```ts
|
|
185
|
+
import { invokeDatabaseFunction } from '@lark-base-open/base-database-app-sdk/page';
|
|
186
|
+
export const loadByTags = () =>
|
|
187
|
+
invokeDatabaseFunction<{ rows: unknown[] }>('listByTags', { tags: ['选项名'] });
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
示例中的 listByTags 必须声明上述 tags 参数;SQL 内将该一维数组映射到单个 `$n`,不是把 Page 请求改成位置数组。
|
|
172
191
|
|
|
173
192
|
上述多选名称筛选仅用于 6.0;2.0 的准入限制及处理方式见[生成参考](base-sql-errors.generated.md),不能由原生多选集合之间的包含比较推断 `.name` 数组具有相同准入。
|
|
174
193
|
|
|
175
194
|
无参数 Function 可以省略 `meta` 或 `meta.params`;归档统一补成 `{"params":[]}`。
|
|
176
195
|
|
|
177
|
-
Database Function
|
|
196
|
+
Database Function 不在 `meta.json` 中手写 `inputSchema`。服务端按 `meta.params` 生成供外部 Agent 使用的命名对象 Schema;CLI 在本地生成与实际调用契约对应的 Page 类型,见[Function 调用契约](development.md#function-调用契约)。SQL 内部 `$n` 的顺序不等于页面请求形态;命名路由传对象,仅旧路由 classic 使用位置数组。FaaS 则必须显式声明,见[FaaS 开发](faas.md#faas-开发)。
|
|
178
197
|
|
|
179
198
|
## 查询约束
|
|
180
199
|
|
|
@@ -192,8 +211,9 @@ Database Function 的 `inputSchema` 由 CLI 根据参数顺序与 kind 生成固
|
|
|
192
211
|
- 集合字段的 PostgreSQL 数组运算符含义为:`@>`(包含)、`<@`(被包含)、`&&`(有交集)。先用 Catalog 的 `sqlType` 区分标量与集合,再按生成参考判断操作是否适用;展开集合前确认业务是否允许改变主表行数。
|
|
193
212
|
- 时间条件使用 Catalog 中确认为 `TIMESTAMP` 的字段和 `TIMESTAMP` 位置参数;当前时间使用 `CURRENT_TIMESTAMP`。查询结果固定为 Base 执行时区下的 `YYYY-MM-DD HH:mm:ss.SSS` 字符串。`EXTRACT(EPOCH FROM timestamp_expr)` 返回保留小数秒的 `DOUBLE`;明确只需整数秒时再写 `::bigint`。
|
|
194
213
|
- 2.0 支持单参 `ROUND(float8)`,半值取偶;numeric 舍入半值远离零。双参 `ROUND` 的首参须可证明为 numeric,精度须为 -15…15 的静态整数;numeric 仍由 DOUBLE 承载,不保证任意十进制精度。
|
|
195
|
-
- 2.0 支持 TEXT 参数的 `CONCAT_WS`:跳过 NULL 值,NULL 分隔符返回 NULL
|
|
196
|
-
-
|
|
214
|
+
- 2.0 支持 TEXT 参数的 `CONCAT_WS`:跳过 NULL 值,NULL 分隔符返回 NULL。
|
|
215
|
+
- 6.0 与 2.0 均不支持 `PERCENTILE_CONT(p) WITHIN GROUP (ORDER BY value)`,正常输入与空输入均在部署校验阶段拒绝。
|
|
216
|
+
- 窗口、聚合、字符串、日期和数值计算先明确结果契约,再查[目录生成的修法与已验证 SQL](base-sql-errors.generated.md)。默认采用满足前提的形式;例外是没有等价 SQL 或改写改变所需语义,此时统一按[SQL 外实现放在哪](database-function-limitations.md#sql-外实现放在哪)选择实现位置。
|
|
197
217
|
|
|
198
218
|
字段类型和成员来自 Catalog,输入按本节参数协议声明;适用的字段操作与修复路径查[生成参考](base-sql-errors.generated.md),而不是从字段名称推断。示例演示参数和结果消费,不作为完整能力清单。
|
|
199
219
|
|
|
@@ -284,20 +304,20 @@ ORDER BY o."订单号" DESC, o.rec_id DESC
|
|
|
284
304
|
LIMIT 20
|
|
285
305
|
```
|
|
286
306
|
|
|
287
|
-
如果没有真实目标表可 JOIN,又需要保留空集合主表行,先核对[生成参考中的语义前提](base-sql-errors.generated.md);没有等价形式时按[SQL 外实现选择原则](
|
|
307
|
+
如果没有真实目标表可 JOIN,又需要保留空集合主表行,先核对[生成参考中的语义前提](base-sql-errors.generated.md);没有等价形式时按[SQL 外实现选择原则](database-function-limitations.md#sql-外实现放在哪)处理。拆分后的输入若在开始时已经确定,应并发调用。
|
|
288
308
|
|
|
289
309
|
搜索、筛选、关联和聚合尽量在查询中完成。没有关系、不同步消费或需要隔离失败语义的结果集可以拆分;拆分后的输入若在开始时已经确定,应并发调用。
|
|
290
310
|
|
|
291
311
|
## 调用与结果
|
|
292
312
|
|
|
293
|
-
|
|
313
|
+
命名路由 Page 与外部 Agent 按冻结名称传对象;FaaS 内部 context 仍按 `meta.params` 顺序传数组。Page 使用 starter 的 runtime client,不传 projectId:
|
|
294
314
|
|
|
295
315
|
```ts
|
|
296
|
-
import { invokeDatabaseFunction } from '
|
|
316
|
+
import { invokeDatabaseFunction } from '@lark-base-open/base-database-app-sdk/page'
|
|
297
317
|
|
|
298
318
|
await invokeDatabaseFunction<{ rows: unknown[] }>(
|
|
299
319
|
'searchTasks',
|
|
300
|
-
|
|
320
|
+
{ keyword: '%评审%', status: '待处理', limit: 20 },
|
|
301
321
|
)
|
|
302
322
|
```
|
|
303
323
|
|
|
@@ -311,10 +331,16 @@ await context.invokeFunction({
|
|
|
311
331
|
})
|
|
312
332
|
```
|
|
313
333
|
|
|
314
|
-
|
|
334
|
+
Page 新入口 HTTP body:
|
|
335
|
+
|
|
336
|
+
```json
|
|
337
|
+
{ "params": { "keyword": "%评审%", "status": "待处理", "limit": 20 } }
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
外部 Agent 调用 `…/functions/searchTasks/invoke` 的 body:
|
|
315
341
|
|
|
316
342
|
```json
|
|
317
|
-
{ "params":
|
|
343
|
+
{ "params": { "keyword": "%评审%", "status": "待处理", "limit": 20 } }
|
|
318
344
|
```
|
|
319
345
|
|
|
320
346
|
返回是 ResultJSON,不是 rows 数组:
|
|
@@ -344,3 +370,5 @@ await context.invokeFunction({
|
|
|
344
370
|
## 校验
|
|
345
371
|
|
|
346
372
|
`base-database-cli deploy` 统一调用服务端查询校验。编译成功仅证明编译阶段;实际读取按[发布与交付](release.md)或用户要求的[专项验收](verification.md)执行。失败时保留具体错误节点和 LogID,按 Catalog、参数与支持边界修复,不猜测响应 envelope 绕过。
|
|
373
|
+
|
|
374
|
+
workspace 或已安装 SDK 的工程,`contracts generate` 使用工程内 SDK `/codegen`。CLI 提取契约并隔离执行生成器;check 只比较生成内容,过期时先重新运行 `contracts generate`。`SDK_CODEGEN_UNAVAILABLE` 表示需要安装包含 codegen 的 SDK,按 CLI 报错给出的安装命令执行(版本与新建工程模板一致),不能通过跳过生成或回退 CLI 模板修复。未安装 SDK 的 classic 工程保留旧输入类型生成行为。
|
|
@@ -1,7 +1,35 @@
|
|
|
1
1
|
# Page 开发与 Function 调用
|
|
2
2
|
|
|
3
|
+
先按[Function 调用契约](#function-调用契约)核对实际调用路由与参数形态,再选择示例。SDK 是否安装只决定 API 文档与导入来源,不决定位置数组或命名对象;未安装 SDK 时保留用户现有依赖与 helper,不为消除分支而安装 SDK 或覆盖 helper。新建仅用 workspace。
|
|
4
|
+
|
|
3
5
|
实现或修改 Page 的运行时接入时读取。FaaS 新增或修改时,还须在 meta.json 显式声明 inputSchema,见[FaaS 开发](faas.md#faas-开发)。基础单表写入与批量调用见[Mutation Function](mutations.md)。查询语法见[Database Function](database-function.md),服务端 handler 与记录写入见[FaaS 协议](faas.md),设计原则见[工程质量](style-guide.md)。
|
|
4
6
|
|
|
7
|
+
## 工程内平台指引
|
|
8
|
+
|
|
9
|
+
开发前读取工程根目录 AGENTS.md 的 base-app 托管段落;它记录当前模板、实际安装的 SDK 版本与包内 docs 路径。SDK 工程按该版本包内文档实现 API;未安装 SDK 的 classic 按[调用契约](#function-调用契约)选择相应 helper 示例;已安装 SDK 但缺少文档时先核对包内容,不据此改用位置参数。CLI 在 init、check、deploy、dev 时维护该段落,不自动升级依赖。
|
|
10
|
+
|
|
11
|
+
## 本地开发入口
|
|
12
|
+
|
|
13
|
+
`dev [directory]` 默认使用当前目录,指定工程目录时写作 `base-database-cli dev ./app`;`--json` 流式输出,每行一个 JSON 事件。
|
|
14
|
+
|
|
15
|
+
执行 `base-database-cli dev` 前,工程必须安装 `@lark-base-open/base-database-app-sdk`,且 `page/index.html` 指向的页面入口必须静态导入并调用 SDK 的 `startBaseApp(options)`;workspace 标准入口符合此要求。classic 旧工程按[workspace 迁移](workspace-migration.md)迁移,或按[手动迁移页面 helper](#手动迁移页面-helper)处理调用,再按[dev 页面 bootstrap](#dev-页面-bootstrap)处理入口接入 SDK。CLI 在启动 Vite、选择端口或生成浏览器链接前检查入口;缺 SDK 返回 `DEV_SDK_MISSING`,入口未启动 SDK 或无法静态判定时返回 `DEV_SDK_NOT_BOOTSTRAPPED` 并给出迁移/最小入口示例。确认要绕过静态检查时可显式使用 `--skip-bootstrap-check`;这不会跳过 SDK 安装检查。
|
|
16
|
+
|
|
17
|
+
检查通过后,用 CLI 输出的完整链接打开;复制地址栏链接给别人会自动打开线上版本。若弹出或地址栏出现访问本地网络/本机设备请求,请允许后点重试。配对通过后无需手动确认,核对常驻“本地调试中”提示条中的身份、preview 环境与写入范围。CLI 只启动本机 Vite 和监听构建,不创建、续租或关闭服务端开发会话。默认从 Catalog 的 baseAppUrl 生成 `/baseapp/dev/<siteToken>/<port>#t=<配对令牌>` 入口;需要切换宿主域名时使用 `--host-origin <实际宿主HTTPS origin>`。
|
|
18
|
+
|
|
19
|
+
宿主路径中的 `home`、`new`、`static`、`dev` 为保留段,不能作为应用 token;旧 `/baseapp/<siteToken>/dev/<port>` 不再兼容。
|
|
20
|
+
|
|
21
|
+
本地服务仅监听 `127.0.0.1:43100–43109`,可用 `--port` 指定白名单端口;被占用时失败。远端 Agent 需要把该端口转发到用户浏览器所在机器。`dev.listening` 只表示监听成功;`dev.ready` 表示 SDK lifecycle 完成且 `localOrigin` 匹配的观察,不替代真实宿主身份和业务验收。开发入口未开放或配对未完成时,不把本地首页 HTTP 200 当作联调通过。
|
|
22
|
+
|
|
23
|
+
收到 `dev.host_not_connected` 时,向用户说明宿主尚未加载本地开发服务器,本地修改还未在宿主中生效;按事件提示打开 CLI 输出的链接并允许浏览器本地网络访问后重试。若页面直接显示已发布应用,说明当前域名暂不支持本地开发,改用 `base-database-cli deploy` 发布 Preview 验证。该提示只出现一次,dev 继续运行,稍后连接仍会发出 `dev.ready`。等待阈值默认 120 秒,可用 `BASE_DATABASE_DEV_HOST_TIMEOUT_MS` 调整(正整数毫秒)。
|
|
24
|
+
|
|
25
|
+
FaaS 变化默认只本地构建;仅在用户已授权修改共享 Preview 时添加 `--deploy-preview`,它启动时及后续 FaaS 变化后发布完整应用 Preview。SQL/Mutation/绑定/依赖变化暂停自动发布,需单独检查并显式 deploy 后重启 dev。发布结果未知时保留回执并停止自动写入,已知 publishId 用 `deployments status <publishId> --wait` 只读核对,禁止盲目重发。退出会清理 Vite、监听、构建进程与本地锁。
|
|
26
|
+
|
|
27
|
+
配对令牌保存在项目 `.base-database-cli/state/dev-pairing-token`(权限 600),dev 重启保持不变;`dev --reset-pairing` 重新生成后须用新的 CLI 链接打开。令牌仅通过环境变量传给 Vite 子进程;`--json` 的地址已打码,完整地址只在人类可读输出显示。state 目录已由模板 gitignore 和上传打包规则排除。旧 SDK 不支持配对时须先升级工程 SDK。
|
|
28
|
+
|
|
29
|
+
## 老模板参考
|
|
30
|
+
|
|
31
|
+
classic 保留自有 helper 时,先按[Function 调用契约](#function-调用契约)选择[存量 helper 示例](legacy-development.md),不按 SDK 是否安装推断参数形态。已安装 SDK 但缺少文档时先核对包内容。
|
|
32
|
+
|
|
5
33
|
## 工程结构
|
|
6
34
|
|
|
7
35
|
```text
|
|
@@ -9,10 +37,10 @@ project/
|
|
|
9
37
|
├── page/
|
|
10
38
|
├── database-functions/<functionId>/{main.sql,meta.json}
|
|
11
39
|
├── mutations/<functionId>/{spec.json,meta.json}
|
|
12
|
-
└── server
|
|
40
|
+
└── server/functions/<functionId>/{index.ts,meta.json}
|
|
13
41
|
```
|
|
14
42
|
|
|
15
|
-
Database Function、Mutation 与 FaaS 的 `functionId` 在应用内全局唯一,匹配 `/^[A-Za-z0-9_-]+$/`;Database Function ID 长度为 1~64。`functionId` 会作为 URL 路径段参与运行态调用,除该字符集外不接受其它字符。不同 FaaS Function 目录独立构建,不跨目录 import。Page 和 `server-functions/`
|
|
43
|
+
Database Function、Mutation 与 FaaS 的 `functionId` 在应用内全局唯一,匹配 `/^[A-Za-z0-9_-]+$/`;Database Function ID 长度为 1~64。`functionId` 会作为 URL 路径段参与运行态调用,除该字符集外不接受其它字符。不同 FaaS Function 目录独立构建,不跨目录 import。classic 的 Page 和 `server-functions/` 分别维护 npm 工程与锁;新建 `init` 使用根 workspace(page + server),唯一根 package-lock.json;SDK 使用已发布版本,新建仅用 workspace。
|
|
16
44
|
|
|
17
45
|
## 第三方依赖策略
|
|
18
46
|
|
|
@@ -42,101 +70,17 @@ base-database-cli lark-cli -- api GET /open-apis/base/v3/sites/<app-token>/get -
|
|
|
42
70
|
|
|
43
71
|
## Function 调用契约
|
|
44
72
|
|
|
45
|
-
|
|
73
|
+
Function ID 为源码目录名且在应用内唯一。输入协议与工程配置的判定统一见[输入声明](workspace-migration.md#classic-输入声明),CLI 不推断用户 helper。确认分支后,workspace 使用 SDK 示例;classic 分别读取[命名对象 helper](legacy-development.md#命名对象-helper)或[位置参数 helper](legacy-development.md#位置参数-helper)。参数名来自冻结的 meta.params / spec.params / inputSchema,不从 SQL 文本猜测。
|
|
46
74
|
|
|
47
|
-
`
|
|
75
|
+
`contracts generate` 统一生成 `function-clients` 与 Function 输入类型映射:SQL 的参数名称、可选性与 `parameterOptions` enum、Mutation 声明,以及 FaaS Standard Schema 同次生成。workspace `defineFunction` 的 `meta.inputSchema` 直接用于 Agent 开放 schema;已有手写 `meta.json` `inputSchema` 工程继续兼容。生成类型只约束输入,运行时仍负责校验,不能凭 TypeScript 类型假定远端结果;Database Function 输出保持 unknown。
|
|
48
76
|
|
|
49
|
-
|
|
50
|
-
| ---------------------- | ------------------------------------------ | ------------------------ | ------------------------------------------------------------------------------------ |
|
|
51
|
-
| Database Function | 按 `$1`、`$2` 排列的数组 | `main.sql` + `meta.json` | 一层 `{data:{rows},code,msg}` |
|
|
52
|
-
| Mutation | 声明顺序的位置数组;多组参数用批量 helper | `spec.json` + `meta.json` | 一层 `{data:{record_ids,records?,record_not_found?,ignored_fields?},code,msg}` |
|
|
53
|
-
| FaaS | 业务对象 | `index.ts` + `meta.json` | 一层 `{data,code,msg}`,`data` 是 handler 业务数据 |
|
|
54
|
-
|
|
55
|
-
Database Function 查询示例:
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
await invokeDatabaseFunction<{ rows: unknown[] }>('listTasks', ['待处理']);
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Mutation 一组参数使用 `invokeDatabaseFunction(functionId, params)`,每组操作一条记录;多组参数使用 `invokeDatabaseMutationBatch(functionId, parameterGroups)`,包装成 `{batch:[{params:[...]}]}`,不能与顶层 params 混用。两个 helper 均从 `page/src/lib/database-runtime.ts` 导出。`code=0` 仍须检查 `data.record_not_found/ignored_fields`,见[调用与结果](mutations.md#调用与结果)。
|
|
62
|
-
|
|
63
|
-
FaaS 创建操作示例:
|
|
64
|
-
|
|
65
|
-
```ts
|
|
66
|
-
await invokeDatabaseFunction<{ created: boolean | null }>('createTask', {
|
|
67
|
-
title: '准备评审',
|
|
68
|
-
status: '待处理',
|
|
69
|
-
});
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
`base-database-cli check --json` 与 Preview `deploy` 会先校验本地 Function metadata,再把 Database Function 的
|
|
73
|
-
`meta.params` 和 FaaS `inputSchema` 生成到
|
|
74
|
-
`page/src/lib/database-function-inputs.generated.ts`,随后才编译 Page。不要手改该文件;新增或修改
|
|
75
|
-
Function 后运行 `check`,让 `functionId`、查询参数顺序以及 FaaS 必填字段和枚举值在 Page
|
|
76
|
-
编译时保持一致。动态字符串不能作为 `functionId` 绕过这份本地契约。
|
|
77
|
-
|
|
78
|
-
metadata 只声明输入,因此生成文件只约束调用参数。调用结果仍由 Page 按 operation 定义
|
|
79
|
-
`invokeDatabaseFunction<TData>` 的 `TData`,并在运行时校验真实响应;CLI 不根据 handler
|
|
80
|
-
实现或查询投影猜测返回类型。生成类型覆盖标量类型、对象属性、必填项、枚举、数组元素和
|
|
81
|
-
`prefixItems` 位置,以及 Database Function 的固定参数 tuple;`minimum`、`maximum`、`minLength`、
|
|
82
|
-
`maxLength`、非固定数组的 `minItems` / `maxItems` 和对象精确性仍由 Function 运行时校验;
|
|
83
|
-
数组的元素类型和 `prefixItems` 位置仍保留在生成类型中。TypeScript 类型不能替代输入解析。
|
|
84
|
-
|
|
85
|
-
`invokeDatabaseFunction` 调用统一网关的 `POST /space/api/bitable/site/v1/:token/invoke_function/:function_id`,由 BaseApp 父页面以同源身份代发;应用 token 与环境由 `src/lib/database-runtime.ts` 统一解析,`env` 走 query,请求体固定为 `{"params": <上述 params>}`。返回统一包裹结构 `{code,msg,data}`,页面使用当前登录用户身份,不保存也不传递任何凭证。
|
|
77
|
+
Function 成功返回一层 `{code,msg,data}`。SQL data 为 ResultJSON;Mutation data 含 record_ids 及可选 records、record_not_found、ignored_fields;FaaS data 为业务结果。成功码不代表批量全部成功,见[调用与结果](mutations.md#调用与结果)。页面运行时 SDK 用法仅在工程已安装 SDK 时读取 SDK 包内文档;本 Skill 不复制 SDK API 说明。
|
|
86
78
|
|
|
87
79
|
## Page 调用
|
|
88
80
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
默认 Page 的 `page/index.html` 需要把 `<title>` 设置为本次生成的应用名称,不留空。
|
|
92
|
-
|
|
93
|
-
默认 Page 必须引用并渲染 `page/src/components/floating-button/index.tsx` 中的 `FloatingButton` 组件。该组件自行解析应用 token,不接受 `projectId`。悬浮控件仅在正式环境向服务端判定有管理权限的访问者提供「编辑应用」入口。
|
|
94
|
-
|
|
95
|
-
当前账号信息(头像、姓名、组织、退出登录)由**应用自己的导航**承载,用 `page/src/components/database-user-menu/index.tsx` 的 `DatabaseUserMenu`。账号菜单位于应用导航区域,例如顶栏右上角或侧边栏底部:
|
|
96
|
-
|
|
97
|
-
```tsx
|
|
98
|
-
// 顶栏右上角
|
|
99
|
-
<header className="flex items-center justify-between ...">
|
|
100
|
-
<h1>设备台账</h1>
|
|
101
|
-
{/* 判据:员工 / 部门 / 领用归还属于组织内多角色协作 */}
|
|
102
|
-
<DatabaseUserMenu audience="enterprise" />
|
|
103
|
-
</header>
|
|
104
|
-
|
|
105
|
-
// 侧边栏左下角
|
|
106
|
-
<aside className="flex flex-col ...">
|
|
107
|
-
<nav className="flex-1">…</nav>
|
|
108
|
-
<DatabaseUserMenu audience="enterprise" align="left" side="up" />
|
|
109
|
-
</aside>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
`align` 控制弹层贴左还是贴右,`side` 控制向上还是向下展开,`showName={false}` 用于窄侧栏只留头像。
|
|
113
|
-
|
|
114
|
-
`audience` 控制是否展示账号信息:多人协作或对外共享的系统使用 `enterprise`;仅本人使用的系统可用 `personal`(不渲染菜单)。根据实际使用者与协作方式判断,不因出现“客户”“供应商”等实体名就认定为多人系统。无法确定时默认 enterprise,保留账号与退出入口;仅受众存在实质歧义时才询问。修改已有页面沿用原策略,除非本次需求改变受众。
|
|
115
|
-
|
|
116
|
-
`page/src/main.tsx` 已在首屏挂载后通过 `DatabaseRuntimeReady` 上报 `siteRuntime.ready()`,并在启动失败时上报 `reportLoadFailed`。宿主从握手完成起 10 秒内等不到 ready 会展示加载失败态,因此不要把 ready 上报移到数据加载完成之后,也不要删除该组件。
|
|
117
|
-
|
|
118
|
-
涉及人员搜索或人员选择的页面,优先引用 `page/src/components/UserSelectorEditor` 和 `page/src/components/UserSelectorPanel` 等 `page/src/components/` 下的人员组件;只有现有组件无法满足交互契约时才做局部扩展。
|
|
119
|
-
这些一方组件以及 `DatabaseUserMenu`、`FloatingButton`、`PageState`、`AttachmentImage` 内置中文、英文、日文固定文案,不依赖 Starling。组件统一按宿主 Runtime Context 的 locale → 浏览器语言 → 英语选择文案,无需 Page 传入或写死语言;宿主切换语言后,组件随重新加载的页面重新解析。Page 自己编写的业务文案仍由应用负责。
|
|
120
|
-
选人组件返回的 `User.user_id` 是 Base 人员单元格使用的内部用户 ID。Mutation 的 `USER_ID` 参数传该 ID 字符串,`list:true` 时传 ID 数组;FaaS 下游人员单元格传 `[{"id": user.user_id}]`。`User.open_id` 只是可选的开放平台标识,不得填入应用记录写入 payload。
|
|
121
|
-
|
|
122
|
-
业务请求集中在 operation/runtime client,不散落在组件中:
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
import { invokeDatabaseFunction } from '../lib/database-runtime';
|
|
81
|
+
页面运行时 API 用法请读取工程 `node_modules/@lark-base-open/base-database-app-sdk/docs/README.md` 索引及其 `page.md`、`compat.md`、`start-base-app.md`、`components.md`(旧双工程安装位于 `page/node_modules`),业务建模与交付流程回到本 Skill。
|
|
126
82
|
|
|
127
|
-
|
|
128
|
-
rows: TRow[];
|
|
129
|
-
columns?: unknown[];
|
|
130
|
-
row_count?: number;
|
|
131
|
-
log_id?: string;
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
浏览器 SDK 对 Database Function、Mutation 和 FaaS 都只返回一层 `{data,code,msg}`。`invokeDatabaseFunction<TData>` 的 `TData` 只描述当前 operation 约定的顶层 `data`:Database Function 通常是 ResultJSON,FaaS 则以各 handler 的业务结果为准,不能统一假设存在 `recordId`。页面只检查一次顶层 `code`,再按 operation 契约校验 `data`;不得写成 `invokeDatabaseFunction<FaasHandlerResult<TData>>`,也不得对 `result.data` 二次解包。否则后端已经写入成功时,页面仍可能误报失败。
|
|
136
|
-
|
|
137
|
-
运行时业务数据在边界处校验,不能只依赖 TypeScript 泛型。`functionId` 和所有路由是工程常量;用户输入只进入已声明的业务参数。
|
|
138
|
-
|
|
139
|
-
Page 的所有业务 HTTP 都经父页面代理,使用 `page/src/lib/database-runtime.ts` 导出的 `fetch` 或 `invokeHttp`,URL 必须是以单个 `/` 开头的同源相对路径;绝对 URL、跨域 URL、路径穿越以及 Cookie、Authorization、Host、Origin 等受限 Header 都会被父页面拒绝。请求体只支持字符串,4xx/5xx 会正常返回 `Response`,业务必须自行判断 `response.ok`。禁止直连业务域名,也不得把直连作为代理失败时的兜底。Page 发起的 Base 业务读取和写入分别走 Database Function 与 Mutation/FaaS。
|
|
83
|
+
默认 Page 的 page/index.html 标题填写应用名称;受众默认 enterprise,仅个人系统选择 personal。人员写入使用内部 user_id,不将 open_id 填入记录 payload。
|
|
140
84
|
|
|
141
85
|
## 日期与时区
|
|
142
86
|
|
|
@@ -153,16 +97,17 @@ Database Function 返回类型与 FaaS 写入格式分别以 [查询类型](data
|
|
|
153
97
|
|
|
154
98
|
### 转换与编辑示例
|
|
155
99
|
|
|
156
|
-
|
|
100
|
+
新建 workspace 随 Page 提供 `page/src/lib/date-time.ts`,其中包含不依赖浏览器或 SDK 的纯函数:
|
|
157
101
|
|
|
158
102
|
- `formatDateInput(epochMs, timeZone)`:时间戳到该业务时区的 `YYYY-MM-DD`。
|
|
159
103
|
- `formatBaseDateTime(epochMs, timeZone)`:时间戳到该时区的 `YYYY-MM-DD HH:mm:ss`。
|
|
160
104
|
- `dateInputToBaseDateTime(value)`:校验日历日期并补 `00:00:00`,不先转成 UTC。
|
|
161
105
|
|
|
162
|
-
|
|
106
|
+
工程缺少该文件时,从当前 CLI 包内 `templates/database-starter-v2/page/src/lib/date-time.ts` 复制到 `page/src/lib/date-time.ts`(先确认目标不存在,不覆盖定制实现)。这是 CLI 分发的无依赖源码,不是 SDK 导出。FaaS 需要使用时,将该无依赖文件复制到目标 `server/functions/<functionId>/`,在同一 Function 内导入;不要跨 Function 或从 Page 目录运行时导入。
|
|
163
107
|
|
|
164
108
|
以下 `BASE_TIME_ZONE` 是应用根据 Base 信息确定的常量,示例值不是默认值。不要让任意请求参数改变写入解释时区。
|
|
165
109
|
|
|
110
|
+
<!-- example: workspace-date -->
|
|
166
111
|
```ts
|
|
167
112
|
// Page:时间戳只在回填边界转换,用户输入仍保持日历日期。
|
|
168
113
|
import { formatDateInput } from './lib/date-time';
|
|
@@ -219,23 +164,18 @@ export function eventFields(now: number) {
|
|
|
219
164
|
|
|
220
165
|
## AI 对话与调用
|
|
221
166
|
|
|
222
|
-
AI
|
|
223
|
-
|
|
224
|
-
能力归属按运行场景判断:面向当前页面业务流程的生成、分类、总结和推荐使用 AI Function;Base 查询与写入仍分别使用 Database Function 和 FaaS。
|
|
225
|
-
|
|
226
|
-
Page 需要 AI 对话、生成、分类、总结、文生图或文生视频时,默认按 `functionKey` 使用 `page/src/lib/database-runtime.ts` 导出的 `callSiteAIFunction` / `invokeSiteAIFunctionStream`,不创建 FaaS 模型代理,也不直连模型域名。AI 能力被收口成一类版本化托管的 AI Function 配置;四类能力配置契约、CLI 建模/调试、计费与单流约束见 [AI Function](ai-function.md)。starter 的 `page/src/examples/ai-function/TextStreamOperation.tsx` 提供最小组件示例。搭建时可复用这些示例的界面及 `ai-copy.ts`,保留 `useUiLanguage()` 接入;内置标题、提示、按钮、任务状态和本地兜底错误自动跟随宿主 locale → 浏览器语言 → 英语。Page 显式传入的 `title` 由 Page 自行处理,服务端错误与 AI 生成内容保留原文。
|
|
227
|
-
|
|
228
|
-
AI 与 Base 数据组合时保持既有边界:先用 Database Function 读取,再由 Page 裁剪必要数据并拼入 `messages` 或 `variables`;需要把结果写回 Base 时另行调用 FaaS。AI 调用本身不经过 FaaS。
|
|
167
|
+
AI 调用按 [AI Function](ai-function.md) 实现,不创建 FaaS 模型代理,也不直连模型域名。
|
|
168
|
+
workspace 的 AI 调用按已安装 SDK 的 docs/README.md 索引定位 API 与示例,不假定工程存在 classic 示例文件;classic 示例路径与语言接入见[存量 Page 参考](legacy-development.md#classic-ai-示例)。
|
|
229
169
|
|
|
230
170
|
## 开发期与运行态输出
|
|
231
171
|
|
|
232
|
-
| 调用层
|
|
233
|
-
|
|
|
234
|
-
| lark-cli 默认 JSON 输出
|
|
235
|
-
| Page
|
|
236
|
-
| Database Function
|
|
237
|
-
| FaaS handler
|
|
238
|
-
| FaaS 下游记录写入
|
|
172
|
+
| 调用层 | 判定方式 |
|
|
173
|
+
| ----------------------- | -------------------------------------------------------------------------------- |
|
|
174
|
+
| lark-cli 默认 JSON 输出 | 先检查进程退出与外层 `ok`,再按该命令的 `data` 契约取值;错误诊断见 `error` |
|
|
175
|
+
| Page | 参阅已安装 SDK 的 docs/compat.md 与 docs/page.md |
|
|
176
|
+
| Database Function | `data` 为 ResultJSON,包含 rows 等查询信息 |
|
|
177
|
+
| FaaS handler | 返回 `{data,code,msg}`,data 为业务结果,不再由 Page 二次解包 |
|
|
178
|
+
| FaaS 下游记录写入 | 检查下游 envelope 和各 batch 的结果语义,见[FaaS 协议](faas.md#应用记录写入协议) |
|
|
239
179
|
|
|
240
180
|
不要把 SDK 的 `code===0` 套在 CLI 外层,也不要将 CLI 外层的 data 当作 handler 业务数据。raw API 的命令封装与业务响应按当前 lark-cli reference 分别解析。
|
|
241
181
|
|
|
@@ -243,8 +183,40 @@ AI 与 Base 数据组合时保持既有边界:先用 Database Function 读取
|
|
|
243
183
|
|
|
244
184
|
实现前确定 operation 固定输入输出,按[工程质量](style-guide.md)检查远程调用依赖。新建示例数据在[发布阶段](release.md#从零建站示例数据验收)通过 CLI 写入真实 Base;不创建仅用于播种的 FaaS,也不在 Page 加载时自动写入。
|
|
245
185
|
|
|
246
|
-
Page 的读取与写入分别通过 Database Function 与 Mutation/FaaS,自动化使用[原生能力](base-capability-routing.md)
|
|
186
|
+
Page 的读取与写入分别通过 Database Function 与 Mutation/FaaS,自动化使用[原生能力](base-capability-routing.md),不从页面模拟后台定时任务。附件 API 来源、写入选型、上传、展示与重试边界统一见[文件传输](file-transfer.md),按 SDK/classic 分流。不能以 mock、未约定网关或旧列表整格覆盖代替。
|
|
247
187
|
|
|
248
|
-
|
|
188
|
+
业务请求的身份与 CSRF 处理由宿主负责;单独 403 不等于 CSRF,Page 不读宿主 Cookie、不手写 CSRF Header。
|
|
249
189
|
|
|
250
190
|
实现完成后按[发布与交付](release.md)继续;用户明确要求运行态检查时按[诊断与验收](verification.md)执行。
|
|
191
|
+
|
|
192
|
+
### SDK 与契约准备
|
|
193
|
+
|
|
194
|
+
使用 dev 前,工程需安装支持配对的 SDK。缺失时按 CLI 报错给出的安装命令执行,版本与新建工程模板一致;未发布 tarball 只用于指定验证工程。
|
|
195
|
+
|
|
196
|
+
classic/workspace 的 defineFunction 均由 CLI 在构建时生成 bindFunctionRuntime,ctx.records 可用。服务端构建模式按[工程目录与构建模式](workspace.md#工程目录与构建模式)选择,不能仅凭 Page 安装 SDK 判断。修改 server-functions/、server/ 或契约后先运行 `base-database-cli contracts generate`,再 `base-database-cli check --json`。
|
|
197
|
+
|
|
198
|
+
页面 HMR 与隐藏/显示不重新配对;切回聚焦复查权限,另有30秒轮询。冷启动握手超时保留 iframe,可等待或重试。权限查询临时失败保留标签内令牌并撤销业务能力,不当作非编辑者跳转。dev watch 忽略自动生成契约及 meta.json 的契约字段,保留用户元数据的变化检测。
|
|
199
|
+
|
|
200
|
+
### Function 参数与生成模块
|
|
201
|
+
|
|
202
|
+
参数形态统一按[Function 调用契约](#function-调用契约)判定;命名对象分支的批量 Mutation 使用命名对象数组。迁移调用方时,本地 metadata 不能证明服务端冻结声明,须人工核对参数名、别名与转导出,不能直接把数组送到统一路由。
|
|
203
|
+
|
|
204
|
+
workspace 的输入类型与 `DatabaseFunctionParameterOptions` 统一生成在 `page/src/generated/function-inputs.ts`,页面可从 `./generated/function-inputs` 导入枚举运行时值;classic helper 保持 `page/src/lib/database-function-inputs.generated.ts`;classic 若生成 SDK clients,另在 `page/src/generated/function-inputs.ts` 保存 SDK 命名输入,不能拿旧 helper 的 tuple 作为 SDK 输入。不要将包含枚举常量的模块改成 `.d.ts`。
|
|
205
|
+
|
|
206
|
+
## 工程迁移与 SDK 升级
|
|
207
|
+
|
|
208
|
+
工程结构和 helper 改动由 coding agent 按[工程迁移指南](workspace-migration.md)执行并验证;CLI 不自动改写。SDK 升级需在用户授权范围内核对依赖及调用方。
|
|
209
|
+
|
|
210
|
+
### 手动迁移页面 helper
|
|
211
|
+
|
|
212
|
+
操作步骤与改前/改后示例统一见[逐步迁移](workspace-migration.md#逐步迁移)。保留自定义业务逻辑,未经核对不覆盖 helper。
|
|
213
|
+
|
|
214
|
+
## 本地检查与契约生成
|
|
215
|
+
|
|
216
|
+
`check` 先按需安装依赖,再核对 Function 契约,最后构建 Page/FaaS。workspace 或 SDK 工程的契约发生变化时会报告 `CONTRACT_STALE`;先在项目根显式执行 `base-database-cli contracts generate`,再运行 `base-database-cli check --json`,不要反复 check 或手改生成物。
|
|
217
|
+
|
|
218
|
+
只有无 App SDK 的 classic 使用本地 metadata 自动更新输入类型。生成形态仍按[Function 调用契约](#function-调用契约)选择;check 的自动生成不改变 helper 路由。`--no-install` 要求依赖已经就绪,不能绕过契约核对。
|
|
219
|
+
|
|
220
|
+
## dev 页面 bootstrap
|
|
221
|
+
|
|
222
|
+
手动迁移 helper 只改变 Function 入口,不建立 dev bootstrap。要使用 dev,先读取工程已安装 SDK 的 docs/start-base-app.md:创建 base-app.config.ts,在真实 Page 入口导入该配置并调用 startBaseApp,把原有业务根组件交给 app 选项、原有 Provider 包裹交给 providers 选项;移除入口原来的 createRoot/render,避免重复挂载。处理返回对象的 ready 拒绝,在 HMR/卸载时 dispose,保留业务初始化顺序,不再手动重复通知 ready。运行 contracts generate 和 check 后再启动 dev。现有页面结构无法直接套用时按 SDK 文档改造入口,不能用 --skip-bootstrap-check 代替修复。
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
## 运行配置与边界
|
|
12
12
|
|
|
13
|
-
环境变量是 Base Database FaaS 的运行配置,不是应用的业务数据或页面功能。值只注入发布后的 FaaS runtime,不注入 Agent 进程、Page 或构建阶段的环境。FaaS 仅用静态 `process.env.NAME` 或 `process.env['NAME']` 读取;CLI 按语法扫描
|
|
13
|
+
环境变量是 Base Database FaaS 的运行配置,不是应用的业务数据或页面功能。值只注入发布后的 FaaS runtime,不注入 Agent 进程、Page 或构建阶段的环境。FaaS 仅用静态 `process.env.NAME` 或 `process.env['NAME']` 读取;CLI 按语法扫描 FaaS 源码目录(见[工程目录](workspace.md#工程目录与构建模式)),忽略注释和字符串示例,动态下标、解构或无法静态确定名称的访问会阻止发布。
|
|
14
14
|
|
|
15
15
|
- `config`:非敏感配置,查询时明文返回。
|
|
16
16
|
- `secret`:API Key、Token 等敏感值,保存后只返回脱敏值。
|
|
@@ -34,7 +34,7 @@ Page 不得实现环境变量管理页、配置清单、变量调试页,或展
|
|
|
34
34
|
|
|
35
35
|
## CLI 写入与核对
|
|
36
36
|
|
|
37
|
-
沿用已核实的本机 `base-database-cli`,无可用入口时按[工程与环境](workspace.md
|
|
37
|
+
沿用已核实的本机 `base-database-cli`,无可用入口时按[工程与环境](workspace.md#环境与依赖)定位当前分发环境的 CLI 入口;仅替换命令前缀,实际业务参数保持一致:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
base-database-cli environment-variables declare MAP_API_KEY \
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# FaaS 与记录协议
|
|
2
2
|
|
|
3
|
+
本文件中基于 `defineFunction`、`ctx.records` 的 SDK 示例只供已安装 SDK 的工程使用;未安装时沿用现有 FaaS handler 与 CLI 流程,不为读取本节而迁移依赖。
|
|
4
|
+
|
|
3
5
|
实现、维护或排查 FaaS 时读取;新写入的选型见[写入方式选择](mutations.md#写入方式选择)。Page 调用方式见[Page 开发](development.md),查询类型与参数见[Database Function](database-function.md),权限判定见[权限设计](permission-design.md)。
|
|
4
6
|
|
|
5
7
|
## 阅读路径
|
|
@@ -19,8 +21,10 @@
|
|
|
19
21
|
|
|
20
22
|
每个 FaaS 业务动作的目录:
|
|
21
23
|
|
|
24
|
+
workspace 默认目录如下,classic 路径按[工程目录与构建模式](workspace.md#工程目录与构建模式)替换。
|
|
25
|
+
|
|
22
26
|
```text
|
|
23
|
-
server
|
|
27
|
+
server/functions/<functionId>/
|
|
24
28
|
├── index.ts
|
|
25
29
|
└── meta.json
|
|
26
30
|
```
|
|
@@ -28,13 +32,13 @@ server-functions/functions/<functionId>/
|
|
|
28
32
|
```json
|
|
29
33
|
{
|
|
30
34
|
"name": "创建任务",
|
|
31
|
-
"description": "
|
|
35
|
+
"description": "成员创建任务时校验输入并写入一条任务记录;只改已有任务的标题时改用 renameTask",
|
|
32
36
|
"inputSchema": {
|
|
33
37
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
34
38
|
"type": "object",
|
|
35
39
|
"properties": {
|
|
36
|
-
"title": { "type": "string", "minLength": 1 },
|
|
37
|
-
"status": { "type": "string", "enum": ["待处理", "进行中", "已完成"] }
|
|
40
|
+
"title": { "type": "string", "minLength": 1, "description": "新任务的标题,去除首尾空白后不能为空" },
|
|
41
|
+
"status": { "type": "string", "enum": ["待处理", "进行中", "已完成"], "description": "新任务的初始状态,按用户明确选择填写" }
|
|
38
42
|
},
|
|
39
43
|
"required": ["title", "status"],
|
|
40
44
|
"additionalProperties": false
|
|
@@ -42,9 +46,9 @@ server-functions/functions/<functionId>/
|
|
|
42
46
|
}
|
|
43
47
|
```
|
|
44
48
|
|
|
45
|
-
`inputSchema` 是调用该 Function 时 `params` 业务值的结构,不包含外层 `{"params": ...}`;FaaS Function
|
|
49
|
+
`inputSchema` 是调用该 Function 时 `params` 业务值的结构,不包含外层 `{"params": ...}`;FaaS Function 必须显式声明,顶层必须是 `"type": "object"`,每个顶层属性(属性名即参数名)必须有非空白的 `description`,写法见[面向 Agent 的函数与参数设计](agent-tool-design.md)。CLI 会校验并上传该 Schema。只使用 JSON Schema 2020-12 的受限子集:`type`、`description`、`properties`、`required`、`additionalProperties`、`items`、`prefixItems`、`minItems`、`maxItems`、`enum`、`minimum`、`maximum`、`minLength`、`maxLength`、`oneOf`、`anyOf`、`pattern`、`default`;`pattern` 须为 RE2 可接受的正则;不使用 `$ref`、`allOf`、`if`/`then`、`format` 或未知关键字。Schema 最大 32 KiB、嵌套不超过 16 层、节点不超过 256 个。
|
|
46
50
|
|
|
47
|
-
Database Function
|
|
51
|
+
Database Function 与 Mutation 不手写 `inputSchema`,由服务端根据参数声明生成;参数声明见 [查询参数协议](database-function.md#function-文件与参数)与 [Mutation 声明](mutations.md#声明与参数)。
|
|
48
52
|
|
|
49
53
|
FaaS 在 `meta.json` 中声明 `inputSchema`,在 `index.ts` 中实现 handler。部署时,CLI 自动校验并上传 Schema 和应用源码。
|
|
50
54
|
|
|
@@ -78,17 +82,17 @@ function parseCreateTask(value: unknown): CreateTaskInput {
|
|
|
78
82
|
const input = value as Record<string, unknown>
|
|
79
83
|
if (
|
|
80
84
|
Object.keys(input).some((key) => key !== 'title' && key !== 'status') ||
|
|
81
|
-
typeof input.title !== 'string' || input.title.length === 0 ||
|
|
85
|
+
typeof input.title !== 'string' || input.title.trim().length === 0 ||
|
|
82
86
|
typeof input.status !== 'string' ||
|
|
83
87
|
!['待处理', '进行中', '已完成'].includes(input.status)
|
|
84
88
|
) {
|
|
85
89
|
throw new Error('任务名称或状态无效')
|
|
86
90
|
}
|
|
87
|
-
return { title: input.title, status: input.status as CreateTaskInput['status'] }
|
|
91
|
+
return { title: input.title.trim(), status: input.status as CreateTaskInput['status'] }
|
|
88
92
|
}
|
|
89
93
|
```
|
|
90
94
|
|
|
91
|
-
默认导出 `handler(rawParams, context)
|
|
95
|
+
默认导出 `handler(rawParams, context)`,完整创建示例见下文。title 在 handler 去除首尾空白后判空并写入规范化值;Schema minLength 只是基础长度约束。上述 meta.json、入参校验和 Page 的 createTask 示例共同使用 title/status;实际业务须同时按 Catalog 更新 Schema、调用参数和 handler,不只改其中一处。
|
|
92
96
|
|
|
93
97
|
`rawParams` 已经是业务对象。输入校验失败返回稳定业务码、`data:null` 和可读 `msg`。`FaasHandlerResult` 只描述 handler 的返回约定,不得作为页面 `invokeFunction` 的泛型参数。
|
|
94
98
|
|
|
@@ -149,7 +153,7 @@ type DownstreamOutcome<T> =
|
|
|
149
153
|
|
|
150
154
|
`retryable` 同时取决于错误和写入语义,不能只看 HTTP 状态。明确幂等的固定字段更新或删除遇到 transport、408、429 或 5xx 时可以标记为可重试;非幂等创建出现 transport 或结果未知时必须为 `false`,除非业务已有稳定幂等键和去重机制。页面不得仅因为 `retryable: true` 自动重提,仍按 operation 契约决定交互。
|
|
151
155
|
|
|
152
|
-
|
|
156
|
+
多路写入的受理、部分完成与失败码按[结果规则](agent-tool-design.md#结果与错误)处理。已完成部分写入时保留 `code=0`,在 data 中标记状态、已完成 ID、失败步骤及后续动作;全部成功省略 errors。
|
|
153
157
|
|
|
154
158
|
应用 invoke 网关在 handler 返回前产生的 504、运行时崩溃或加载失败无法被上述结构捕获。排查这类错误时保留 invoke HTTP 响应自身的 `x-tt-logid`,不要伪装成某次 OpenAPI 调用错误。
|
|
155
159
|
|
|
@@ -194,8 +198,7 @@ POST /open-apis/bitable/v1/apps/:base_token/tables/:table_id/remove_attachments
|
|
|
194
198
|
五个请求体都是 strict JSON Schema:不接受表格中未列出的额外顶层字段。「每批 1~200 条
|
|
195
199
|
记录」只适用于前三条 batch 路由;附件增量路由的限制是**一次操作的 `file_token` 总数不超过
|
|
196
200
|
50**;附件映射及每个 record-field 数组没有非空 Schema 约束。record ID 必须以 `rec` 开头、
|
|
197
|
-
后续为大小写字母和数字,用 `^rec[A-Za-z0-9]{1,32}$`
|
|
198
|
-
`reczz2893mUCkwnr` 长度会超过旧的 `{1,11}` 上限,不要在业务层依赖固定短长度);删除列表不允许重复,
|
|
201
|
+
后续为大小写字母和数字,用 `^rec[A-Za-z0-9]{1,32}$` 校验即可;删除列表不允许重复,
|
|
199
202
|
更新映射的 key 自然唯一。`batch_update` 使用 `update_records` 为不同记录分别提交
|
|
200
203
|
patch;不要混用 MCP 工具层 `patch_records_batch` 的 `record_id_list + patch` 请求结构。
|
|
201
204
|
|
|
@@ -260,7 +263,7 @@ patch;不要混用 MCP 工具层 `patch_records_batch` 的 `record_id_list + p
|
|
|
260
263
|
- `batch_delete`:`record_id_list` 必须与请求列表一致,`record_not_found` 必须是其子集;实际删除的 ID 是两者的差集。
|
|
261
264
|
|
|
262
265
|
`code === 0` 且 `record_not_found` 非空是 批量写入的合法部分成功,不是 `invalid_response`。FaaS handler 必须在
|
|
263
|
-
业务结果中保留已完成和未找到的 ID;需要向 Page
|
|
266
|
+
业务结果中保留已完成和未找到的 ID;需要向 Page 表达部分成功时,保留 `code=0`,在 data 中标记部分完成状态,
|
|
264
267
|
但不得伪装成下游失败或整体重试。只有响应缺失、类型不符或不满足上述 operation 约束时才按
|
|
265
268
|
`invalid_response` 处理;非幂等创建不得自动重试。
|
|
266
269
|
|
|
@@ -464,12 +467,12 @@ export default async function handler(
|
|
|
464
467
|
const [recordId] = created.record_id_list
|
|
465
468
|
if (created.ignored_fields?.length) {
|
|
466
469
|
return {
|
|
467
|
-
data: { created: true, recordId, ignoredFields: created.ignored_fields },
|
|
468
|
-
code:
|
|
470
|
+
data: { status: 'partial', created: true, recordId, ignoredFields: created.ignored_fields },
|
|
471
|
+
code: 0,
|
|
469
472
|
msg: '任务已创建,但部分字段未写入,请勿重复创建',
|
|
470
473
|
}
|
|
471
474
|
}
|
|
472
|
-
return { data: { created: true, recordId }, code: 0, msg: 'success' }
|
|
475
|
+
return { data: { status: 'complete', created: true, recordId }, code: 0, msg: 'success' }
|
|
473
476
|
}
|
|
474
477
|
```
|
|
475
478
|
|
|
@@ -556,3 +559,27 @@ batch 路由单批最多 200 条。多选、多人员和多值关联这些集合
|
|
|
556
559
|
**整格覆盖的合并基准必须是可信的完整列表。** Database Function 回读走从库,刚写完就回读可能拿到写入前的旧值;拿缺项的列表做基准整格写回,会静默删掉其它项,而写入仍返回成功。读取失败、从未读到过、或回读缺少本次刚写入的项时,禁掉入口让用户稍后重试,不要写。
|
|
557
560
|
|
|
558
561
|
页面内可串行处理同一记录字段的更新,但不能因此承诺跨访问者原子性。文件字节的上传与展示是另外的路,见[文件传输](file-transfer.md)。
|
|
562
|
+
|
|
563
|
+
### 独立 Schema 契约(CLI 支持时)
|
|
564
|
+
|
|
565
|
+
当前 CLI 的 `contracts generate` 可从 SDK `defineFunction` 的独立 `contract.ts`
|
|
566
|
+
提取 input/output;先用 `base-database-cli contracts --help` 核对能力。旧版本可继续手写 meta,
|
|
567
|
+
不因此中断既有工程。CLI 只执行隔离后的 Schema 构造和 Standard JSON Schema 转换,
|
|
568
|
+
无法隔离或转换时警告并使用 unknown/runtime-only,不执行业务入口。
|
|
569
|
+
|
|
570
|
+
用 `contracts generate <工程目录>` 显式更新生成区和 Page 类型客户端;check/deploy
|
|
571
|
+
发现过期契约时需要重新生成。后端发现 FG 不可用时使用 `--runtime-only` 省略发现 Schema,
|
|
572
|
+
不切换身份或开启 FG。完整本地契约仍保留可转换的规则,SQL 输出类型保持 unknown。
|
|
573
|
+
生成细节、白名单和限制见 CLI 包 README 的“本地诊断与 Function 契约”。
|
|
574
|
+
|
|
575
|
+
### 页面消费部分完成结果
|
|
576
|
+
|
|
577
|
+
下面消费片段接收上述 createTask 的 envelope;仅在完整确认后展示全部完成,部分完成也保留 recordId,不重复创建。按[Function 调用契约](development.md#function-调用契约)选择工程自己的调用入口。
|
|
578
|
+
|
|
579
|
+
<!-- example: faas-partial-consumer -->
|
|
580
|
+
```ts
|
|
581
|
+
export function createTaskOutcome(result: {code: number; msg?: string; data?: {created: boolean | null; recordId?: string; status?: string; ignoredFields?: unknown[]}}) {
|
|
582
|
+
if (result.code !== 0 || !result.data || result.data.created !== true || !result.data.recordId) throw new Error(result.msg || '创建结果待核对,不重复创建')
|
|
583
|
+
return {recordId: result.data.recordId, complete: result.data.status === 'complete' && !result.data.ignoredFields?.length}
|
|
584
|
+
}
|
|
585
|
+
```
|