Files
contracts/base/res_api_param_test1.json
T
what 9446571363 重构: base 包资源核心类型迁移到 req/resx,新增 res_watcher/res_api_param
base/resource.go、resource_hooks.go、resource_test.go、query_field.go 删除,ResField 等具体实现搬到 req/resx(见 res_field.go 里的类型别名)。res_listener.go 替换成 res_watcher.go,对应资源变更监听概念改名。新增 res_api_param.go 及配套测试(ResApi 参数建模,给 MCP tool 的 JSON Schema 生成用)。
2026-07-22 09:13:05 +08:00

344 lines
18 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"tools": [
{
"name": "res-query",
"description": "Query records with filters, joins, aggregates, ordering, and pagination.\rThe main resource and each hasOne/hasMany relation are independent query contexts; inner/left/right are JOINs within their parent context.\rTop-level conditions / groupBy / orderBy / limit / offset apply to the main resource SQL. Each relation has its own conditions / groupBy / orderBy / limit that apply to that relation's SQL.\rIMPORTANT:\r(1) All field codes MUST come from res-schema results already in this conversation — never guess or infer field names.\r(2) Fields belonging to a hasOne/hasMany context must use object form with codeResource set to that relation's code.\r(3) Call res-schema first if the resource schema has not been fetched yet.",
"inputSchema": {
"type": "object",
"properties": {
"conditions": {
"type": "object",
"properties": {
"children": {
"type": "array",
"items": {
"$ref": "#/properties/conditions"
},
"title": "子条件",
"description": "子条件节点,递归结构"
},
"exprs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"title": "字段编码",
"description": "必须来自 res-schema 返回的字段列表,禁止猜测字段名"
},
"fieldResource": {
"type": "string",
"title": "所属资源",
"description": "字段所属资源标识,取值为主资源编码或当前查询上下文(conditions 所在层级)对应的 relations[].code"
},
"fieldSqlFunc": {
"type": "string",
"title": "列SQL函数",
"description": "对列应用 SQL 函数后再参与比较,拼接为 {func}({fieldResource}.{field}) {operator} {token}。\r\n支持 SQL-92 / SQL:1999 / SQL:2003 标准函数及数据库方言函数,如 DATE、UPPER、ROUND。\r\n需要第二参数的函数(如 ROUND、CAST)配合 fieldSqlFuncParam 使用。"
},
"fieldSqlFuncParam": {
"type": "string",
"title": "列SQL函数参数",
"description": "fieldSqlFunc 的附加参数,按函数类型用途不同:\r\r通用函数(有 param 时):{func}({fieldResource}.{field}, {fieldSqlFuncParam}) {operator} {token}\r 示例:ROUND(col, 2) → fieldSqlFuncParam=\\\"2\\\"\r SUBSTRING(col, 1, 10) → fieldSqlFuncParam=\\\"1, 10\\\""
},
"ignoreEmptyParam": {
"type": "boolean",
"title": "忽略空参数",
"description": "当 tokenType=param 且请求参数值为空(空字符串或 null)时,跳过该条件不生成 SQL。用于实现可选过滤项",
"default": false
},
"operator": {
"type": "string",
"title": "运算符",
"description": "标准 SQL 比较运算符:\r\n= / != / > / >= / < / <=\r\nLIKE:模糊匹配(%keyword%\r\nIN:包含,value 逗号分隔多值\r\nIS NULL / IS NOT NULL:空值判断,无需 value\r\nREGEXP:正则匹配",
"default": "="
},
"token": {
"type": "string",
"title": "比较值",
"description": "比较目标,内容由 tokenType 决定。operator 为 IS NULL/IS NOT NULL 时可省略"
},
"tokenType": {
"type": "string",
"title": "比较值类型",
"description": "先选类型再填 token\r\nstringtoken 填字面量如 '2024-01-01'\r\nfunctoken 填内置函数名 UserID|UserUuid|UserRolesUuid|UserPlatform|UserSaaS\r\nparamtoken 填请求参数路径如 body.status\r\nsqltoken 填原始SQL如 CURRENT_DATE",
"default": "string",
"enum": [
"string",
"func"
]
}
},
"title": "条件项",
"description": "单条比较表达式,生成 [{fieldSqlFunc}(]{fieldResource}.{field}[)] {operator} {token} 片段",
"required": [
"field",
"operator"
]
},
"title": "条件表达式列表",
"description": "当前层的叶子比较列表,每项生成一个 {fieldResource}.{field} {operator} {token} 片段,同层多项以 type 连接"
},
"type": {
"type": "string",
"title": "逻辑连接符",
"description": "当前节点的逻辑运算符,将 exprs 各项与 children 各组以 AND 或 OR 连接",
"default": "and",
"enum": [
"and",
"or"
]
}
},
"title": "树形查询条件",
"description": "WHERE 条件树。\rexprs 每项生成一段比较:[{fieldSqlFunc}(]{fieldResource}.{field}[)] {operator} {token},同层多项以 type(and/or) 连接;\rchildren 为同结构子节点,递归嵌套实现复杂过滤。",
"required": [
"exprs",
"type"
]
},
"fields": {
"type": "array",
"items": {
"type": "object",
"properties": {
"alias": {
"type": "string",
"title": "别名",
"description": "输出字段别名,对应 SQL AS。isExpr=true 时必填,否则结果列无法被引用;普通字段不填则默认使用 code 值"
},
"code": {
"type": "string",
"title": "字段编码",
"description": "两种互斥用法,每个对象只能选其一:\r1. 字段编码,格式为 {Resource}.{field}Resource 取值为主资源编码或 relations[].code,如 User.amount / Order.priceisExpr 保持默认 false\r2. 原始 SQL 表达式(如 COUNT(*) / SUM(amount)),必须同时设置 isExpr = true,且 alias 必填\r注意:SELECT 中混入聚合表达式与非聚合字段时,需配合 groupBy 使用,否则结果不符合预期\r重要:字段编码必须来自 res-schema 返回的字段列表,禁止猜测或推断字段名"
},
"codeResource": {
"type": "string",
"title": "所属资源",
"description": "字段所属的表标识,取值为主资源编码或 relations[].code"
},
"dataType": {
"type": "string",
"title": "数据类型",
"description": "指定字段的返回数据类型,影响序列化方式;不填则由资源字段定义决定",
"default": "string",
"enum": [
"string",
"bool",
"number",
"array",
"json",
"integer",
"float"
]
},
"isExpr": {
"type": "boolean",
"title": "是否表达式",
"description": "设为 true 时,code 内容作为原始 SQL 表达式拼入 SELECT(如聚合函数 COUNT(*) / SUM(amount)),而非普通字段编码。isExpr=true 时 alias 为必填项",
"default": false
}
},
"title": "资源字段",
"description": "结构化字段,支持指定所属资源、输出别名、聚合表达式及数据类型",
"required": [
"code",
"codeResource"
]
},
"title": "查询字段",
"description": "SELECT 字段列表,涵盖所有查询上下文(主资源 + 所有 hasOne/hasMany),通过 codeResource 路由到对应的独立 SQL。不传则返回所有字段。\r主资源和每个 hasOne/hasMany 各是一个独立查询上下文,inner/left/right 只是其所在上下文内的 JOIN。\r仅查询聚合结果(如 COUNT(*) / SUM(amount))时,fields 只传聚合字段,不要混入普通字段,除非同时提供 groupBy。\r重要:所有字段编码必须先通过 res-schema 确认,禁止凭名称语义猜测"
},
"groupBy": {
"type": "array",
"items": {
"oneOf": [
{
"type": "string",
"title": "字段编码",
"description": "格式必须为 {Resource}.{field},如 User.status。\r{Resource} 取值为主资源编码或 relations[].code"
},
{
"type": "object",
"properties": {
"expr": {
"type": "string",
"title": "表达式",
"description": "type=field 时填 {Resource}.{field}(如 User.status\rtype=sql 时填原始 SQL 表达式(如 DATE(created_at)"
},
"type": {
"type": "string",
"title": "表达式类型",
"description": "field:按资源字段分组,expr 填 {Resource}.{field},如 User.status\rsql:按原始 SQL 表达式分组,expr 填任意合法 SQL,如 DATE(created_at)",
"default": "sql",
"enum": [
"field",
"sql"
]
}
},
"title": "分组表达式",
"description": "结构化分组项,type=field 用于资源字段,type=sql 用于原始 SQL 表达式",
"required": [
"expr",
"type"
]
}
]
},
"title": "分组规则",
"description": "GROUP BY 列表,配合 fields 中的聚合表达式使用。\r字段必须带资源前缀({Resource}.{field});聚合函数(COUNT / SUM 等)放在 fields 中,不属于此处"
},
"limit": {
"type": "integer",
"title": "每页条数",
"description": "当前查询上下文返回的最大记录数(顶层时限制主资源结果,relations 内时限制该关联结果)",
"default": 30
},
"offset": {
"type": "integer",
"title": "偏移量",
"description": "主资源查询跳过的记录数,仅顶层有效,relations 内不支持",
"default": 0
},
"orderBy": {
"type": "array",
"items": {
"oneOf": [
{
"type": "string",
"title": "字段编码",
"description": "格式必须为 {Resource}.{field},如 User.created_at,默认升序(ASC)。\r需要降序或使用 SQL 表达式时使用对象形式"
},
{
"type": "object",
"properties": {
"direction": {
"type": "string",
"title": "排序方向",
"default": "asc",
"enum": [
"asc",
"desc"
]
},
"expr": {
"type": "string",
"title": "表达式",
"description": "type=field 时填 {Resource}.{field}(如 User.created_at);type=sql 时填原始 SQL 表达式(如 COUNT(*) / DATE(created_at)"
},
"type": {
"type": "string",
"title": "表达式类型",
"description": "field:按资源字段排序,expr 填 {Resource}.{field},如 User.created_at\rsql:按原始 SQL 表达式排序,expr 填任意合法 SQL,如 COUNT(*) / DATE(created_at)",
"default": "field",
"enum": [
"field",
"sql"
]
}
},
"title": "排序表达式",
"description": "结构化排序项,type=field 用于资源字段,type=sql 用于原始 SQL 表达式",
"required": [
"type",
"expr"
]
}
]
},
"title": "排序规则",
"description": "ORDER BY 列表,多项按顺序依次应用。\r字段必须带资源前缀({Resource}.{field});需要降序或 SQL 表达式排序时使用对象形式"
},
"relations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"actuallyField": {
"type": "string",
"title": "实际资源字段",
"description": "目标资源(code)参与 ON 条件的字段"
},
"actuallyResource": {
"type": "string",
"title": "实际资源",
"description": "被关联的目标资源编码(相当于 SQL 表名)。JOIN 拼接为:{type} JOIN {actuallyResource} AS {code} ON {code}.{actuallyField} = {relationResource}.{relationField}"
},
"code": {
"type": "string",
"title": "关联标识",
"description": "关联唯一标识,同时作为别名:JOIN 时为表别名(AS code),子查询时为结果 JSON 字段的键名。\r通常与 actuallyResource 保持一致;仅当多个关联引用同一资源导致冲突时,才需要重命名加以区分"
},
"conditions": {
"$ref": "#/properties/conditions",
"description": "该关联的过滤条件,结构与顶层 conditions 相同。hasOne/hasMany 作用于子查询 WHEREinner/left/right 作用于 JOIN ON 或主查询 WHERE"
},
"groupBy": {
"$ref": "#/properties/groupBy",
"description": "该关联的 GROUP BY,仅 hasOne/hasMany 子查询生效,结构与顶层 groupBy 相同"
},
"limit": {
"$ref": "#/properties/limit",
"description": "该关联的最大返回条数,仅 hasOne/hasMany 子查询生效,结构与顶层 limit 相同"
},
"name": {
"type": "string",
"title": "关联名称",
"description": "关联的显示名称"
},
"orderBy": {
"$ref": "#/properties/orderBy",
"description": "该关联的 ORDER BY,仅 hasOne/hasMany 子查询生效,结构与顶层 orderBy 相同"
},
"relationField": {
"type": "string",
"title": "被关联资源字段",
"description": "ON 条件对端资源的字段"
},
"relationResource": {
"type": "string",
"title": "被关联资源",
"description": "ON 条件对端的资源编码(通常为主资源或父关联资源)"
},
"type": {
"type": "string",
"title": "关联类型",
"description": "关联模式:\r\ninner / left / rightSQL JOIN,要求与主资源同一数据库连接,将关联字段合并到主查询行\r\nhasOne:独立子查询,支持跨库,结果聚合为单个对象(result[code] = {}\r\nhasMany:独立子查询,支持跨库,结果聚合为对象数组(result[code] = [...]\r\n跨数据库连接的关联必须使用 hasOne 或 hasMany",
"enum": [
"inner",
"left",
"right",
"hasOne",
"hasMany"
]
}
},
"required": [
"actuallyField",
"actuallyResource",
"code",
"relationField",
"relationResource",
"type"
]
},
"title": "资源关联",
"description": "关联配置列表。\rinner / left / rightSQL JOIN,要求关联资源与主资源在同一数据库连接,将关联字段合并到主查询行。\rhasOne / hasMany:独立子查询,支持跨数据库连接,结果聚合为 JSON 字段(hasOne 为单对象,hasMany 为数组)。\r跨库关联必须使用 hasOne 或 hasMany,不可使用 JOIN 类型。"
},
"resource": {
"type": "string",
"title": "主资源",
"description": "主资源编码(resource_code),作为本次查询的根上下文,relations 中的关联资源均以此为基础展开"
}
},
"required": [
"fields",
"resource"
]
},
"annotations": {}
}
]
}