/api/rule:
  get:
    tags: [Rule]
    summary: List rules
    security:
      - bearerAuth: []
    parameters:
      - name: EventCode
        in: query
        schema:
          type: string
        description: Filter by event code
      - name: TestSiteID
        in: query
        schema:
          type: integer
        description: Filter by TestSiteID (returns rules linked to this test). Rules are only returned when attached to tests.
      - name: search
        in: query
        schema:
          type: string
        description: Search by rule code or name
    responses:
      '200':
        description: List of rules
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                message:
                  type: string
                data:
                  type: array
                  items:
                    $ref: '../components/schemas/rules.yaml#/RuleDef'

  post:
    tags: [Rule]
    summary: Create rule
    description: |
      Create a new rule. Rules must be linked to at least one test via TestSiteIDs.
      A single rule can be linked to multiple tests. Rules are active only when attached to tests.
    security:
      - bearerAuth: []
    requestBody:
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              RuleCode:
                type: string
                example: AUTO_SET_RESULT
              RuleName:
                type: string
                example: Automatically Set Result
              Description:
                type: string
              EventCode:
                type: string
                example: test_created
              TestSiteIDs:
                type: array
                items:
                  type: integer
                description: Array of TestSiteIDs to link this rule to (required)
                example: [1, 2, 3]
              ConditionExpr:
                type: string
                nullable: true
                description: Raw DSL expression. Compile it first and persist the compiled JSON in ConditionExprCompiled.
                example: "if(sex('M'); result_set(0.5); result_set(0.6))"
              ConditionExprCompiled:
                type: string
                nullable: true
                description: Compiled JSON payload from POST /api/rule/compile
            required: [RuleCode, RuleName, EventCode, TestSiteIDs]
    responses:
      '201':
        description: Rule created

/api/rule/{id}:
  get:
    tags: [Rule]
    summary: Get rule with linked tests
    security:
      - bearerAuth: []
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: RuleID
    responses:
      '200':
        description: Rule details with linked test sites
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                message:
                  type: string
                data:
                  $ref: '../components/schemas/rules.yaml#/RuleWithDetails'
      '404':
        description: Rule not found

  patch:
    tags: [Rule]
    summary: Update rule
    description: |
      Update a rule. TestSiteIDs can be provided to update which tests the rule is linked to.
      Tests not in the new list will be unlinked, and new tests will be linked.
      Rules are active only when attached to tests.
    security:
      - bearerAuth: []
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: RuleID
    requestBody:
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              RuleCode: { type: string }
              RuleName: { type: string }
              Description: { type: string }
              EventCode: { type: string }
              TestSiteIDs:
                type: array
                items:
                  type: integer
                description: Array of TestSiteIDs to link this rule to
              ConditionExpr: { type: string, nullable: true }
    responses:
      '200':
        description: Rule updated
      '404':
        description: Rule not found

  delete:
    tags: [Rule]
    summary: Soft delete rule
    security:
      - bearerAuth: []
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: RuleID
    responses:
      '200':
        description: Rule deleted
      '404':
        description: Rule not found

/api/rule/validate:
  post:
    tags: [Rule]
    summary: Validate/evaluate an expression
    security:
      - bearerAuth: []
    requestBody:
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              expr:
                type: string
              context:
                type: object
                additionalProperties: true
            required: [expr]
    responses:
      '200':
        description: Validation result

/api/rule/compile:
  post:
    tags: [Rule]
    summary: Compile DSL expression to engine-compatible structure
    description: |
      Compile a DSL expression to the engine-compatible JSON structure.
      Frontend calls this when user clicks "Compile" button.
      Returns compiled structure that can be saved to ConditionExprCompiled field.
    security:
      - bearerAuth: []
    requestBody:
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              expr:
                type: string
                description: Raw DSL expression
                example: "if(sex('M'); result_set(0.5); result_set(0.6))"
            required: [expr]
    responses:
      '200':
        description: Compilation successful
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: success
                data:
                  type: object
                  properties:
                    raw:
                      type: string
                      description: Original DSL expression
                    compiled:
                      type: object
                      description: Parsed structure with conditionExpr, valueExpr, then, else
                    conditionExprCompiled:
                      type: string
                      description: JSON string to save to ConditionExprCompiled field
      '400':
        description: Compilation failed (invalid syntax)
