Data Table for Page API Skill
Overview
This skill provides a Python client script to access the platform data table REST APIs in sandbox.
Use this skill (@datatable-for-page-api) when the user wants to perform any of the following:
- 创建数据表: create a new custom table with a name and optional description
- 查看/搜索数据表: list existing tables, search by name, get table definition detail
- 修改表结构: rename table, change description, update field/column definitions
- 删除数据表: remove a table definition
- 复制表: copy an existing table structure to a new table
- 创建数据表SQL操作API: create a new SQL-based table operation API for page components
- 更新数据表SQL操作API: update an existing SQL-based table operation API
Agent workflow
创建表并定义SQL操作API(推荐标准流程)
- 调用
add-table(POST .../compose/db/table/add)创建表,获得表 ID。 - 立刻调用
get-table读出建表时自动生成的 8 个系统字段(id/uid/user_name/nick_name/agent_id/agent_name/created/modified),它们必须原样回传。 - 调用
update-table-definition(POST .../compose/db/table/updateTableDefinition)定义字段结构——必须传"系统字段(原样)+自定义字段"的完整 fieldList,不能只传新字段。详见下方「⚠️ update-table-definition 关键约束」。 - 再次调用
get-table读取dorisTable(物理表名,形如custom_table_{表ID}),SQL API 的 SQL 语句里必须用这个物理表名,不能用建表时的中文表名(如"用户表")。 - 调用
table-sql-new(POST .../table/sql/new)创建数据表SQL操作API,用于页面组件调用。 - 如需修改已创建的SQL操作API,调用
table-sql-update(POST .../table/sql/update)。 - 【最易遗漏】前端对接 + 登记进
.project.md:建表/建 API 只是脚手架。建好后必须:①获取每个 SQL 操作 API 的端点 token;②按下方「⚠️ 前端对接规范(必读)」落地前端 lib;③把表 ID、物理表名、token、SQL、入出参全部登记进项目根目录的.project.md(见下方「项目记忆.project.md」)。前端真正能调用才算闭环。
⚠️ 不要用
copy-table来"绕过"建表/加字段。update-table-definition用对格式后完全能自建自定义字段(见下方约束)。复制别人的表会把无关字段带进来,造成字段语义错乱。
查询表信息
- 若不知道表 ID,先调用
list-tables获取表列表。 - 调用
get-table(GET .../compose/db/table/detailById)获取表定义详情。
脚本封装:add_table / list_tables / update_table_definition / table_sql_new / table_sql_update 等;CLI:add-table、list-tables、table-sql-new、table-sql-update 等。
⚠️ update-table-definition 关键约束(必读,否则必然报错)
这是本技能最容易踩坑的接口。以下任一条件不满足,后端会返回 4000 JSON parse error 或 5000 系统开小差啦:
fieldType必须是数字枚举,绝对不能传类型名字符串(如"VARCHAR"/"INT")。合法枚举:fieldType 类型 1VARCHAR 2INT 5DATETIME 6BIGINT 7MEDIUMTEXT / 长文本 必须传完整的 fieldList(系统字段 + 自定义字段),只传自定义字段会被拒。
- 先
get-table读出系统字段,原样保留其fieldType/defaultValue(时间字段是CURRENT_TIMESTAMP)/sortIndex/systemFieldFlag:true,再追加自定义字段。 - VARCHAR 字段需带
fieldStrLen(如 255),数值/时间字段fieldStrLen传null。
- 先
**字段注释的 key 是
fieldDescription**。每个字段需带完整属性:
fieldName/fieldDescription/fieldType(数字) /fieldStrLen/nullableFlag/defaultValue/uniqueFlag/enabledFlag/sortIndex/systemFieldFlag。
可直接复制的正确 fieldList 模板
下面是已验证成功的完整请求体(系统字段原样 + 自定义字段),替换 id 为你的表 ID、自定义字段按需修改即可:
python scripts/datatable_for_page_api.py update-table-definition --id 398 --field-list '[
{"fieldName":"id","fieldDescription":"主键ID","fieldType":6,"fieldStrLen":null,"nullableFlag":false,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":0,"systemFieldFlag":true},
{"fieldName":"uid","fieldDescription":"用户唯一标识","fieldType":1,"fieldStrLen":255,"nullableFlag":false,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":1,"systemFieldFlag":true},
{"fieldName":"user_name","fieldDescription":"用户名","fieldType":1,"fieldStrLen":255,"nullableFlag":true,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":2,"systemFieldFlag":true},
{"fieldName":"nick_name","fieldDescription":"用户昵称","fieldType":1,"fieldStrLen":255,"nullableFlag":true,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":3,"systemFieldFlag":true},
{"fieldName":"agent_id","fieldDescription":"智能体唯一标识","fieldType":1,"fieldStrLen":255,"nullableFlag":true,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":4,"systemFieldFlag":true},
{"fieldName":"agent_name","fieldDescription":"智能体名称","fieldType":1,"fieldStrLen":255,"nullableFlag":true,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":5,"systemFieldFlag":true},
{"fieldName":"created","fieldDescription":"数据创建时间","fieldType":5,"fieldStrLen":null,"nullableFlag":false,"defaultValue":"CURRENT_TIMESTAMP","uniqueFlag":false,"enabledFlag":true,"sortIndex":6,"systemFieldFlag":true},
{"fieldName":"modified","fieldDescription":"数据修改时间","fieldType":5,"fieldStrLen":null,"nullableFlag":false,"defaultValue":"CURRENT_TIMESTAMP","uniqueFlag":false,"enabledFlag":true,"sortIndex":7,"systemFieldFlag":true},
{"fieldName":"title","fieldDescription":"标题","fieldType":1,"fieldStrLen":255,"nullableFlag":true,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":8,"systemFieldFlag":false},
]'
排错提示:若仍报
5000,逐项自查——①是否误用了字符串 fieldType ②是否漏传系统字段 ③是否漏了 fieldStrLen。
⚠️ 前端对接规范(必读,建完 SQL API 后立刻照做)
table-sql-new / table-sql-update 只是把 SQL 操作 API 注册到平台;前端页面真正调用它时走的是另一条路径。这一步没有文档支撑是前后对接反复踩坑的根因,逐条核对:
0. 关键真相:SQL 操作 API 本质是工作流(Workflow)
通过本技能创建的「数据表 SQL 操作 API」,平台会把它实例化为一个 Workflow(工作流),工作流内部含一个 SQL 节点,真正去读写底层物理表(形如 custom_table_{表ID})。
- 前端页面调用时,调用的就是这个工作流。
- 每个这样的工作流都有一个唯一的端点 token(一串数字),前端 lib 靠「功能名 → token」映射表来调用。
- ⚠️ 该 token 通常不直接出现在创建接口的返回体里,需要从平台「SQL 操作 API / 工作流列表」中获取。取到后必须立即登记进
.project.md,下次无需再查找。 - ⚠️ 实际上
table-sql-new/table-sql-update的返回体(data.apiSchema)里会带调用路径.../api/v1/4sandbox/page/w/{token},末尾那串数字就是当前生效的 token —— 直接从这里抓即可,不必再去别处找。
0.1 ⚠️ 更新 SQL API 后,端点 token 会变(高频踩坑)
table-sql-update成功后,平台经常会重新生成端点 token,旧 token 立即失效。- 现象:只改了 SQL(或 args),前端却开始 404 / 调用失败 / 返回非预期结果,且
.project.md里登记的还是旧 token。 - 每次 new/update 后的强制闭环(少一步都会断链):
- 从返回体
data.apiSchema里抓最新 token(正则page/w/(\d+)); - 立刻用新 token 覆盖
.project.md对应条目; - 立刻同步前端 lib 的「功能名 → token」映射;
- 用新 token 实际调一次验证通不通。
- 从返回体
- 排错第一反应:前端报「调用失败 / 404 / 调不通」时,先查 token 是否在最近一次 update 后没刷新,再去查 SQL 语法。
1. 调用路径与端点 token
页面调用路径(唯一正确路径,同源调用,浏览器自带登录态):
POST {PLATFORM_BASE_URL}/api/v1/4sandbox/page/w/{token} Content-Type: application/json- 前端代码里直接用相对路径
/api/page/w/{token}即可(同源,登录态由浏览器自动带),不要在前端请求头里塞Authorization/SANDBOX_ACCESS_KEY——那是 Python 脚本侧管理端鉴权用的,前端拿不到也不该出现。 /api/v1/4sandbox/...前缀仅用于 Python 脚本侧内部调试,前端不要用。
- 前端代码里直接用相对路径
2. 响应外壳结构(查询类)
所有查询类 API 的返回都包在统一外壳里,业务数据在 data.outputList,不是 data 本身:
{
"success": true,
"message": "success",
"data": {
"outputList": [ { "id": 1, "...": "..." } ],
"rowNum": 1
}
}
前端解析:const rows = result.data?.outputList ?? []。务必先判 result.success,失败时抛 result.message。
3. 写操作(INSERT / UPDATE / DELETE)语义
- 写操作通常只返回
{ success: true },不回填新主键 id。 - 因此前端「新增」后不要用假 id 渲染单条,应直接整表/按条件重新拉取列表刷新。
- 批量删除/更新同理,按调用次数计数成功条数即可。
4. LIKE 模糊查询:用普通参数 {{var}} + 前端自拼 %
- 模糊查询统一用
{{var}}普通参数占位符,不要用${{var}}。 - SQL 写法:
WHERE name LIKE {{keyword}}(和精确匹配=用同一种占位符)。 - 平台不会自动包
%,前端必须自己拼:传%关键词%(前一个%、后一个%),例如搜「小美」就传%小美%。 - 普通参数走参数化通道,值一定带引号,不会把关键词当成列名。
- ⚠️ 不要用
${{var}}:它在本平台展开后值常丢引号,生成WHERE name LIKE 小美,MySQL 把关键词当列名,报Unknown column 'xxx' in 'where clause'。 - 精确匹配用
={{var}},模糊匹配用LIKE {{keyword}}(前端拼%),二者不要混用。
5. 字段名对齐
- 建表字段名(
fieldName)= SQL 列名 = 响应 JSON 字段名,三者必须一致。 - 当后端列名与前端业务概念不同时(很常见),在前端
lib层集中写一个toXxx(raw)映射函数做转换,组件层只消费映射后的统一类型,不要把映射逻辑散落到各个组件。 id在后端是数值(bigint),前端建议统一String(id)处理,避免大整数精度问题。- 系统字段
created/modified是平台自动维护的CURRENT_TIMESTAMP,建表时保留其defaultValue,前端只读不写。
6. referer
页面同源调用时浏览器会自动带上 referer,一般无需手动处理。若在非页面环境(如脚本/SSR)调试页面端点,需手动带 referer: {PLATFORM_BASE_URL}/page/{PROJECT_ID}-/dev/,否则可能被拦。
项目记忆 .project.md(强制执行)
项目根目录维护一份 .project.md,作为 AI 的「项目记忆中枢」,集中沉淀项目设计、数据表结构、SQL 操作 API(工作流)及其端点 token 等关键信息。解决「端点 token 从哪来」反复踩坑的问题。
- 进入项目做任何开发前,必须先阅读
.project.md(不存在则创建)。 - 建表 / 建(或更新)SQL 操作 API 后,立即把表 ID、物理表名、端点 token、SQL、入出参登记进
.project.md,再开始写前端代码。 - 前端开发时,端点 token、字段名一律从
.project.md取,不要凭记忆或猜测。 - 开发过程中只要产生了应长期保留的信息(改了字段、定了调用约定等),同步更新
.project.md。 - 它是唯一事实来源(single source of truth);只存「项目级、跨会话需保留」的信息,临时调试信息不要塞进来。
.project.md 建议登记模板
# 项目记忆(.project.md)
## 1. 项目概述
- 用途 / 技术栈 / 模版类型(react-vite / vue3-vite 等)
## 2. 数据表清单
### 表:<表名>
- 表 ID:<如 398>
- 物理表名(dorisTable):<如 custom_table_398>
- 字段:
| 字段 | 类型 | 系统/自定义 | 说明 |
|------|------|------------|------|
## 3. SQL 操作 API(工作流)清单
### <功能名,如 getAll / add / update / delete / search>
- 工作流 ID:<如平台分配的 workflow id>
- 端点 token:<前端 /api/page/w/{token} 用的那串数字>
- 绑定物理表:<如 custom_table_398>
- SQL 节点文本:
```sql
SELECT ... FROM custom_table_398 WHERE ...
- 入参:<参数名 / 是否必填 / 用途;LIKE 用 {{var}},前端自拼
%关键词%> - 出参:查询类在 data.outputList;写操作仅回 success,不回填 id
4. 前端调用约定
- lib 文件位置:<如 src/lib/xxxTableApi.ts>
- 字段映射:<后端列名 ↔ 前端模型名>
- 写后刷新 / 跨表级联顺序等约定
5. 变更记录
- 日期 + 改动摘要
## 跨表关联与级联更新(常见范式)
业务里常出现「主表某个字段引用另一张字典表」的情况(例如:业务表 A 有一个分类字段,值来自字典表 B 的名称)。改字典表名称时,必须**级联更新**业务表里所有引用它的行,否则出现脏数据。
### 范式
1. 为级联操作单独建一个 **UPDATE 类 SQL 操作 API**(不要复用普通更新 API),形如:
```sql
UPDATE custom_table_{A的表ID}
SET {关联字段} = {{newName}}
WHERE {关联字段} = {{oldName}}
前端「改名」流程要保证先级联、再改字典表的顺序:
1) 调用级联 UPDATE API,把业务表里 oldName 全部改成 newName 2) 调用字典表自身的 update API,改字典记录 3) 刷新业务列表(级联生效)删除字典项同理:先级联把引用置为一个约定的默认值(如
"default"或「未指定」),再删字典记录。
跨表没有外键约束,一致性完全靠应用层按上述顺序保证。把级联 API 和调用顺序登记进
.project.md,避免下次遗漏。
前端 lib 层最小模板(TypeScript)
新建业务时,前端 src/lib/xxxTableApi.ts 按下面骨架填写即可,已内含:端点 token 映射、统一外壳解析、outputList 取值、写后刷新约定、原始行→前端模型映射。字段全部替换为你的实际表结构。
/**
* 业务表 API 封装(基于平台数据表 SQL 操作 API,本质是工作流)
* 调用路径:POST /api/page/w/{token}(同源,浏览器自带登录态)
*/
// 每个建好的 SQL 操作 API(工作流)一个 token,从 .project.md 取,不要凭记忆
const API_ENDPOINTS = {
getAll: '<<token>>',
getById: '<<token>>',
add: '<<token>>',
update: '<<token>>',
remove: '<<token>>',
// 模糊查询用 LIKE 占位符 ${query} 的那个 API
search: '<<token>>',
} as const;
/** 前端统一模型(字段名按你的业务命名,与后端列名解耦) */
export interface YourItem {
id: string;
// ... 你的业务字段
createdAt: string;
updatedAt: string;
}
/** 后端原始行(字段名 = SQL 列名 = 建表 fieldName) */
interface RawRow {
id: number;
// ... 与 SQL SELECT 列一一对应
created?: string;
modified?: string;
}
/** 统一外壳 */
interface ApiEnvelope<T> {
success: boolean;
message: string;
data?: { outputList: T[]; rowNum: number };
}
const API_PATH_PREFIX = '/api/page/w';
/** 统一调用:解析外壳,失败抛错,成功返回 data */
async function callAPI<T>(
token: string,
params: Record<string, unknown> = {}
): Promise<T> {
const res = await fetch(`${API_PATH_PREFIX}/${token}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const result: ApiEnvelope<T> = await res.json();
if (!result.success) throw new Error(result.message || 'API 调用失败');
return (result.data ?? ({} as T));
}
/** 后端原始行 -> 前端模型(字段映射集中在此,勿散落到组件) */
function toItem(r: RawRow): YourItem {
return {
id: String(r.id),
// ... 字段映射
createdAt: r.created ?? '',
updatedAt: r.modified ?? '',
};
}
// ===== 查询类:读 data.outputList =====
export async function getAll(): Promise<YourItem[]> {
const data = await callAPI<{ outputList: RawRow[] }>(API_ENDPOINTS.getAll);
return (data.outputList ?? []).map(toItem);
}
export async function search(query: string): Promise<YourItem[]> {
// 后端用普通参数占位符 LIKE {{query}},平台不自动包 %,前端自拼 %query%
const data = await callAPI<{ outputList: RawRow[] }>(API_ENDPOINTS.search, { query: `%${query}%` });
return (data.outputList ?? []).map(toItem);
}
// ===== 写操作类:通常只回 success,新增后整表刷新 =====
export async function add(input: Partial<YourItem>): Promise<void> {
await callAPI(API_ENDPOINTS.add, {
/* 把 input 映射成后端列名参数 */
});
// 注意:写操作不回填新 id,调用方 add 后应重新 getAll() 刷新
}
export async function update(id: string, input: Partial<YourItem>): Promise<void> {
await callAPI(API_ENDPOINTS.update, { id, /* ...列名参数 */ });
}
export async function remove(id: string): Promise<void> {
await callAPI(API_ENDPOINTS.remove, { id });
}
调用方约定:页面组件
await add(...)之后立即await getAll()重新拉取列表,不要依赖写操作的返回值渲染单条。
Authentication
The script reads authentication from environment variables:
| Variable | Description |
|---|---|
PLATFORM_BASE_URL |
Platform API base URL (e.g. https://xxx) |
SANDBOX_ACCESS_KEY |
Sandbox access key for API calls |
SANDBOX_ID |
Sandbox identifier (optional; sent as X-Sandbox-Id when available) |
DEV_PROJECT_ID |
当前项目 ID(projectId),table-sql-new / table-sql-update 的 --project-id 参数从这里取值 |
DEV_SPACE_ID |
当前项目所在空间 ID(spaceId),add-table / list-tables 的 spaceId 由脚本从此变量自动读取并注入请求体,确保表建在/查在项目空间而非个人空间 |
Requests use:
Authorization: Bearer $SANDBOX_ACCESS_KEYX-Sandbox-Id: $SANDBOX_ID(when set)
⚠️ 获取 projectId(禁止创建测试工作流)
table-sql-new 和 table-sql-update 需要 projectId 参数。直接从环境变量 DEV_PROJECT_ID 读取,不要用其他方式获取。
🚫 绝对禁止创建测试 SQL 工作流(如
SELECT 1)来探测 projectId 或验证 API 连通性。
- 每个通过
table-sql-new创建的 SQL API 都会实例化为一个永久工作流,平台没有删除接口,测试工作流会永久残留在项目中。- 正确做法:
projectId = os.environ.get('DEV_PROJECT_ID'),直接使用。
⚠️ 获取 spaceId(禁止使用个人空间)
add-table 和 list-tables 需要 spaceId 参数。脚本已自动从环境变量 DEV_SPACE_ID 读取并注入请求体,无需也禁止手动指定。
🚫 绝对禁止把表建到/查到用户个人空间。
- 平台后端在
spaceId为空时,会回退到调用者的个人空间 ID,而个人空间不是项目所在空间——建到个人空间的表不会出现在项目里,前端 SQL API 也读不到。- 正确做法:保证沙箱环境注入了
DEV_SPACE_ID(项目空间 ID),脚本会自动带上;不要通过修改脚本、手动构造请求体等方式绕过。- 排错第一反应:表建完后在前端/列表里看不到,先确认
DEV_SPACE_ID是否正确指向项目空间,而不是个人空间。
Python Script
The client script is located here:
datatable-for-page-api/scripts/datatable_for_page_api.py
Base URL
Table Definition endpoints are called under:
$PLATFORM_BASE_URL/api/v1/4sandbox/compose/db/table/...
Table SQL API endpoints are called under:
$PLATFORM_BASE_URL/api/v1/4sandbox/table/sql/...
For sandbox calls, spaceId in table-add and table-list requests is sourced automatically from the DEV_SPACE_ID environment variable by the script (see below). Never omit or override it — if spaceId is missing the backend falls back to the caller's personal space, which is NOT the project space and will create/query tables in the wrong place.
Supported Endpoints
Table Definition(表结构管理)
| CLI Command | Method | Endpoint | Description |
|---|---|---|---|
add-table |
POST | /add |
Create a new table definition(新增表定义) |
update-table-name |
POST | /updateTableName |
Update table name / description / icon(更新表名称和描述) |
update-table-definition |
POST | /updateTableDefinition |
Update table field definitions(更新表字段定义) |
delete-table |
POST | /delete/{id} |
Delete a table definition(删除表定义) |
list-tables |
POST | /list |
Query table definitions paginated(查询表定义列表) |
get-table |
GET | /detailById?id= |
Get table definition detail(查询表定义详情) |
exist-table-data |
GET | /existTableData?tableId= |
Check if table has business data(查询表是否有数据) |
copy-table |
POST | /copyTableDefinition?tableId= |
Copy a table structure(复制表结构) |
Table SQL API(数据表SQL操作API管理)
| CLI Command | Method | Endpoint | Description |
|---|---|---|---|
table-sql-new |
POST | /api/v1/4sandbox/table/sql/new |
Create a new SQL-based table operation API(创建数据表SQL操作API) |
table-sql-update |
POST | /api/v1/4sandbox/table/sql/update |
Update an existing SQL-based table operation API(更新数据表SQL操作API) |
Usage
python scripts/datatable_for_page_api.py --help
Table Definition Examples
# Create a new table(创建表)
python scripts/datatable_for_page_api.py add-table --name "Users" --description "User information table"
# List tables(查询表列表)
python scripts/datatable_for_page_api.py list-tables --page-no 1 --page-size 20
# Get table definition detail(查看表结构详情)
python scripts/datatable_for_page_api.py get-table --table-id 123
# Update table name and description(修改表名称和描述)
python scripts/datatable_for_page_api.py update-table-name --id 123 --name "Users_v2" --description "Updated user table"
# Update table field definitions(修改表字段定义)
# ⚠️ fieldType 必须是数字枚举(1=VARCHAR,2=INT,5=DATETIME,6=BIGINT,7=TEXT),不能传 "VARCHAR"/"INT" 字符串
# ⚠️ 注释字段 key 是 fieldDescription
# ⚠️ 必须传完整 fieldList(系统字段+自定义字段),详见上文「⚠️ update-table-definition 关键约束」
python scripts/datatable_for_page_api.py update-table-definition --id 123 --field-list '[{"fieldName":"name","fieldType":1,"fieldStrLen":255,"fieldDescription":"user name","nullableFlag":true,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":8,"systemFieldFlag":false},{"fieldName":"age","fieldType":2,"fieldStrLen":null,"fieldDescription":"user age","nullableFlag":true,"defaultValue":null,"uniqueFlag":false,"enabledFlag":true,"sortIndex":9,"systemFieldFlag":false}]'
# Copy a table(复制表)
python scripts/datatable_for_page_api.py copy-table --table-id 123
# Check if table has data(检查表是否有数据)
python scripts/datatable_for_page_api.py exist-table-data --table-id 123
# Delete a table(删除表)
python scripts/datatable_for_page_api.py delete-table --id 123
Table SQL API Examples
⚠️ SQL 语句里的表名必须用
get-table返回的dorisTable(物理表名,形如custom_table_123),不能用建表时的表名(如"用户表")。 占位符:{{var}}普通参数(LIKE 也用它,前端自拼%关键词%)。
# Create a new SQL table operation API(创建数据表SQL操作API)
# 注意:FROM 后面是 dorisTable 物理表名 custom_table_123,不是表名"用户表"
python scripts/datatable_for_page_api.py table-sql-new \
--project-id "100" \
--table-id 123 \
--api-name "queryUsers" \
--description "Query users by name" \
--sql "SELECT * FROM custom_table_123 WHERE name = {{name}}" \
--args '[{"name":"name","description":"user name","require":true}]'
# Update an existing SQL table operation API(更新数据表SQL操作API)
python scripts/datatable_for_page_api.py table-sql-update \
--project-id "100" \
--api-id 456 \
--api-name "queryUsersV2" \
--description "Query users by name and age" \
--sql "SELECT * FROM custom_table_123 WHERE name = {{name}} AND age > {{age}}" \
--args '[{"name":"name","description":"user name","require":true},{"name":"age","description":"min age","require":false}]'