636 lines
16 KiB
Markdown
636 lines
16 KiB
Markdown
# API 文档
|
||
|
||
## 元数据
|
||
- 需求编号:004-02
|
||
- 文档版本:v1.0.0
|
||
- 创建时间:2026-02-05
|
||
- 创建人:AI Assistant
|
||
- 状态:已完成
|
||
|
||
## API 概述
|
||
|
||
本文档描述了 Tooling API 元数据操作功能的 REST API 接口,包括元数据的创建、查询、更新、删除操作,以及操作日志的查询功能。
|
||
|
||
### 核心功能
|
||
- **创建元数据**:支持创建 CustomObject、CustomField、ApexClass、ApexTrigger、Flow
|
||
- **查询元数据**:支持通用 SOQL 查询,使用 SoqlBuilder 动态构建查询语句
|
||
- **更新元数据**:支持通用元数据更新操作
|
||
- **删除元数据**:支持通用元数据删除操作
|
||
- **操作日志查询**:支持查询元数据操作日志
|
||
|
||
### 技术架构
|
||
- **Controller**:`ToolingMetadataController` - 处理 HTTP 请求和响应
|
||
- **Service**:`ToolingMetadataServiceImpl` - 实现业务逻辑
|
||
- **Factory**:`ToolingConnectionFactory` - 管理 Tooling API 连接
|
||
- **异步日志**:使用 Spring @Async 异步记录操作日志
|
||
|
||
### 基础信息
|
||
- **基础路径**:`/salesforce/tooling/metadata`
|
||
- **认证方式**:Bearer Token(JWT)
|
||
- **权限控制**:`@PreAuthorize("@ss.hasLogin()")`
|
||
- **数据格式**:JSON
|
||
|
||
## 接口列表
|
||
|
||
### 1. 创建自定义对象
|
||
|
||
#### 接口信息
|
||
- **接口名称**:创建自定义对象
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/salesforce/tooling/metadata/custom-object`
|
||
- **功能描述**:通过 Tooling API 创建 Salesforce 自定义对象
|
||
|
||
#### 请求参数
|
||
|
||
**请求体(Body)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| customObject | Object | 是 | 自定义对象定义 |
|
||
| customObject.fullName | String | 是 | 对象 API 名称(如 MyCustomObject__c) |
|
||
| customObject.label | String | 是 | 对象标签 |
|
||
| customObject.pluralLabel | String | 是 | 对象复数标签 |
|
||
| customObject.description | String | 否 | 对象描述 |
|
||
| customObject.sharingModel | String | 否 | 共享模式(ReadWrite/Read/Private) |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"fullName": "MyCustomObject__c",
|
||
"label": "My Custom Object",
|
||
"pluralLabel": "My Custom Objects",
|
||
"description": "Custom object for testing",
|
||
"sharingModel": "ReadWrite"
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 响应数据 |
|
||
| data.success | Boolean | 是否成功 |
|
||
| data.id | String | 创建的对象 ID |
|
||
| data.metadataName | String | 元数据名称 |
|
||
| data.operationTime | String | 操作时间(yyyy-MM-dd HH:mm:ss) |
|
||
| data.errorCode | String | 错误码(失败时) |
|
||
| data.errorMessage | String | 错误消息(失败时) |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "创建自定义对象成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "a01xx0000000001AAA",
|
||
"metadataName": "MyCustomObject__c",
|
||
"operationTime": "2026-02-05 10:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
**失败响应示例**:
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "创建自定义对象失败",
|
||
"data": {
|
||
"success": false,
|
||
"metadataName": "MyCustomObject__c",
|
||
"operationTime": "2026-02-05 10:00:00",
|
||
"errorCode": "TOOLING_META_003",
|
||
"errorMessage": "元数据已存在"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 创建自定义字段
|
||
|
||
#### 接口信息
|
||
- **接口名称**:创建自定义字段
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/salesforce/tooling/metadata/custom-field`
|
||
- **功能描述**:在指定对象上创建自定义字段
|
||
|
||
#### 请求参数
|
||
|
||
**请求体(Body)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| customField | Object | 是 | 自定义字段定义 |
|
||
| customField.fullName | String | 是 | 字段 API 名称(如 MyField__c) |
|
||
| customField.label | String | 是 | 字段标签 |
|
||
| customField.type | String | 是 | 字段类型(Text/Number/Date/DateTime/Checkbox 等) |
|
||
| customField.length | Integer | 否 | 字段长度(Text 类型时必填) |
|
||
| objectType | String | 是 | 对象类型(如 MyCustomObject__c) |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"customField": {
|
||
"fullName": "MyField__c",
|
||
"label": "My Field",
|
||
"type": "Text",
|
||
"length": 255
|
||
},
|
||
"objectType": "MyCustomObject__c"
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 响应数据 |
|
||
| data.success | Boolean | 是否成功 |
|
||
| data.id | String | 创建的字段 ID |
|
||
| data.metadataName | String | 元数据名称 |
|
||
| data.operationTime | String | 操作时间 |
|
||
| data.errorCode | String | 错误码(失败时) |
|
||
| data.errorMessage | String | 错误消息(失败时) |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "创建自定义字段成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "a02xx0000000001AAA",
|
||
"metadataName": "MyCustomObject__c.MyField__c",
|
||
"operationTime": "2026-02-05 10:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 创建 Apex 类
|
||
|
||
#### 接口信息
|
||
- **接口名称**:创建 Apex 类
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/salesforce/tooling/metadata/apex-class`
|
||
- **功能描述**:创建新的 Apex 类定义
|
||
|
||
#### 请求参数
|
||
|
||
**请求体(Body)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| apexClass | Object | 是 | Apex 类定义 |
|
||
| apexClass.name | String | 是 | 类名 |
|
||
| apexClass.body | String | 是 | 类代码内容 |
|
||
| apexClass.apiVersion | Double | 否 | API 版本(默认 58.0) |
|
||
| apexClass.status | String | 否 | 状态(Active/Inactive,默认 Active) |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"apexClass": {
|
||
"name": "MyClass",
|
||
"body": "public class MyClass {\n public void hello() {\n System.debug('Hello World');\n }\n}",
|
||
"apiVersion": 58.0,
|
||
"status": "Active"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "创建 Apex 类成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "01pxx0000000001AAA",
|
||
"metadataName": "MyClass",
|
||
"operationTime": "2026-02-05 10:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 创建 Apex 触发器
|
||
|
||
#### 接口信息
|
||
- **接口名称**:创建 Apex 触发器
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/salesforce/tooling/metadata/apex-trigger`
|
||
- **功能描述**:创建新的 Apex 触发器
|
||
|
||
#### 请求参数
|
||
|
||
**请求体(Body)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| apexTrigger | Object | 是 | Apex 触发器定义 |
|
||
| apexTrigger.name | String | 是 | 触发器名称 |
|
||
| apexTrigger.body | String | 是 | 触发器代码内容 |
|
||
| apexTrigger.tableEnumOrId | String | 是 | 关联对象(如 Account) |
|
||
| apexTrigger.apiVersion | Double | 否 | API 版本(默认 58.0) |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"apexTrigger": {
|
||
"name": "MyTrigger",
|
||
"body": "trigger MyTrigger on Account (before insert) {\n System.debug('Account created');\n}",
|
||
"tableEnumOrId": "Account",
|
||
"apiVersion": 58.0
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "创建 Apex 触发器成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "01qxx0000000001AAA",
|
||
"metadataName": "MyTrigger",
|
||
"operationTime": "2026-02-05 10:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5. 创建 Flow
|
||
|
||
#### 接口信息
|
||
- **接口名称**:创建 Flow
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/salesforce/tooling/metadata/flow`
|
||
- **功能描述**:创建新的 Flow 定义
|
||
|
||
#### 请求参数
|
||
|
||
**请求体(Body)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| flow | Object | 是 | Flow 定义 |
|
||
| flow.fullName | String | 是 | Flow API 名称 |
|
||
| flow.label | String | 是 | Flow 标签 |
|
||
| flow.description | String | 否 | Flow 描述 |
|
||
| flow.apiVersion | Double | 否 | API 版本(默认 58.0) |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"flow": {
|
||
"fullName": "MyFlow",
|
||
"label": "My Flow",
|
||
"description": "Flow for testing",
|
||
"apiVersion": 58.0
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "创建 Flow 成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "300xx0000000001AAA",
|
||
"metadataName": "MyFlow",
|
||
"operationTime": "2026-02-05 10:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 6. 查询元数据
|
||
|
||
#### 接口信息
|
||
- **接口名称**:查询元数据
|
||
- **请求方式**:GET
|
||
- **请求路径**:`/salesforce/tooling/metadata/query`
|
||
- **功能描述**:使用 SOQL 查询元数据
|
||
|
||
#### 请求参数
|
||
|
||
**查询参数(Query)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| objectType | String | 是 | 对象类型(如 ApexClass、CustomObject 等) |
|
||
| fields | String | 是 | 查询字段(逗号分隔,如 Id,Name,ApiVersion) |
|
||
| whereClause | String | 否 | WHERE 条件(如 Name='MyClass') |
|
||
| limit | Integer | 否 | 查询限制(默认 100,最大 2000) |
|
||
|
||
**请求示例**:
|
||
```http
|
||
GET /salesforce/tooling/metadata/query?objectType=ApexClass&fields=Id,Name,ApiVersion,Status&limit=10 HTTP/1.1
|
||
Host: localhost:8080
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码 |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 响应数据 |
|
||
| data.total | Integer | 总记录数 |
|
||
| data.records | Array | 记录列表 |
|
||
| data.queryTime | String | 查询时间 |
|
||
| data.errorCode | String | 错误码(失败时) |
|
||
| data.errorMessage | String | 错误消息(失败时) |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "查询元数据成功",
|
||
"data": {
|
||
"total": 100,
|
||
"records": [
|
||
{
|
||
"id": "01pxx0000000001AAA",
|
||
"name": "MyClass",
|
||
"apiVersion": 58.0,
|
||
"status": "Active"
|
||
}
|
||
],
|
||
"queryTime": "2026-02-05 10:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 7. 更新元数据
|
||
|
||
#### 接口信息
|
||
- **接口名称**:更新元数据
|
||
- **请求方式**:PUT
|
||
- **请求路径**:`/salesforce/tooling/metadata/update`
|
||
- **功能描述**:更新指定的元数据记录
|
||
|
||
#### 请求参数
|
||
|
||
**请求体(Body)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| sObject | Object | 是 | 元数据对象 |
|
||
| sObject.id | String | 是 | 记录 ID |
|
||
| sObject.attributes | Object | 是 | 对象属性 |
|
||
| sObject.attributes.type | String | 是 | 对象类型(如 ApexClass) |
|
||
| ... | ... | ... | 其他字段根据对象类型而定 |
|
||
|
||
**请求示例**:
|
||
```json
|
||
{
|
||
"sObject": {
|
||
"id": "01pxx0000000001AAA",
|
||
"attributes": {
|
||
"type": "ApexClass"
|
||
},
|
||
"name": "MyClassUpdated",
|
||
"body": "public class MyClassUpdated {\n public void hello() {\n System.debug('Hello World Updated');\n }\n}",
|
||
"apiVersion": 58.0,
|
||
"status": "Active"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "更新元数据成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "01pxx0000000001AAA",
|
||
"operationTime": "2026-02-05 10:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 8. 删除元数据
|
||
|
||
#### 接口信息
|
||
- **接口名称**:删除元数据
|
||
- **请求方式**:DELETE
|
||
- **请求路径**:`/salesforce/tooling/metadata/delete`
|
||
- **功能描述**:删除指定的元数据记录
|
||
|
||
#### 请求参数
|
||
|
||
**查询参数(Query)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| id | String | 是 | 记录 ID |
|
||
| objectType | String | 是 | 对象类型(如 ApexClass) |
|
||
|
||
**请求示例**:
|
||
```http
|
||
DELETE /salesforce/tooling/metadata/delete?id=01pxx0000000001AAA&objectType=ApexClass HTTP/1.1
|
||
Host: localhost:8080
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "删除元数据成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "01pxx0000000001AAA",
|
||
"operationTime": "2026-02-05 10:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 9. 获取元数据操作日志
|
||
|
||
#### 接口信息
|
||
- **接口名称**:获取元数据操作日志
|
||
- **请求方式**:GET
|
||
- **请求路径**:`/salesforce/tooling/metadata/logs`
|
||
- **功能描述**:查询元数据操作日志
|
||
|
||
#### 请求参数
|
||
|
||
**查询参数(Query)**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| operationType | String | 否 | 操作类型(create/update/delete/query) |
|
||
| metadataType | String | 否 | 元数据类型(如 ApexClass) |
|
||
| status | String | 否 | 操作状态(success/failed) |
|
||
| startTime | String | 否 | 开始时间(yyyy-MM-dd HH:mm:ss) |
|
||
| endTime | String | 否 | 结束时间(yyyy-MM-dd HH:mm:ss) |
|
||
| pageNum | Integer | 否 | 页码(默认 1) |
|
||
| pageSize | Integer | 否 | 每页大小(默认 10,最大 100) |
|
||
|
||
**请求示例**:
|
||
```http
|
||
GET /salesforce/tooling/metadata/logs?operationType=create&startTime=2026-02-05%2000:00:00&endTime=2026-02-05%2023:59:59&pageNum=1&pageSize=10 HTTP/1.1
|
||
Host: localhost:8080
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码 |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 响应数据 |
|
||
| data.total | Integer | 总记录数 |
|
||
| data.pageNum | Integer | 当前页码 |
|
||
| data.pageSize | Integer | 每页大小 |
|
||
| data.list | Array | 日志列表 |
|
||
| data.list[].id | Long | 日志 ID |
|
||
| data.list[].operationType | String | 操作类型 |
|
||
| data.list[].metadataType | String | 元数据类型 |
|
||
| data.list[].metadataId | String | 元数据 ID |
|
||
| data.list[].metadataName | String | 元数据名称 |
|
||
| data.list[].status | String | 操作状态 |
|
||
| data.list[].operationTime | String | 操作时间 |
|
||
| data.list[].userId | String | 用户 ID |
|
||
|
||
**成功响应示例**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "查询元数据操作日志成功",
|
||
"data": {
|
||
"total": 100,
|
||
"pageNum": 1,
|
||
"pageSize": 10,
|
||
"list": [
|
||
{
|
||
"id": 1,
|
||
"operationType": "create",
|
||
"metadataType": "ApexClass",
|
||
"metadataId": "01pxx0000000001AAA",
|
||
"metadataName": "MyClass",
|
||
"status": "success",
|
||
"operationTime": "2026-02-05 10:00:00",
|
||
"userId": "user001"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 错误码
|
||
|
||
### 错误码列表
|
||
|
||
| 错误码 | 错误消息 | 说明 |
|
||
|--------|----------|------|
|
||
| TOOLING_META_001 | Session 无效或已过期 | Session ID 无效或已过期,需要重新登录 |
|
||
| TOOLING_META_002 | 创建元数据失败 | 创建元数据失败 |
|
||
| TOOLING_META_003 | 查询元数据失败 | 查询元数据失败 |
|
||
| TOOLING_META_004 | 更新元数据失败 | 更新元数据失败 |
|
||
| TOOLING_META_005 | 删除元数据失败 | 删除元数据失败 |
|
||
| TOOLING_META_006 | 权限不足 | 当前用户没有访问该元数据的权限 |
|
||
| TOOLING_META_007 | 元数据验证失败 | 元数据验证失败 |
|
||
| TOOLING_META_008 | 用户未登录 | 用户未登录或 Session 已过期 |
|
||
| TOOLING_META_009 | 元数据类型不支持 | 不支持的元数据类型 |
|
||
| TOOLING_META_010 | 元数据已存在 | 元数据已存在 |
|
||
| TOOLING_META_011 | 元数据不存在 | 元数据不存在 |
|
||
|
||
### 错误响应格式
|
||
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "操作失败",
|
||
"data": {
|
||
"success": false,
|
||
"errorCode": "TOOLING_META_001",
|
||
"errorMessage": "Session 无效或已过期"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 数据类型说明
|
||
|
||
### 元数据类型(MetadataType)
|
||
|
||
| 类型 | 说明 |
|
||
|------|------|
|
||
| CustomObject | 自定义对象 |
|
||
| CustomField | 自定义字段 |
|
||
| CustomIndex | 自定义索引 |
|
||
| ApexClass | Apex 类 |
|
||
| ApexTrigger | Apex 触发器 |
|
||
| ApexPage | Visualforce 页面 |
|
||
| ApexComponent | Visualforce 组件 |
|
||
| Flow | Flow 定义 |
|
||
| FlowDefinition | Flow 定义(新版) |
|
||
| FlowVersion | Flow 版本 |
|
||
| FlowTestCoverage | Flow 测试覆盖率 |
|
||
|
||
### 操作类型(OperationType)
|
||
|
||
| 类型 | 说明 |
|
||
|------|------|
|
||
| create | 创建操作 |
|
||
| update | 更新操作 |
|
||
| delete | 删除操作 |
|
||
| query | 查询操作 |
|
||
|
||
### 操作状态(Status)
|
||
|
||
| 状态 | 说明 |
|
||
|------|------|
|
||
| success | 成功 |
|
||
| failed | 失败 |
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
- [需求文档](../requirements/sub/2026-01-28-004-02-元数据操作.md)
|
||
- [设计文档](../design/2026-02-03-004-02-元数据操作-设计.md)
|
||
- [决策文档](../decisions/2026-02-03-004-02-ADR-元数据操作技术选型.md)
|
||
- [SQL 脚本](../sql/2026-02-03-004-02-元数据操作日志.sql)
|
||
- [提示词文档](../prompts/2026-02-05-004-02-prompt-元数据操作.md)
|
||
- [变更日志](../changelog/2026-02-05-004-02-changelog.md)
|
||
- [复盘文档](../retros/2026-02-05-004-02-retro.md)
|
||
- [会话记录](../sessions/2026-02-03-004-02-session.md)
|