openapi: 3.0.3
info:
  title: 元数据职责分层 API
  description: |
    提供元数据字段职责分层配置、槽位定义管理及按角色查询能力。
    
    ## 字段角色定义
    - `resource_filter`: 资源过滤角色，用于 KB 文档检索
    - `slot`: 运行时槽位角色，用于对话信息收集
    - `prompt_var`: 提示词变量角色，用于 Prompt 注入
    - `routing_signal`: 路由信号角色，用于意图路由判断
  version: 0.1.0
  x-contract-level: L1
  contact:
    name: AI Robot Core Team

servers:
  - url: /api
    description: API Server

tags:
  - name: MetadataSchema
    description: 元数据字段定义管理（扩展 field_roles）
  - name: SlotDefinition
    description: 槽位定义管理
  - name: RuntimeSlot
    description: 运行时槽位查询

paths:
  /admin/metadata-schemas:
    get:
      summary: 获取元数据字段定义列表
      description: |-
        [AC-MRS-06] 支持按状态、范围、角色过滤查询元数据字段定义列表。
      operationId: listMetadataSchemas
      tags:
        - MetadataSchema
      parameters:
        - name: status
          in: query
          description: 字段状态过滤
          schema:
            $ref: '#/components/schemas/MetadataFieldStatus'
        - name: scope
          in: query
          description: 适用范围过滤
          schema:
            $ref: '#/components/schemas/MetadataScope'
        - name: field_role
          in: query
          description: 字段角色过滤
          schema:
            $ref: '#/components/schemas/FieldRole'
        - name: tenant_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: 成功返回字段定义列表
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MetadataFieldDefinition'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      summary: 创建元数据字段定义
      description: |-
        [AC-MRS-01][AC-MRS-02][AC-MRS-03] 创建新的元数据字段定义，支持 field_roles 多选配置。
      operationId: createMetadataSchema
      tags:
        - MetadataSchema
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MetadataFieldDefinitionCreate'
      responses:
        '201':
          description: 创建成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetadataFieldDefinition'
        '400':
          $ref: '#/components/responses/BadRequest'
        '409':
          description: field_key 已存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /admin/metadata-schemas/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    get:
      summary: 获取单个元数据字段定义
      operationId: getMetadataSchema
      tags:
        - MetadataSchema
      responses:
        '200':
          description: 成功返回字段定义
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetadataFieldDefinition'
        '404':
          $ref: '#/components/responses/NotFound'

    put:
      summary: 更新元数据字段定义
      description: |-
        [AC-MRS-01] 更新元数据字段定义，支持修改 field_roles。
      operationId: updateMetadataSchema
      tags:
        - MetadataSchema
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MetadataFieldDefinitionUpdate'
      responses:
        '200':
          description: 更新成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetadataFieldDefinition'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'

    delete:
      summary: 删除元数据字段定义
      description: |-
        [AC-MRS-16] 删除元数据字段定义，无需考虑历史数据兼容性。
      operationId: deleteMetadataSchema
      tags:
        - MetadataSchema
      responses:
        '204':
          description: 删除成功
        '404':
          $ref: '#/components/responses/NotFound'

  /admin/metadata-schemas/by-role:
    get:
      summary: 按角色查询元数据字段定义
      description: |-
        [AC-MRS-04][AC-MRS-05] 按指定角色查询所有包含该角色的活跃字段定义。
      operationId: getMetadataSchemasByRole
      tags:
        - MetadataSchema
      parameters:
        - name: role
          in: query
          required: true
          description: 字段角色
          schema:
            $ref: '#/components/schemas/FieldRole'
        - name: tenant_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: include_deprecated
          in: query
          description: 是否包含已废弃字段
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: 成功返回字段定义列表
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MetadataFieldDefinition'
        '400':
          description: 无效的角色参数
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error_code: INVALID_ROLE
                message: "Invalid role 'invalid_role'. Valid roles are: resource_filter, slot, prompt_var, routing_signal"

  /admin/slot-definitions:
    get:
      summary: 获取槽位定义列表
      operationId: listSlotDefinitions
      tags:
        - SlotDefinition
      parameters:
        - name: tenant_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: required
          in: query
          description: 是否必填槽位过滤
          schema:
            type: boolean
      responses:
        '200':
          description: 成功返回槽位定义列表
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SlotDefinition'

    post:
      summary: 创建槽位定义
      description: |-
        [AC-MRS-07][AC-MRS-08] 创建新的槽位定义，可关联已有元数据字段。
      operationId: createSlotDefinition
      tags:
        - SlotDefinition
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SlotDefinitionCreate'
      responses:
        '201':
          description: 创建成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SlotDefinition'
        '400':
          $ref: '#/components/responses/BadRequest'

  /admin/slot-definitions/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid

    get:
      summary: 获取单个槽位定义
      operationId: getSlotDefinition
      tags:
        - SlotDefinition
      responses:
        '200':
          description: 成功返回槽位定义
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SlotDefinition'
        '404':
          $ref: '#/components/responses/NotFound'

    put:
      summary: 更新槽位定义
      operationId: updateSlotDefinition
      tags:
        - SlotDefinition
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SlotDefinitionUpdate'
      responses:
        '200':
          description: 更新成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SlotDefinition'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'

    delete:
      summary: 删除槽位定义
      description: |-
        [AC-MRS-16] 删除槽位定义，无需考虑历史数据兼容性。
      operationId: deleteSlotDefinition
      tags:
        - SlotDefinition
      responses:
        '204':
          description: 删除成功
        '404':
          $ref: '#/components/responses/NotFound'

  /mid/slots/by-role:
    get:
      summary: 运行时按角色获取槽位定义
      description: |-
        [AC-MRS-10] 运行时接口，按角色获取槽位定义及关联的元数据字段信息。
      operationId: getSlotsByRole
      tags:
        - RuntimeSlot
      parameters:
        - name: role
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/FieldRole'
        - name: tenant_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: 成功返回槽位定义列表
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SlotDefinitionWithField'
        '400':
          $ref: '#/components/responses/BadRequest'

  /mid/slots/{slot_key}:
    parameters:
      - name: slot_key
        in: path
        required: true
        schema:
          type: string

    get:
      summary: 获取运行时槽位值
      description: |-
        [AC-MRS-09] 获取指定槽位的运行时值，包含来源、置信度、更新时间。
      operationId: getSlotValue
      tags:
        - RuntimeSlot
      parameters:
        - name: tenant_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: user_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
        - name: session_id
          in: query
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: 成功返回槽位值
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RuntimeSlotValue'
        '404':
          description: 槽位不存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

