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 生成用)。
344 lines
18 KiB
JSON
344 lines
18 KiB
JSON
{
|
||
"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\nstring:token 填字面量如 '2024-01-01'\r\nfunc:token 填内置函数名 UserID|UserUuid|UserRolesUuid|UserPlatform|UserSaaS\r\nparam:token 填请求参数路径如 body.status\r\nsql:token 填原始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.price,isExpr 保持默认 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 作用于子查询 WHERE;inner/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 / right:SQL 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 / right:SQL JOIN,要求关联资源与主资源在同一数据库连接,将关联字段合并到主查询行。\rhasOne / hasMany:独立子查询,支持跨数据库连接,结果聚合为 JSON 字段(hasOne 为单对象,hasMany 为数组)。\r跨库关联必须使用 hasOne 或 hasMany,不可使用 JOIN 类型。"
|
||
},
|
||
"resource": {
|
||
"type": "string",
|
||
"title": "主资源",
|
||
"description": "主资源编码(resource_code),作为本次查询的根上下文,relations 中的关联资源均以此为基础展开"
|
||
}
|
||
},
|
||
"required": [
|
||
"fields",
|
||
"resource"
|
||
]
|
||
},
|
||
"annotations": {}
|
||
}
|
||
]
|
||
} |