openapi: 3.1.0
info:
  title: TenantPilot Baseline Compare RBAC Planning Contract
  version: 0.1.0
  description: |
    Planning artifact for Spec 128. Documents the existing workflow surfaces that
    will gain Intune RBAC Role Definition baseline support.
servers:
  - url: https://tenantpilot.local
paths:
  /workspaces/{workspaceId}/baseline-profiles/{profileId}:
    patch:
      summary: Update baseline profile scope to include baseline-supported foundations
      operationId: updateBaselineProfileScope
      parameters:
        - $ref: '#/components/parameters/WorkspaceId'
        - $ref: '#/components/parameters/ProfileId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BaselineProfileScopeUpdate'
      responses:
        '200':
          description: Baseline profile updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaselineProfile'
        '403':
          description: In-scope member lacks workspace baseline management capability
        '404':
          description: Workspace or profile is outside authorized scope

  /workspaces/{workspaceId}/baseline-profiles/{profileId}/captures:
    post:
      summary: Start baseline capture for the selected baseline profile
      operationId: startBaselineCapture
      parameters:
        - $ref: '#/components/parameters/WorkspaceId'
        - $ref: '#/components/parameters/ProfileId'
      responses:
        '202':
          description: Baseline capture accepted and queued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationRunQueued'
        '403':
          description: In-scope member lacks workspace baseline management capability
        '404':
          description: Workspace or profile is outside authorized scope

  /tenants/{tenantId}/baseline-compares:
    post:
      summary: Start baseline compare for the tenant using the assigned baseline profile
      operationId: startBaselineCompare
      parameters:
        - $ref: '#/components/parameters/TenantId'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                baseline_snapshot_id:
                  type: integer
                  minimum: 1
      responses:
        '202':
          description: Baseline compare accepted and queued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationRunQueued'
        '403':
          description: In-scope member lacks tenant sync capability
        '404':
          description: Tenant is outside authorized scope

  /tenants/{tenantId}/baseline-compares/{runId}:
    get:
      summary: Read baseline compare run detail including RBAC Role Definition summary
      operationId: getBaselineCompareRun
      parameters:
        - $ref: '#/components/parameters/TenantId'
        - $ref: '#/components/parameters/RunId'
      responses:
        '200':
          description: Compare run detail
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaselineCompareRun'
        '403':
          description: In-scope member lacks required capability
        '404':
          description: Tenant or run is outside authorized scope

  /tenants/{tenantId}/findings:
    get:
      summary: List tenant findings, including baseline.compare RBAC Role Definition drift
      operationId: listTenantFindings
      parameters:
        - $ref: '#/components/parameters/TenantId'
        - name: source
          in: query
          schema:
            type: string
            enum: [baseline.compare]
        - name: policy_type
          in: query
          schema:
            type: string
            enum: [intuneRoleDefinition]
      responses:
        '200':
          description: Findings list
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Finding'
        '403':
          description: In-scope member lacks findings-view capability
        '404':
          description: Tenant is outside authorized scope

components:
  parameters:
    WorkspaceId:
      name: workspaceId
      in: path
      required: true
      schema:
        type: integer
        minimum: 1
    ProfileId:
      name: profileId
      in: path
      required: true
      schema:
        type: integer
        minimum: 1
    TenantId:
      name: tenantId
      in: path
      required: true
      schema:
        type: integer
        minimum: 1
    RunId:
      name: runId
      in: path
      required: true
      schema:
        type: integer
        minimum: 1

  schemas:
    BaselineProfileScopeUpdate:
      type: object
      required: [scope_jsonb]
      properties:
        scope_jsonb:
          type: object
          properties:
            policy_types:
              type: array
              items:
                type: string
            foundation_types:
              type: array
              items:
                type: string
                enum: [intuneRoleDefinition]

    BaselineProfile:
      type: object
      required: [id, scope_jsonb]
      properties:
        id:
          type: integer
        scope_jsonb:
          type: object
          properties:
            policy_types:
              type: array
              items:
                type: string
            foundation_types:
              type: array
              items:
                type: string

    OperationRunQueued:
      type: object
      required: [id, type, status]
      properties:
        id:
          type: integer
        type:
          type: string
          enum: [baseline_capture, baseline_compare]
        status:
          type: string
          enum: [queued, running]

    BaselineCompareRun:
      type: object
      required: [id, type, status, context]
      properties:
        id:
          type: integer
        type:
          type: string
          enum: [baseline_compare]
        status:
          type: string
        outcome:
          type: string
        context:
          type: object
          properties:
            baseline_compare:
              type: object
              properties:
                reason_code:
                  type: string
                rbac_role_definitions:
                  $ref: '#/components/schemas/RbacRoleDefinitionSummary'

    RbacRoleDefinitionSummary:
      type: object
      required: [total_compared, unchanged, modified, missing, unexpected]
      properties:
        total_compared:
          type: integer
          minimum: 0
        unchanged:
          type: integer
          minimum: 0
        modified:
          type: integer
          minimum: 0
        missing:
          type: integer
          minimum: 0
        unexpected:
          type: integer
          minimum: 0

    Finding:
      type: object
      required: [id, source, severity, evidence_jsonb]
      properties:
        id:
          type: integer
        source:
          type: string
          enum: [baseline.compare]
        severity:
          type: string
          enum: [low, medium, high]
        evidence_jsonb:
          type: object
          properties:
            change_type:
              type: string
              enum: [modified, missing, unexpected]
            summary:
              type: object
              properties:
                kind:
                  type: string
                  enum: [intune_rbac_role_definition]
            baseline:
              type: object
            current:
              type: object