components:
  schemas:
    FieldRole:
      type: string
      enum:
        - resource_filter
        - slot
        - prompt_var
        - routing_signal
      description: |
        字段角色类型：
        - resource_filter: 资源过滤角色
        - slot: 运行时槽位角色
        - prompt_var: 提示词变量角色
        - routing_signal: 路由信号角色

    MetadataFieldStatus:
      type: string
      enum:
        - draft
        - active
        - deprecated

    MetadataScope:
      type: string
      enum:
        - kb_document
        - intent_rule
        - script_flow
        - prompt_template

    MetadataFieldType:
      type: string
      enum:
        - string
        - number
        - boolean
        - enum
        - array_enum

    MetadataFieldDefinition:
      type: object
      required:
        - id
        - tenant_id
        - field_key
        - label
        - type
        - status
        - field_roles
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        field_key:
          type: string
          pattern: '^[a-z][a-z0-9_]*$'
          description: 字段键名，仅允许小写字母数字下划线
        label:
          type: string
          description: 显示名称
        type:
          $ref: '#/components/schemas/MetadataFieldType'
        required:
          type: boolean
          default: false
        options:
          type: array
          items:
            type: string
          description: 选项列表（enum/array_enum 类型必填）
        default_value:
          description: 默认值
        scope:
          type: array
          items:
            $ref: '#/components/schemas/MetadataScope'
          description: 适用范围
        is_filterable:
          type: boolean
          default: false
        is_rank_feature:
          type: boolean
          default: false
        field_roles:
          type: array
          items:
            $ref: '#/components/schemas/FieldRole'
          description: 字段角色列表
        status:
          $ref: '#/components/schemas/MetadataFieldStatus'
        version:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    MetadataFieldDefinitionCreate:
      type: object
      required:
        - tenant_id
        - field_key
        - label
        - type
      properties:
        tenant_id:
          type: string
          format: uuid
        field_key:
          type: string
          pattern: '^[a-z][a-z0-9_]*$'
        label:
          type: string
          minLength: 1
          maxLength: 100
        type:
          $ref: '#/components/schemas/MetadataFieldType'
        required:
          type: boolean
          default: false
        options:
          type: array
          items:
            type: string
        default_value:
          type: object
        scope:
          type: array
          items:
            $ref: '#/components/schemas/MetadataScope'
        is_filterable:
          type: boolean
          default: false
        is_rank_feature:
          type: boolean
          default: false
        field_roles:
          type: array
          items:
            $ref: '#/components/schemas/FieldRole'
          description: 字段角色列表，可为空

    MetadataFieldDefinitionUpdate:
      type: object
      properties:
        label:
          type: string
          minLength: 1
          maxLength: 100
        required:
          type: boolean
        options:
          type: array
          items:
            type: string
        default_value:
          type: object
        scope:
          type: array
          items:
            $ref: '#/components/schemas/MetadataScope'
        is_filterable:
          type: boolean
        is_rank_feature:
          type: boolean
        field_roles:
          type: array
          items:
            $ref: '#/components/schemas/FieldRole'
        status:
          $ref: '#/components/schemas/MetadataFieldStatus'

    ExtractStrategy:
      type: string
      enum:
        - rule
        - llm
        - user_input
      description: |
        槽位提取策略：
        - rule: 规则提取
        - llm: LLM 推断
        - user_input: 用户输入

    SlotSource:
      type: string
      enum:
        - user_confirmed
        - rule_extracted
        - llm_inferred
        - default

    SlotDefinition:
      type: object
      required:
        - id
        - tenant_id
        - slot_key
        - type
        - required
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        slot_key:
          type: string
          pattern: '^[a-z][a-z0-9_]*$'
          description: 槽位键名
        type:
          $ref: '#/components/schemas/MetadataFieldType'
        required:
          type: boolean
          description: 是否必填槽位
        extract_strategy:
          $ref: '#/components/schemas/ExtractStrategy'
        validation_rule:
          type: string
          description: 校验规则（正则或 JSON Schema）
        ask_back_prompt:
          type: string
          description: 追问提示语模板
        default_value:
          description: 默认值
        linked_field_id:
          type: string
          format: uuid
          description: 关联的元数据字段 ID
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    SlotDefinitionCreate:
      type: object
      required:
        - tenant_id
        - slot_key
        - type
        - required
      properties:
        tenant_id:
          type: string
          format: uuid
        slot_key:
          type: string
          pattern: '^[a-z][a-z0-9_]*$'
        type:
          $ref: '#/components/schemas/MetadataFieldType'
        required:
          type: boolean
        extract_strategy:
          $ref: '#/components/schemas/ExtractStrategy'
        validation_rule:
          type: string
        ask_back_prompt:
          type: string
        default_value:
          type: object
        linked_field_id:
          type: string
          format: uuid

    SlotDefinitionUpdate:
      type: object
      properties:
        type:
          $ref: '#/components/schemas/MetadataFieldType'
        required:
          type: boolean
        extract_strategy:
          $ref: '#/components/schemas/ExtractStrategy'
        validation_rule:
          type: string
        ask_back_prompt:
          type: string
        default_value:
          type: object
        linked_field_id:
          type: string
          format: uuid

    SlotDefinitionWithField:
      type: object
      description: 槽位定义与关联字段信息
      allOf:
        - $ref: '#/components/schemas/SlotDefinition'
        - type: object
          properties:
            linked_field:
              $ref: '#/components/schemas/MetadataFieldDefinition'

    RuntimeSlotValue:
      type: object
      required:
        - key
        - value
        - source
        - confidence
      properties:
        key:
          type: string
          description: 槽位键名
        value:
          description: 槽位值
        source:
          $ref: '#/components/schemas/SlotSource'
          description: 槽位来源
        confidence:
          type: number
          format: float
          minimum: 0.0
          maximum: 1.0
          description: 置信度
        updated_at:
          type: string
          format: date-time
          description: 最后更新时间

    ErrorResponse:
      type: object
      required:
        - error_code
        - message
      properties:
        error_code:
          type: string
        message:
          type: string
        details:
          type: object
          additionalProperties: true

  responses:
    BadRequest:
      description: 请求参数错误
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error_code: BAD_REQUEST
            message: "Invalid request parameters"

    Unauthorized:
      description: 未授权
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error_code: UNAUTHORIZED
            message: "Authentication required"

    NotFound:
      description: 资源不存在
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error_code: NOT_FOUND
            message: "Resource not found"
