openapi: 3.0.0
paths:
  /api/data-marts:
    post:
      operationId: DataMartController_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDataMartRequestApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateDataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new DataMart
      tags:
        - DataMarts
    get:
      operationId: DataMartController_list
      parameters:
        - name: offset
          required: false
          in: query
          description: Number of DataMarts to skip before returning results
          schema:
            example: 0
            type: number
        - name: ownerFilter
          required: false
          in: query
          description: Filter DataMarts by whether they have technical or business owners
          schema:
            enum:
              - has_owners
              - no_owners
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedDataMartsResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List all DataMarts
      tags:
        - DataMarts
  /api/data-marts/by-connector/{connectorName}:
    get:
      operationId: DataMartController_listDataMartsByConnectorName
      parameters:
        - name: connectorName
          required: true
          in: path
          description: Connector name
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List DataMarts by connector name
      tags:
        - DataMarts
  /api/data-marts/member-ownership-warnings:
    get:
      operationId: DataMartController_getMemberOwnershipWarnings
      parameters: []
      responses:
        '200':
          description: >-
            Technical-owner warnings for project members whose role makes
            ownership ineffective
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - userId
                    - warning
                  properties:
                    userId:
                      type: string
                      example: user-123
                    warning:
                      type: string
                      example: >-
                        Technical Owner — requires Technical User role to be
                        effective
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
      security:
        - bearer: []
      summary: List member ownership warnings
      tags:
        - DataMarts
  /api/data-marts/ai-helper/availability:
    get:
      description: >-
        Returns { enabled: true } when AI keys are present and metadata
        generation is available; { enabled: false } otherwise. Frontend uses
        this to decide whether to render AI-helper buttons.
      operationId: DataMartController_getAiHelperAvailability
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/DataMartAiHelperAvailabilityResponseApiDto
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Check whether the AI helper is configured on this deployment
      tags:
        - DataMarts
  /api/data-marts/{id}:
    get:
      operationId: DataMartController_get
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get a DataMart by ID
      tags:
        - DataMarts
    delete:
      operationId: DataMartController_delete
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: DataMart deleted
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Soft delete DataMart
      tags:
        - DataMarts
  /api/data-marts/{id}/definition:
    put:
      operationId: DataMartController_updateDefinition
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataMartDefinitionApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update DataMart definition
      tags:
        - DataMarts
  /api/data-marts/{id}/title:
    put:
      operationId: DataMartController_updateTitle
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataMartTitleApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update DataMart title
      tags:
        - DataMarts
  /api/data-marts/{id}/description:
    put:
      operationId: DataMartController_updateDescription
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataMartDescriptionApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update DataMart description
      tags:
        - DataMarts
  /api/data-marts/{id}/owners:
    put:
      operationId: DataMartController_updateOwners
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataMartOwnersApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update DataMart owners
      tags:
        - DataMarts
  /api/data-marts/{id}/contexts:
    put:
      description: >-
        Editors may only attach contexts they themselves are bound to. Admins
        may attach any context.
      operationId: DataMartController_updateContexts
      parameters:
        - name: id
          required: true
          in: path
          description: Data Mart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateEntityContextsRequestApiDto'
      responses:
        '200':
          description: Data Mart contexts updated
        '401':
          description: Authentication required
        '403':
          description: |-
            Caller is not allowed to attach one of the contexts

            Forbidden. Required role: Technical User
        '404':
          description: Data Mart or Context not found
      security:
        - bearer: []
      summary: Replace the contexts attached to a Data Mart
      tags:
        - DataMarts
  /api/data-marts/{id}/publish:
    put:
      operationId: DataMartController_publish
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Publish DataMart
      tags:
        - DataMarts
  /api/data-marts/{id}/manual-run:
    post:
      operationId: DataMartController_manualRun
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RunDataMartRequestApiDto'
      responses:
        '201':
          description: DataMart run created
          content:
            application/json:
              schema:
                type: object
                required:
                  - runId
                properties:
                  runId:
                    type: string
                    format: uuid
                    example: 123e4567-e89b-12d3-a456-426614174000
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Manual run DataMart
      tags:
        - DataMarts
  /api/data-marts/{id}/runs/{runId}/cancel:
    post:
      operationId: DataMartController_cancelRun
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: runId
          required: true
          in: path
          description: Run ID
          schema:
            type: string
      responses:
        '204':
          description: DataMart run cancelled
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Cancel a DataMart run
      tags:
        - DataMarts
  /api/data-marts/{id}/validate-definition:
    post:
      operationId: DataMartController_validate
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartValidationResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Validate DataMart definition
      tags:
        - DataMarts
  /api/data-marts/{id}/schema:
    put:
      operationId: DataMartController_updateSchema
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataMartSchemaApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update DataMart schema
      tags:
        - DataMarts
  /api/data-marts/{id}/blended-fields-config:
    put:
      operationId: DataMartController_updateBlendedFieldsConfig
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateBlendedFieldsConfigApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update DataMart blended fields config
      tags:
        - DataMarts
  /api/data-marts/{id}/runs:
    get:
      operationId: DataMartController_getRunHistory
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: limit
          required: false
          in: query
          description: Maximum number of runs to return
          schema:
            example: 20
            type: number
        - name: offset
          required: false
          in: query
          description: Number of runs to skip before returning results
          schema:
            example: 0
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartRunsResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get DataMart run history
      tags:
        - DataMarts
  /api/data-marts/{id}/runs/{runId}:
    get:
      operationId: DataMartController_getRunById
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: runId
          required: true
          in: path
          description: Run ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataMartRunResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get DataMart run by ID
      tags:
        - DataMarts
  /api/data-marts/health-status:
    post:
      operationId: DataMartController_getBatchHealthStatus
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchDataMartHealthStatusRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchDataMartHealthStatusResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Batch get DataMart health status
      tags:
        - DataMarts
  /api/data-marts/{id}/availability:
    put:
      operationId: DataMartController_updateAvailability
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataMartAvailabilityApiDto'
      responses:
        '204':
          description: DataMart availability updated
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Update DataMart availability
      tags:
        - DataMarts
  /api/data-marts/{id}/blendable-schema:
    get:
      description: >-
        Returns native fields, blended fields pulled from joined DataMarts, and
        the list of available sources reachable via relationships.
      operationId: DataMartController_getBlendableSchema
      parameters:
        - name: id
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BlendableSchemaDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get blendable schema for a DataMart
      tags:
        - DataMarts
  /api/data-storages:
    get:
      operationId: DataStorageController_getAll
      parameters:
        - name: ownerFilter
          required: false
          in: query
          description: Filter Data Storages by whether they have owners
          schema:
            enum:
              - has_owners
              - no_owners
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataStorageListResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get all Data Storages
      tags:
        - DataStorages
    post:
      operationId: DataStorageController_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDataStorageApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStorageResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new Data Storage
      tags:
        - DataStorages
  /api/data-storages/{id}:
    put:
      operationId: DataStorageController_update
      parameters:
        - name: id
          required: true
          in: path
          description: Data Storage ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataStorageApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStorageResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update Data Storage by ID
      tags:
        - DataStorages
    get:
      operationId: DataStorageController_get
      parameters:
        - name: id
          required: true
          in: path
          description: Data Storage ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStorageResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get a Data Storage by ID
      tags:
        - DataStorages
    delete:
      operationId: DataStorageController_delete
      parameters:
        - name: id
          required: true
          in: path
          description: Data Storage ID
          schema:
            type: string
      responses:
        '200':
          description: Data Storage successfully deleted
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Delete Data Storage by ID
      tags:
        - DataStorages
  /api/data-storages/by-type/{type}:
    get:
      operationId: DataStorageController_getByType
      parameters:
        - name: type
          required: true
          in: path
          description: Data Storage type
          schema:
            enum:
              - GOOGLE_BIGQUERY
              - AWS_ATHENA
              - SNOWFLAKE
              - AWS_REDSHIFT
              - DATABRICKS
              - LEGACY_GOOGLE_BIGQUERY
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataStorageByTypeResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List Data Storages by type (for credential copy)
      tags:
        - DataStorages
  /api/data-storages/oauth/settings:
    get:
      operationId: DataStorageController_getOAuthSettings
      parameters: []
      responses:
        '200':
          description: OAuth settings
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GoogleOAuthSettingsResponseDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get Google OAuth settings (client ID, redirect URI, scopes)
      tags:
        - DataStorages
  /api/data-storages/oauth/exchange:
    post:
      operationId: DataStorageController_exchangeOAuthCode
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExchangeAuthorizationCodeRequestDto'
      responses:
        '200':
          description: OAuth credential created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExchangeAuthorizationCodeResponseDto'
        '400':
          description: Invalid authorization code or state
        '401':
          description: Authentication required
        '403':
          description: |-
            OAuth state does not belong to your project

            Forbidden. Required role: Technical User
        '503':
          description: Google OAuth is not configured
      security:
        - bearer: []
      summary: Exchange OAuth authorization code for tokens (Data Storage)
      tags:
        - DataStorages
  /api/data-storages/{id}/resources:
    get:
      operationId: DataStorageController_listStorageResources
      parameters:
        - name: id
          required: true
          in: path
          description: Data Storage ID
          schema:
            type: string
        - name: level
          required: true
          in: query
          description: 'Tree level to load: namespaces | resources'
          schema:
            enum:
              - namespaces
              - resources
            type: string
        - name: namespaceId
          required: false
          in: query
          description: >-
            Top-level container ID (GCP project, Snowflake database, …).
            Required for level=resources.
          schema:
            example: my-gcp-project
            type: string
        - name: resourceType
          required: false
          in: query
          description: Filter leaf resources by type. Only applies to level=resources.
          schema:
            enum:
              - TABLE
              - VIEW
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListStorageResourcesResponseDto'
        '400':
          description: >-
            Resource browsing not supported for this storage type, or required
            params missing
        '401':
          description: Authentication required
        '403':
          description: |-
            No access to this Storage

            Forbidden. Required role: Business User
      security:
        - bearer: []
      summary: List storage resources (namespaces / leaf resources) for a storage
      tags:
        - DataStorages
  /api/data-storages/{id}/validate-access:
    post:
      operationId: DataStorageController_validate
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStorageAccessValidationResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Validate Data Storage access
      tags:
        - DataStorages
  /api/data-storages/{id}/oauth/authorize:
    post:
      operationId: DataStorageController_generateOAuthAuthorizationUrl
      parameters:
        - name: id
          required: true
          in: path
          description: Data Storage ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateAuthorizationUrlRequestDto'
      responses:
        '200':
          description: Authorization URL and state token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateAuthorizationUrlResponseDto'
        '400':
          description: Invalid redirect URI
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
        '503':
          description: Google OAuth is not configured
      security:
        - bearer: []
      summary: Generate Google OAuth authorization URL for a Data Storage
      tags:
        - DataStorages
  /api/data-storages/{id}/oauth/status:
    get:
      operationId: DataStorageController_getOAuthStatus
      parameters:
        - name: id
          required: true
          in: path
          description: Data Storage ID
          schema:
            type: string
      responses:
        '200':
          description: OAuth connection status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GoogleOAuthStatusResponseDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get OAuth status for a Data Storage
      tags:
        - DataStorages
  /api/data-storages/{id}/oauth:
    delete:
      operationId: DataStorageController_revokeOAuth
      parameters:
        - name: id
          required: true
          in: path
          description: Data Storage ID
          schema:
            type: string
      responses:
        '204':
          description: OAuth credentials revoked
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Revoke Google OAuth credentials for a Data Storage
      tags:
        - DataStorages
  /api/data-storages/{id}/availability:
    put:
      operationId: DataStorageController_updateAvailability
      parameters:
        - name: id
          required: true
          in: path
          description: Data Storage ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateStorageAvailabilityApiDto'
      responses:
        '204':
          description: Data Storage availability updated
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Update Data Storage availability
      tags:
        - DataStorages
  /api/data-destinations:
    post:
      operationId: DataDestinationController_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDataDestinationApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataDestinationResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Create a new Data Destination
      tags:
        - DataDestinations
    get:
      operationId: DataDestinationController_getAll
      parameters:
        - name: ownerFilter
          required: false
          in: query
          description: Filter Data Destinations by whether they have owners
          schema:
            enum:
              - has_owners
              - no_owners
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataDestinationResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get all Data Destinations
      tags:
        - DataDestinations
  /api/data-destinations/by-type/{type}:
    get:
      operationId: DataDestinationController_getByType
      parameters:
        - name: type
          required: true
          in: path
          description: Data Destination type
          schema:
            enum:
              - GOOGLE_SHEETS
              - LOOKER_STUDIO
              - EMAIL
              - SLACK
              - MS_TEAMS
              - GOOGLE_CHAT
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataDestinationByTypeResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List Data Destinations by type (for credential copy)
      tags:
        - DataDestinations
  /api/data-destinations/{id}:
    put:
      operationId: DataDestinationController_update
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataDestinationApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataDestinationResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Update Data Destination by ID
      tags:
        - DataDestinations
    get:
      operationId: DataDestinationController_get
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataDestinationResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get a Data Destination by ID
      tags:
        - DataDestinations
    delete:
      operationId: DataDestinationController_delete
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      responses:
        '200':
          description: Data Destination successfully deleted
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Delete Data Destination by ID
      tags:
        - DataDestinations
  /api/data-destinations/oauth/settings:
    get:
      operationId: DataDestinationController_getOAuthSettings
      parameters: []
      responses:
        '200':
          description: OAuth configuration settings
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GoogleOAuthSettingsResponseDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get Google OAuth settings for Data Destinations
      tags:
        - DataDestinations
  /api/data-destinations/oauth/credential-status/{credentialId}:
    get:
      operationId: DataDestinationController_getOAuthCredentialStatus
      parameters:
        - name: credentialId
          required: true
          in: path
          description: OAuth Credential ID
          schema:
            type: string
      responses:
        '200':
          description: OAuth credential status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GoogleOAuthStatusResponseDto'
        '401':
          description: Authentication required
        '403':
          description: |-
            Credential does not belong to your project

            Forbidden. Required role: Business User
      security:
        - bearer: []
      summary: Get OAuth credential status by credential ID
      tags:
        - DataDestinations
  /api/data-destinations/oauth/authorize:
    post:
      operationId: DataDestinationController_generateOAuthAuthorizationUrlStandalone
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateAuthorizationUrlRequestDto'
      responses:
        '200':
          description: Authorization URL and state token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateAuthorizationUrlResponseDto'
        '400':
          description: Invalid redirect URI
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '503':
          description: Google OAuth is not configured
      security:
        - bearer: []
      summary: Generate Google OAuth authorization URL for Data Destination credentials
      tags:
        - DataDestinations
  /api/data-destinations/oauth/exchange:
    post:
      operationId: DataDestinationController_exchangeOAuthCode
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExchangeAuthorizationCodeRequestDto'
      responses:
        '200':
          description: OAuth credential created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExchangeAuthorizationCodeResponseDto'
        '400':
          description: Invalid authorization code or state
        '401':
          description: Authentication required
        '403':
          description: |-
            OAuth state does not belong to your project

            Forbidden. Required role: Business User
        '503':
          description: Google OAuth is not configured
      security:
        - bearer: []
      summary: Exchange OAuth authorization code for tokens (Data Destination)
      tags:
        - DataDestinations
  /api/data-destinations/{id}/impact:
    get:
      operationId: DataDestinationController_getImpact
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataDestinationImpactResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: >-
        Get usage impact for a Data Destination (reports + distinct data marts
        referencing it)
      tags:
        - DataDestinations
  /api/data-destinations/{id}/rotate-secret-key:
    post:
      operationId: DataDestinationController_rotateSecretKey
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataDestinationResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Rotate secret key for Data Destination
      tags:
        - DataDestinations
  /api/data-destinations/{id}/oauth/authorize:
    post:
      operationId: DataDestinationController_generateOAuthAuthorizationUrl
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateAuthorizationUrlRequestDto'
      responses:
        '200':
          description: Authorization URL and state token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateAuthorizationUrlResponseDto'
        '400':
          description: Invalid redirect URI
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '503':
          description: Google OAuth is not configured
      security:
        - bearer: []
      summary: Generate Google OAuth authorization URL for a Data Destination
      tags:
        - DataDestinations
  /api/data-destinations/{id}/oauth/status:
    get:
      operationId: DataDestinationController_getOAuthStatus
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      responses:
        '200':
          description: OAuth connection status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GoogleOAuthStatusResponseDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get OAuth status for a Data Destination
      tags:
        - DataDestinations
  /api/data-destinations/{id}/oauth:
    delete:
      operationId: DataDestinationController_revokeOAuth
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      responses:
        '204':
          description: OAuth credentials revoked
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Revoke Google OAuth credentials for a Data Destination
      tags:
        - DataDestinations
  /api/data-destinations/{id}/availability:
    put:
      operationId: DataDestinationController_updateAvailability
      parameters:
        - name: id
          required: true
          in: path
          description: Data Destination ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDestinationAvailabilityApiDto'
      responses:
        '204':
          description: Data Destination availability updated
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Update Data Destination availability
      tags:
        - DataDestinations
  /api/reports:
    post:
      operationId: ReportController_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - title
                - dataMartId
                - dataDestinationId
                - destinationConfig
              properties:
                title:
                  type: string
                  example: My Report
                dataMartId:
                  type: string
                  description: ID of the data mart
                dataDestinationId:
                  type: string
                  description: ID of the data destination
                destinationConfig:
                  description: Configuration for the selected data destination.
                  oneOf:
                    - $ref: '#/components/schemas/ReportEmailDestinationConfigApiDto'
                    - allOf:
                        - $ref: >-
                            #/components/schemas/ReportLegacyEmailDestinationConfigApiDto
                      not:
                        required:
                          - templateSource
                    - $ref: >-
                        #/components/schemas/ReportGoogleSheetsDestinationConfigApiDto
                    - $ref: >-
                        #/components/schemas/ReportLookerStudioDestinationConfigApiDto
                ownerIds:
                  type: array
                  items:
                    type: string
                  maxItems: 100
                columnConfig:
                  type: array
                  nullable: true
                  items:
                    type: string
                    minLength: 1
                    description: Selected output column name.
                  description: >-
                    Ordered selected output column names. Set null to include
                    all native columns.
                  example:
                    - date
                    - campaign_name
                    - spend
                filterConfig:
                  type: array
                  nullable: true
                  maxItems: 50
                  items:
                    $ref: '#/components/schemas/ReportFilterRuleApiDto'
                  description: >-
                    Output filters. Use placement=pre-join and aliasPath for
                    slice filters.
                sortConfig:
                  type: array
                  nullable: true
                  maxItems: 10
                  items:
                    $ref: '#/components/schemas/ReportSortRuleApiDto'
                  description: Ordered sort rules. Earlier rules take precedence.
                  example:
                    - column: date
                      direction: desc
                limitConfig:
                  type: integer
                  nullable: true
                  minimum: 1
                  maximum: 10000000
                  description: >-
                    Maximum number of rows to return. Set null to return without
                    an explicit cap.
                  example: 1000
      responses:
        '201':
          description: The report has been successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReportResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Create a new report
      tags:
        - Reports
    get:
      operationId: ReportController_listByProject
      parameters:
        - name: ownerFilter
          required: false
          in: query
          description: Filter reports by whether they have owners
          schema:
            enum:
              - has_owners
              - no_owners
            type: string
      responses:
        '200':
          description: List of reports for the project
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ReportResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get all reports for a project
      tags:
        - Reports
  /api/reports/{id}:
    get:
      operationId: ReportController_get
      parameters:
        - name: id
          required: true
          in: path
          description: Report ID
          schema:
            type: string
      responses:
        '200':
          description: The report
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReportResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get a report by ID
      tags:
        - Reports
    delete:
      operationId: ReportController_delete
      parameters:
        - name: id
          required: true
          in: path
          description: Report ID
          schema:
            type: string
      responses:
        '200':
          description: The report has been successfully deleted.
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Delete a report
      tags:
        - Reports
    put:
      operationId: ReportController_update
      parameters:
        - name: id
          required: true
          in: path
          description: Report ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - title
                - dataDestinationId
                - destinationConfig
              properties:
                title:
                  type: string
                  example: My Report
                dataDestinationId:
                  type: string
                  description: ID of the data destination
                destinationConfig:
                  description: Configuration for the selected data destination.
                  oneOf:
                    - $ref: '#/components/schemas/ReportEmailDestinationConfigApiDto'
                    - allOf:
                        - $ref: >-
                            #/components/schemas/ReportLegacyEmailDestinationConfigApiDto
                      not:
                        required:
                          - templateSource
                    - $ref: >-
                        #/components/schemas/ReportGoogleSheetsDestinationConfigApiDto
                    - $ref: >-
                        #/components/schemas/ReportLookerStudioDestinationConfigApiDto
                ownerIds:
                  type: array
                  items:
                    type: string
                  maxItems: 100
                columnConfig:
                  type: array
                  nullable: true
                  items:
                    type: string
                    minLength: 1
                    description: Selected output column name.
                  description: >-
                    Ordered selected output column names. Set null to include
                    all native columns.
                  example:
                    - date
                    - campaign_name
                    - spend
                filterConfig:
                  type: array
                  nullable: true
                  maxItems: 50
                  items:
                    $ref: '#/components/schemas/ReportFilterRuleApiDto'
                  description: >-
                    Output filters. Use placement=pre-join and aliasPath for
                    slice filters.
                sortConfig:
                  type: array
                  nullable: true
                  maxItems: 10
                  items:
                    $ref: '#/components/schemas/ReportSortRuleApiDto'
                  description: Ordered sort rules. Earlier rules take precedence.
                  example:
                    - column: date
                      direction: desc
                limitConfig:
                  type: integer
                  nullable: true
                  minimum: 1
                  maximum: 10000000
                  description: >-
                    Maximum number of rows to return. Set null to return without
                    an explicit cap.
                  example: 1000
      responses:
        '200':
          description: The report has been successfully updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReportResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Update an existing report
      tags:
        - Reports
  /api/reports/data-mart/{dataMartId}:
    get:
      operationId: ReportController_listByDataMart
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: Data mart ID
          schema:
            type: string
      responses:
        '200':
          description: List of reports for the data mart
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ReportResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get all reports for a data mart
      tags:
        - Reports
  /api/reports/data-mart/{dataMartId}/insight-template/{insightTemplateId}:
    get:
      operationId: ReportController_listByInsightTemplate
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: Data mart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight template ID
          schema:
            type: string
      responses:
        '200':
          description: >-
            List of email reports that use the insight template as their
            template source
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ReportResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get email reports that use an insight template
      tags:
        - Reports
  /api/reports/{id}/run:
    post:
      operationId: ReportController_runReport
      parameters:
        - name: id
          required: true
          in: path
          description: Report ID
          schema:
            type: string
      responses:
        '201':
          description: The manual report run trigger has been successfully created.
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Trigger a manual report run
      tags:
        - Reports
  /api/reports/{id}/generated-sql:
    get:
      operationId: ReportController_getGeneratedSql
      parameters:
        - name: id
          required: true
          in: path
          description: Report ID
          schema:
            type: string
      responses:
        '200':
          description: The generated SQL query for the report.
          content:
            application/json:
              schema:
                type: object
                required:
                  - sql
                properties:
                  sql:
                    type: string
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get the generated SQL for a report
      tags:
        - Reports
  /api/reports/{id}/copy-as-data-mart:
    post:
      operationId: ReportController_copyAsDataMart
      parameters:
        - name: id
          required: true
          in: path
          description: Report ID
          schema:
            type: string
      responses:
        '201':
          description: The new data mart has been successfully created.
          content:
            application/json:
              schema:
                type: object
                required:
                  - dataMartId
                properties:
                  dataMartId:
                    type: string
                    format: uuid
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Copy a report as a new data mart with SQL definition
      tags:
        - Reports
  /api/data-marts/{dataMartId}/insights:
    post:
      operationId: InsightController_create
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInsightRequestApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new Insight
      tags:
        - Insights
    get:
      operationId: InsightController_list
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/InsightListItemResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List Insights for a DataMart
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insights/ai-generate:
    post:
      operationId: InsightController_createWithAi
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new Insight with AI
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insights/{insightId}:
    get:
      operationId: InsightController_get
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightId
          required: true
          in: path
          description: Insight ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get an Insight by ID
      tags:
        - Insights
    put:
      operationId: InsightController_update
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightId
          required: true
          in: path
          description: Insight ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateInsightRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update Insight
      tags:
        - Insights
    delete:
      operationId: InsightController_delete
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightId
          required: true
          in: path
          description: Insight ID
          schema:
            type: string
      responses:
        '204':
          description: Insight deleted
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Soft delete Insight
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insights/{insightId}/title:
    put:
      operationId: InsightController_updateTitle
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightId
          required: true
          in: path
          description: Insight ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateInsightTitleApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update Insight title
      tags:
        - Insights
  /api/data-marts/{dataMartId}/ai-assistant/sessions:
    post:
      operationId: AiAssistantController_createSession
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAiAssistantSessionRequestApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateAiAssistantSessionResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create AI Source Assistant session
      tags:
        - Insights
    get:
      operationId: AiAssistantController_listSessions
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: scope
          required: true
          in: query
          schema:
            $ref: '#/components/schemas/AiAssistantScope'
        - name: templateId
          required: false
          in: query
          description: Template id filter. Use with template scope
          schema:
            example: 6f093b03-30c1-43e0-b9ed-6d87d33edf15
            type: string
        - name: limit
          required: false
          in: query
          description: Limit number of sessions
          schema:
            minimum: 1
            maximum: 100
            default: 20
            type: number
        - name: offset
          required: false
          in: query
          description: Offset for pagination
          schema:
            minimum: 0
            default: 0
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: >-
                    #/components/schemas/AiAssistantSessionListItemResponseApiDto
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List AI Source Assistant sessions for current user and context
      tags:
        - Insights
  /api/data-marts/{dataMartId}/ai-assistant/sessions/{sessionId}:
    get:
      operationId: AiAssistantController_getSession
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: sessionId
          required: true
          in: path
          description: AI Source Assistant Session ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AiAssistantSessionResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get AI Source Assistant session with message history
      tags:
        - Insights
    delete:
      operationId: AiAssistantController_deleteSession
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: sessionId
          required: true
          in: path
          description: AI Source Assistant Session ID
          schema:
            type: string
      responses:
        '204':
          description: ''
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Delete AI Source Assistant session
      tags:
        - Insights
  /api/data-marts/{dataMartId}/ai-assistant/sessions/{sessionId}/title:
    patch:
      operationId: AiAssistantController_updateSessionTitle
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: sessionId
          required: true
          in: path
          description: AI Source Assistant Session ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAiAssistantSessionTitleRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AiAssistantSessionListItemResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update AI Source Assistant session title
      tags:
        - Insights
  /api/data-marts/{dataMartId}/ai-assistant/sessions/{sessionId}/messages:
    post:
      description: >-
        Returns lightweight response payload or heavy route trigger id depending
        on server-side routing.
      operationId: AiAssistantController_createMessage
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: sessionId
          required: true
          in: path
          description: AI Source Assistant Session ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAiAssistantMessageRequestApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateAiAssistantMessageResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Append user message to AI Source Assistant session
      tags:
        - Insights
  /api/data-marts/{dataMartId}/ai-assistant/sessions/{sessionId}/apply:
    post:
      operationId: AiAssistantController_apply
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: sessionId
          required: true
          in: path
          description: AI Source Assistant Session ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ApplyAiAssistantSessionRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApplyAiAssistantSessionResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Execute pre-created apply action by id
      tags:
        - Insights
  /api/data-marts/{dataMartId}/ai-assistant/run-triggers:
    get:
      operationId: AiAssistantRunTriggerController_listAiAssistantTriggers
      parameters:
        - name: dataMartId
          required: true
          in: path
          schema:
            type: string
        - name: sessionId
          required: true
          in: query
          description: AI assistant session id
          schema:
            example: 6f093b03-30c1-43e0-b9ed-6d87d33edf15
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/data-marts/{dataMartId}/ai-assistant/run-triggers/{triggerId}/status:
    get:
      operationId: AiAssistantRunTriggerController_getTriggerStatus
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/data-marts/{dataMartId}/ai-assistant/run-triggers/{triggerId}:
    get:
      operationId: AiAssistantRunTriggerController_getTriggerResponse
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
    delete:
      operationId: AiAssistantRunTriggerController_abortTriggerRun
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-artifacts:
    post:
      operationId: InsightArtifactController_create
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInsightArtifactRequestApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightArtifactResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new Insight Artifact
      tags:
        - Insights
    get:
      operationId: InsightArtifactController_list
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: >-
                        #/components/schemas/InsightArtifactListItemResponseApiDto
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List Insight Artifacts for a DataMart
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-artifacts/{insightArtifactId}:
    get:
      operationId: InsightArtifactController_get
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightArtifactId
          required: true
          in: path
          description: Insight Artifact ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightArtifactResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get an Insight Artifact by ID
      tags:
        - Insights
    put:
      operationId: InsightArtifactController_update
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightArtifactId
          required: true
          in: path
          description: Insight Artifact ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateInsightArtifactRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightArtifactResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update Insight Artifact
      tags:
        - Insights
    delete:
      operationId: InsightArtifactController_delete
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightArtifactId
          required: true
          in: path
          description: Insight Artifact ID
          schema:
            type: string
      responses:
        '204':
          description: Insight Artifact deleted
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Soft delete Insight Artifact
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-artifacts/{insightArtifactId}/title:
    put:
      operationId: InsightArtifactController_updateTitle
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightArtifactId
          required: true
          in: path
          description: Insight Artifact ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateInsightArtifactTitleApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightArtifactResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update Insight Artifact title
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-artifacts/{insightArtifactId}/sql-preview-triggers:
    post:
      description: >-
        Initiates asynchronous SQL preview for the specified Insight Artifact.
        Returns a trigger ID to check status and retrieve preview rows.
      operationId: InsightArtifactSqlPreviewTriggerController_createTrigger
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightArtifactId
          required: true
          in: path
          description: Insight Artifact ID
          schema:
            type: string
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RunInsightArtifactSqlPreviewRequestApiDto'
      responses:
        '201':
          description: Trigger created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  triggerId:
                    type: string
                    description: ID of the created trigger
                    example: 550e8400-e29b-41d4-a716-446655440000
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Create a new Insight Artifact SQL preview trigger
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-artifacts/{insightArtifactId}/sql-preview-triggers/{triggerId}/status:
    get:
      operationId: InsightArtifactSqlPreviewTriggerController_getTriggerStatus
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-artifacts/{insightArtifactId}/sql-preview-triggers/{triggerId}:
    get:
      operationId: InsightArtifactSqlPreviewTriggerController_getTriggerResponse
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
    delete:
      operationId: InsightArtifactSqlPreviewTriggerController_abortTriggerRun
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-templates:
    post:
      operationId: InsightTemplateController_create
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInsightTemplateRequestApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightTemplateResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new Insight Template
      tags:
        - Insights
    get:
      operationId: InsightTemplateController_list
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: >-
                        #/components/schemas/InsightTemplateListItemResponseApiDto
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List Insight Templates for a DataMart
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-templates/{insightTemplateId}:
    get:
      operationId: InsightTemplateController_get
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightTemplateResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get an Insight Template by ID
      tags:
        - Insights
    put:
      operationId: InsightTemplateController_update
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateInsightTemplateRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightTemplateResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update Insight Template
      tags:
        - Insights
    delete:
      operationId: InsightTemplateController_delete
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
      responses:
        '204':
          description: Insight Template deleted
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Soft delete Insight Template
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-templates/{insightTemplateId}/title:
    put:
      operationId: InsightTemplateController_updateTitle
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateInsightTemplateTitleApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightTemplateResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update Insight Template title
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-templates/{insightTemplateId}/sources/{sourceId}:
    delete:
      operationId: InsightTemplateController_deleteSource
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
        - name: sourceId
          required: true
          in: path
          description: Insight Template Source ID
          schema:
            type: string
      responses:
        '204':
          description: Insight Template Source deleted
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Delete Insight Template Source and linked artifact
      tags:
        - Insights
    patch:
      operationId: InsightTemplateController_updateSource
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
        - name: sourceId
          required: true
          in: path
          description: Insight Template Source ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateInsightTemplateSourceRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightTemplateSourceDetailsApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update Insight Template Source linked artifact
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-templates/{insightTemplateId}/sources:
    get:
      operationId: InsightTemplateController_listSources
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/InsightTemplateSourceDetailsApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List Insight Template Sources for a template
      tags:
        - Insights
    post:
      operationId: InsightTemplateController_createSource
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInsightTemplateSourceRequestApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightTemplateSourceDetailsApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create Insight Template Source with linked artifact
      tags:
        - Insights
  /api/connectors:
    get:
      operationId: ConnectorController_getAvailableConnectors
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConnectorDefinitionResponseApiDto'
      security:
        - bearer: []
      summary: Get available connectors
      tags:
        - Connectors
  /api/connectors/{connectorName}/specification:
    get:
      operationId: ConnectorController_getConnectorSpecification
      parameters:
        - name: connectorName
          required: true
          in: path
          description: Connector name
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConnectorSpecificationResponseApiDto'
        '404':
          description: Connector not found
      security:
        - bearer: []
      summary: Get connector specification
      tags:
        - Connectors
  /api/connectors/{connectorName}/fields:
    get:
      operationId: ConnectorController_getConnectorFields
      parameters:
        - name: connectorName
          required: true
          in: path
          description: Connector name
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConnectorFieldsResponseApiDto'
        '404':
          description: Connector not found
      security:
        - bearer: []
      summary: Get connector fields
      tags:
        - Connectors
  /api/connectors/{connectorName}/oauth/settings:
    get:
      operationId: ConnectorController_getConnectorOAuthSettings
      parameters:
        - name: connectorName
          required: true
          in: path
          description: Connector name
          schema:
            type: string
        - name: path
          required: true
          in: query
          description: Path to the OAuth configuration in connector specification
          schema:
            example: AuthType.oauth2
            type: string
      responses:
        '200':
          description: OAuth UI settings
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConnectorOAuthSettingsResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '404':
          description: Connector not found
      security:
        - bearer: []
      summary: Get OAuth settings (UI variables) for a connector
      tags:
        - Connectors
  /api/connectors/{connectorName}/oauth/exchange:
    post:
      operationId: ConnectorController_handleOAuthCallback
      parameters:
        - name: connectorName
          required: true
          in: path
          description: Connector name
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExchangeOAuthCredentialsDto'
      responses:
        '201':
          description: OAuth credentials exchanged successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConnectorOAuthCredentialsResponseApiDto'
        '400':
          description: Invalid OAuth credentials payload
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Exchange OAuth credentials for a connector
      tags:
        - Connectors
  /api/connectors/{connectorName}/oauth/status/{credentialId}:
    get:
      operationId: ConnectorController_getConnectorOAuthStatus
      parameters:
        - name: connectorName
          required: true
          in: path
          description: Connector name
          schema:
            type: string
        - name: credentialId
          required: true
          in: path
          description: OAuth credential ID
          schema:
            type: string
      responses:
        '200':
          description: OAuth credential status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConnectorOAuthStatusResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get connector OAuth status
      tags:
        - Connectors
  /api/data-marts/{dataMartId}/scheduled-triggers:
    post:
      description: >-
        Creates a scheduled connector run or report run trigger for a published
        DataMart. REPORT_RUN triggers require triggerConfig.reportId and report
        mutation access. CONNECTOR_RUN triggers must not include triggerConfig
        and require a Technical User role.
      operationId: ScheduledTriggerController_create
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        description: >-
          Set isActive to true to schedule the next run immediately. If omitted,
          isActive defaults to false.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateScheduledTriggerRequestApiDto'
            examples:
              reportRun:
                summary: Schedule a report run
                value:
                  type: REPORT_RUN
                  cronExpression: 0 9 * * *
                  timeZone: UTC
                  isActive: true
                  triggerConfig:
                    type: scheduled-report-run-config
                    reportId: 9cabc24e-1234-4a5a-8b12-abcdef123456
              connectorRun:
                summary: Schedule a connector run
                value:
                  type: CONNECTOR_RUN
                  cronExpression: 0 * * * *
                  timeZone: UTC
                  isActive: false
      responses:
        '201':
          description: Scheduled trigger created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledTriggerResponseApiDto'
        '400':
          description: >-
            Invalid request, invalid cron expression, invalid trigger config, or
            DataMart is not published
        '401':
          description: Authentication required
        '403':
          description: >-
            Insufficient permissions to manage the requested trigger type or
            report trigger target


            Forbidden. Required role: Business User
        '404':
          description: DataMart or report not found
      security:
        - bearer: []
      summary: Create a scheduled trigger for a DataMart
      tags:
        - ScheduledTriggers
    get:
      description: >-
        Returns scheduled triggers for the DataMart in the current project,
        including createdByUser projections when available.
      operationId: ScheduledTriggerController_list
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ScheduledTriggerResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List scheduled triggers for a DataMart
      tags:
        - ScheduledTriggers
  /api/data-marts/{dataMartId}/scheduled-triggers/{id}:
    get:
      description: >-
        Returns a scheduled trigger that belongs to the specified DataMart and
        project.
      operationId: ScheduledTriggerController_get
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: id
          required: true
          in: path
          description: Scheduled Trigger ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledTriggerResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '404':
          description: Scheduled trigger not found
      security:
        - bearer: []
      summary: Get a scheduled trigger by ID
      tags:
        - ScheduledTriggers
    put:
      description: >-
        Updates cronExpression, timeZone, and isActive. Trigger type and
        triggerConfig are immutable. Permission checks are based on the existing
        trigger type.
      operationId: ScheduledTriggerController_update
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: id
          required: true
          in: path
          description: Scheduled Trigger ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateScheduledTriggerRequestApiDto'
      responses:
        '200':
          description: Scheduled trigger updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledTriggerResponseApiDto'
        '400':
          description: >-
            Invalid request, invalid cron expression, invalid stored trigger
            config, or DataMart is not published
        '401':
          description: Authentication required
        '403':
          description: >-
            Insufficient permissions to manage the requested trigger type or
            report trigger target


            Forbidden. Required role: Business User
        '404':
          description: Scheduled trigger not found
      security:
        - bearer: []
      summary: Update a scheduled trigger
      tags:
        - ScheduledTriggers
    delete:
      description: >-
        Deletes a scheduled trigger after applying permission checks based on
        the existing trigger type.
      operationId: ScheduledTriggerController_delete
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: id
          required: true
          in: path
          description: Scheduled Trigger ID
          schema:
            type: string
      responses:
        '200':
          description: Scheduled trigger deleted
        '400':
          description: Invalid stored trigger config
        '401':
          description: Authentication required
        '403':
          description: >-
            Insufficient permissions to manage the requested trigger type or
            report trigger target


            Forbidden. Required role: Business User
        '404':
          description: Scheduled trigger not found
      security:
        - bearer: []
      summary: Delete a scheduled trigger
      tags:
        - ScheduledTriggers
  /api/external/looker/get-config:
    post:
      operationId: LookerStudioConnectorController_getConfig
      parameters: []
      responses:
        '200':
          description: ''
      security:
        - bearer: []
      tags:
        - Looker Studio Connector endpoints
  /api/external/looker/get-schema:
    post:
      operationId: LookerStudioConnectorController_getSchema
      parameters: []
      responses:
        '200':
          description: ''
      security:
        - bearer: []
      tags:
        - Looker Studio Connector endpoints
  /api/external/looker/get-data:
    post:
      operationId: LookerStudioConnectorController_getData
      parameters: []
      responses:
        '200':
          description: ''
      security:
        - bearer: []
      tags:
        - Looker Studio Connector endpoints
  /api/data-marts/{dataMartId}/sql-dry-run-triggers:
    post:
      description: >-
        Creates an asynchronous SQL dry run trigger for the specified DataMart.
        Poll the trigger status, then retrieve the SQL dry run result when
        processing is finished.
      operationId: SqlDryRunTriggerController_createSqlDryRunTrigger
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SqlDryRunRequestApiDto'
      responses:
        '201':
          description: Trigger created successfully
          content:
            application/json:
              schema:
                type: object
                required:
                  - triggerId
                properties:
                  triggerId:
                    type: string
                    format: uuid
                    description: ID of the created trigger
                    example: 550e8400-e29b-41d4-a716-446655440000
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Create a new SQL dry run trigger
      tags:
        - DataMarts
  /api/data-marts/{dataMartId}/sql-dry-run-triggers/{triggerId}/status:
    get:
      description: Returns the current scheduler status for the SQL dry run trigger.
      operationId: SqlDryRunTriggerController_getTriggerStatus
      parameters:
        - name: triggerId
          required: true
          in: path
          description: SQL dry run trigger ID
          schema:
            type: string
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema: {}
      responses:
        '200':
          description: Current trigger status
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                properties:
                  status:
                    type: string
                    enum:
                      - IDLE
                      - READY
                      - PROCESSING
                      - SUCCESS
                      - ERROR
                      - CANCELLING
                      - CANCELLED
                    example: IDLE
                    description: Current trigger status
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '404':
          description: Trigger not found
      security:
        - bearer: []
      summary: Get SQL dry run trigger status
      tags:
        - DataMarts
  /api/data-marts/{dataMartId}/sql-dry-run-triggers/{triggerId}:
    get:
      description: >-
        Returns and removes the SQL dry run result when the trigger succeeds.
        SQL validation failures are returned as isValid=false with an error
        message.
      operationId: SqlDryRunTriggerController_getTriggerResponse
      parameters:
        - name: triggerId
          required: true
          in: path
          description: SQL dry run trigger ID
          schema:
            type: string
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema: {}
      responses:
        '200':
          description: SQL dry run result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SqlDryRunResponseApiDto'
        '400':
          description: Trigger failed or was cancelled
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '404':
          description: Trigger not found
        '408':
          description: Trigger response is not ready
      security:
        - bearer: []
      summary: Get SQL dry run result
      tags:
        - DataMarts
    delete:
      description: >-
        Cancels a SQL dry run trigger owned by the current user. Idle or
        successful triggers are removed; ready or processing triggers are marked
        as cancelling.
      operationId: SqlDryRunTriggerController_abortTriggerRun
      parameters:
        - name: triggerId
          required: true
          in: path
          description: SQL dry run trigger ID
          schema:
            type: string
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema: {}
      responses:
        '200':
          description: Trigger cancellation accepted or trigger removed
        '400':
          description: Trigger can't be cancelled at current state
        '401':
          description: Authentication required
        '403':
          description: |-
            Forbidden. Required role: Business User

            Current user is not allowed to cancel this trigger
        '404':
          description: Trigger not found
      security:
        - bearer: []
      summary: Cancel SQL dry run trigger
      tags:
        - DataMarts
  /api/data-marts/{dataMartId}/schema-actualize-triggers:
    post:
      operationId: SchemaActualizeTriggerController_createTrigger
      parameters:
        - name: dataMartId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - DataMarts
  /api/data-marts/{dataMartId}/schema-actualize-triggers/{triggerId}/status:
    get:
      operationId: SchemaActualizeTriggerController_getTriggerStatus
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - DataMarts
  /api/data-marts/{dataMartId}/schema-actualize-triggers/{triggerId}:
    get:
      operationId: SchemaActualizeTriggerController_getTriggerResponse
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - DataMarts
    delete:
      operationId: SchemaActualizeTriggerController_abortTriggerRun
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - DataMarts
  /api/data-storages/{dataStorageId}/publish-drafts-triggers:
    post:
      operationId: PublishDraftsTriggerController_createTrigger
      parameters:
        - name: dataStorageId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      tags:
        - DataStorages
  /api/data-storages/{dataStorageId}/publish-drafts-triggers/{triggerId}/status:
    get:
      operationId: PublishDraftsTriggerController_getTriggerStatus
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - DataStorages
  /api/data-storages/{dataStorageId}/publish-drafts-triggers/{triggerId}:
    get:
      operationId: PublishDraftsTriggerController_getTriggerResponse
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - DataStorages
    delete:
      operationId: PublishDraftsTriggerController_abortTriggerRun
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - DataStorages
  /api/data-marts/{dataMartId}/ai-helper/triggers:
    post:
      description: >-
        Creates an asynchronous AI metadata generation trigger for the specified
        DataMart. Poll the trigger status, then retrieve the result when
        processing is finished.
      operationId: AiHelperTriggerController_createAiHelperTrigger
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAiHelperTriggerRequestApiDto'
      responses:
        '201':
          description: Trigger created successfully
          content:
            application/json:
              schema:
                type: object
                required:
                  - triggerId
                properties:
                  triggerId:
                    type: string
                    format: uuid
                    description: ID of the created trigger
                    example: 550e8400-e29b-41d4-a716-446655440000
        '401':
          description: Authentication required
        '403':
          description: |-
            Forbidden. Required role: Technical User

            Current user is not allowed to edit this DataMart
        '503':
          description: AI helper is not configured on this deployment
      security:
        - bearer: []
      summary: Create a new AI helper trigger
      tags:
        - DataMarts
  /api/data-marts/{dataMartId}/ai-helper/triggers/{triggerId}/status:
    get:
      description: Returns the current scheduler status for the AI helper trigger.
      operationId: AiHelperTriggerController_getTriggerStatus
      parameters:
        - name: triggerId
          required: true
          in: path
          description: AI helper trigger ID
          schema:
            type: string
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema: {}
      responses:
        '200':
          description: Current trigger status
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                properties:
                  status:
                    type: string
                    enum:
                      - IDLE
                      - READY
                      - PROCESSING
                      - SUCCESS
                      - ERROR
                      - CANCELLING
                      - CANCELLED
                    example: IDLE
                    description: Current trigger status
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '404':
          description: Trigger not found
      security:
        - bearer: []
      summary: Get AI helper trigger status
      tags:
        - DataMarts
  /api/data-marts/{dataMartId}/ai-helper/triggers/{triggerId}:
    get:
      description: >-
        Returns and removes the AI helper result when the trigger succeeds.
        Trigger errors are returned with HTTP 400 carrying the user-facing error
        message.
      operationId: AiHelperTriggerController_getTriggerResponse
      parameters:
        - name: triggerId
          required: true
          in: path
          description: AI helper trigger ID
          schema:
            type: string
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema: {}
      responses:
        '200':
          description: AI helper result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AiHelperTriggerResponseApiDto'
        '400':
          description: Trigger failed or was cancelled
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '404':
          description: Trigger not found
        '408':
          description: Trigger response is not ready
      security:
        - bearer: []
      summary: Get AI helper result
      tags:
        - DataMarts
    delete:
      description: >-
        Cancels an AI helper trigger owned by the current user. Idle or
        successful triggers are removed; ready or processing triggers are marked
        as cancelling.
      operationId: AiHelperTriggerController_abortTriggerRun
      parameters:
        - name: triggerId
          required: true
          in: path
          description: AI helper trigger ID
          schema:
            type: string
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema: {}
      responses:
        '200':
          description: Trigger cancellation accepted or trigger removed
        '400':
          description: Trigger can't be cancelled at current state
        '401':
          description: Authentication required
        '403':
          description: |-
            Forbidden. Required role: Business User

            Current user is not allowed to cancel this trigger
        '404':
          description: Trigger not found
      security:
        - bearer: []
      summary: Cancel AI helper trigger
      tags:
        - DataMarts
  /api/data-marts/{dataMartId}/insights/{insightId}/run-triggers:
    post:
      description: >-
        Initiates an asynchronous run of the specified Insight. Returns a
        trigger ID to check status and retrieve the runId.
      operationId: InsightRunTriggerController_createTrigger
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightId
          required: true
          in: path
          description: Insight ID
          schema:
            type: string
      responses:
        '201':
          description: Trigger created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  triggerId:
                    type: string
                    description: ID of the created trigger
                    example: 550e8400-e29b-41d4-a716-446655440000
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new Insight run trigger
      tags:
        - Insights
    get:
      description: Returns a list of triggers for the specified Insight.
      operationId: InsightRunTriggerController_listInsightTriggers
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightId
          required: true
          in: path
          description: Insight ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: >-
                        #/components/schemas/InsightRunTriggerListItemResponseApiDto
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List Insight run triggers
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insights/{insightId}/run-triggers/{triggerId}/status:
    get:
      operationId: InsightRunTriggerController_getTriggerStatus
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insights/{insightId}/run-triggers/{triggerId}:
    get:
      operationId: InsightRunTriggerController_getTriggerResponse
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
    delete:
      operationId: InsightRunTriggerController_abortTriggerRun
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-templates/{insightTemplateId}/run-triggers:
    post:
      description: >-
        Initiates an asynchronous run of the specified Insight Template. Returns
        a trigger ID to check status and retrieve the runId.
      operationId: InsightTemplateRunTriggerController_createTrigger
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/CreateInsightTemplateRunTriggerRequestApiDto
      responses:
        '201':
          description: Trigger created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  triggerId:
                    type: string
                    description: ID of the created trigger
                    example: 550e8400-e29b-41d4-a716-446655440000
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new Insight Template run trigger
      tags:
        - Insights
    get:
      description: Returns a list of triggers for the specified Insight Template.
      operationId: InsightTemplateRunTriggerController_listInsightTemplateTriggers
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: DataMart ID
          schema:
            type: string
        - name: insightTemplateId
          required: true
          in: path
          description: Insight Template ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: >-
                        #/components/schemas/InsightTemplateRunTriggerListItemResponseApiDto
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List Insight Template run triggers
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-templates/{insightTemplateId}/run-triggers/{triggerId}/status:
    get:
      operationId: InsightTemplateRunTriggerController_getTriggerStatus
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/data-marts/{dataMartId}/insight-templates/{insightTemplateId}/run-triggers/{triggerId}:
    get:
      operationId: InsightTemplateRunTriggerController_getTriggerResponse
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
    delete:
      operationId: InsightTemplateRunTriggerController_abortTriggerRun
      parameters:
        - name: triggerId
          required: true
          in: path
          schema:
            type: string
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Insights
  /api/markdown/parse-to-html:
    post:
      operationId: MarkdownParserController_parseToHtml
      parameters: []
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - Utils
  /api/internal/legacy-data-marts-sync/{id}:
    post:
      operationId: LegacyDataMartsSyncController_syncDataMart
      parameters:
        - name: id
          required: true
          in: path
          description: Data mart ID
          schema:
            type: string
      responses:
        '204':
          description: Data sync initiated
      security:
        - bearer: []
      summary: Sync legacy data mart by ID
      tags:
        - LegacyDataMartsSync
    delete:
      operationId: LegacyDataMartsSyncController_deleteDataMart
      parameters:
        - name: id
          required: true
          in: path
          description: Data mart ID
          schema:
            type: string
      responses:
        '204':
          description: Data mart deletion initiated
      security:
        - bearer: []
      summary: Delete legacy data mart by ID
      tags:
        - LegacyDataMartsSync
  /api/project-setup-progress:
    get:
      operationId: ProjectSetupProgressController_getProgress
      parameters: []
      responses:
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      tags:
        - project-setup-progress
  /api/data-marts/{dataMartId}/relationships:
    post:
      operationId: DataMartRelationshipController_create
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: Source data mart ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateRelationshipRequestApiDto'
      responses:
        '201':
          description: The relationship has been successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RelationshipResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Create a new relationship for a data mart
      tags:
        - Data Mart Relationships
    get:
      operationId: DataMartRelationshipController_list
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: Source data mart ID
          schema:
            type: string
      responses:
        '200':
          description: List of relationships for the data mart
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RelationshipResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List all relationships for a data mart
      tags:
        - Data Mart Relationships
  /api/data-marts/{dataMartId}/relationships/{id}:
    get:
      operationId: DataMartRelationshipController_get
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: Source data mart ID
          schema:
            type: string
        - name: id
          required: true
          in: path
          description: Relationship ID
          schema:
            type: string
      responses:
        '200':
          description: The relationship
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RelationshipResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get a relationship by ID
      tags:
        - Data Mart Relationships
    patch:
      operationId: DataMartRelationshipController_update
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: Source data mart ID
          schema:
            type: string
        - name: id
          required: true
          in: path
          description: Relationship ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateRelationshipRequestApiDto'
      responses:
        '200':
          description: The relationship has been successfully updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RelationshipResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update an existing relationship
      tags:
        - Data Mart Relationships
    delete:
      operationId: DataMartRelationshipController_delete
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: Source data mart ID
          schema:
            type: string
        - name: id
          required: true
          in: path
          description: Relationship ID
          schema:
            type: string
      responses:
        '204':
          description: The relationship has been successfully deleted.
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Delete a relationship
      tags:
        - Data Mart Relationships
  /api/data-storages/{storageId}/relationships:
    get:
      operationId: DataStorageRelationshipController_listByStorage
      parameters:
        - name: storageId
          required: true
          in: path
          description: Data storage ID
          schema:
            type: string
      responses:
        '200':
          description: List of relationships for the data storage
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RelationshipResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List all relationships for a data storage
      tags:
        - Data Storage Relationships
  /api/contexts:
    post:
      operationId: ContextController_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateContextRequestApiDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContextResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '409':
          description: Context name already exists in this project
      security:
        - bearer: []
      summary: Create a new Context
      tags:
        - Contexts
    get:
      operationId: ContextController_list
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ContextResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List all Contexts in the project
      tags:
        - Contexts
  /api/contexts/{id}:
    put:
      operationId: ContextController_update
      parameters:
        - name: id
          required: true
          in: path
          description: Context ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateContextRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContextResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '404':
          description: Context not found
        '409':
          description: Context name already exists in this project
      security:
        - bearer: []
      summary: Update a Context by ID
      tags:
        - Contexts
    delete:
      description: >-
        Soft-deletes the context. Returns 409 with impact counts if it is still
        attached to any Data Mart, Storage, Destination or Member — caller must
        detach first.
      operationId: ContextController_delete
      parameters:
        - name: id
          required: true
          in: path
          description: Context ID
          schema:
            type: string
      responses:
        '204':
          description: Context deleted
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '404':
          description: Context not found
        '409':
          description: Context is still attached to resources or members
      security:
        - bearer: []
      summary: Delete a Context by ID
      tags:
        - Contexts
  /api/contexts/{id}/impact:
    get:
      description: >-
        Used to render the "Cannot delete" dialog. Returns counts of resources
        and members that reference the context.
      operationId: ContextController_getImpact
      parameters:
        - name: id
          required: true
          in: path
          description: Context ID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContextImpactResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '404':
          description: Context not found
      security:
        - bearer: []
      summary: Get usage counts and affected members for a Context
      tags:
        - Contexts
  /api/contexts/{id}/members:
    put:
      description: >-
        Admins are silently dropped from the input — they always have
        project-wide scope. The dropped admin user ids are returned in
        `droppedAdminIds` so the UI can warn the caller.
      operationId: ContextController_setContextMembers
      parameters:
        - name: id
          required: true
          in: path
          description: Context ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateContextMembersRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateContextMembersResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '404':
          description: Context not found
      security:
        - bearer: []
      summary: Replace the set of non-admin members bound to a Context
      tags:
        - Contexts
  /api/members:
    get:
      operationId: ProjectMembersController_list
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProjectMemberResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List project members with their role scope and assigned contexts
      tags:
        - Project Members
  /api/members/invite:
    post:
      description: >-
        Returns a discriminated union by `kind`: `email-sent` when the IDP
        server delivers the invitation email itself, or `magic-link` when the
        IDP returns a one-time link the admin must share manually.
      operationId: ProjectMembersController_invite
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InviteMemberRequestApiDto'
      responses:
        '202':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InviteMemberResponseApiDto'
        '400':
          description: Invalid email, role, or context ids
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '409':
          description: Member with this email already exists
        '502':
          description: Upstream IDP failure
      security:
        - bearer: []
      summary: Invite a new project member by email
      tags:
        - Project Members
  /api/members/{userId}:
    put:
      description: >-
        When the role changes, the IDP is updated first; only on success local
        scope and context bindings are persisted.
      operationId: ProjectMembersController_update
      parameters:
        - name: userId
          required: true
          in: path
          description: Project member user ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateMemberRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateMemberResponseApiDto'
        '400':
          description: Invalid context ids
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '404':
          description: Member not found in project
        '502':
          description: Upstream IDP failure when changing role
      security:
        - bearer: []
      summary: Update a project member's role, scope, and context bindings
      tags:
        - Project Members
    delete:
      description: >-
        Removes the member from the IDP and clears their local scope and context
        bindings. Idempotent for users already absent from the IDP.
      operationId: ProjectMembersController_remove
      parameters:
        - name: userId
          required: true
          in: path
          description: Project member user ID
          schema:
            type: string
      responses:
        '204':
          description: Member removed
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '502':
          description: Upstream IDP failure
      security:
        - bearer: []
      summary: Remove a project member
      tags:
        - Project Members
  /api/members/requests:
    get:
      description: >-
        Returns the array of pending requests for the project. Empty array means
        there are no pending requests. The non-OWOX IDP providers (better-auth,
        null) return an empty list rather than throwing.
      operationId: ProjectMembersController_listRequests
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MembershipRequestApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '502':
          description: Upstream IDP failure
      security:
        - bearer: []
      summary: List pending project membership requests
      tags:
        - Project Members
  /api/members/requests/{requestId}/approve:
    post:
      description: >-
        Resolves the requester into a full project member with the chosen role.
        Optionally narrows the role scope and pre-assigns contexts. Mirrors the
        post-invite scope/context apply.
      operationId: ProjectMembersController_approveRequest
      parameters:
        - name: requestId
          required: true
          in: path
          description: Pending request id (stable identifier from IDP)
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ApproveMembershipRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApproveMembershipRequestResponseApiDto'
        '400':
          description: Invalid role or context ids
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '404':
          description: Membership request not found
        '501':
          description: IDP provider does not support membership requests
        '502':
          description: Upstream IDP failure
      security:
        - bearer: []
      summary: Approve a pending membership request
      tags:
        - Project Members
  /api/members/requests/{requestId}/decline:
    post:
      description: >-
        Removes the request from the pending queue. Returns 404 if the request
        was already removed or never existed (symmetric with approve).
      operationId: ProjectMembersController_declineRequest
      parameters:
        - name: requestId
          required: true
          in: path
          description: Pending request id (stable identifier from IDP)
          schema:
            type: string
      responses:
        '204':
          description: Request declined
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Project Admin'
        '404':
          description: Membership request not found
        '501':
          description: IDP provider does not support membership requests
        '502':
          description: Upstream IDP failure
      security:
        - bearer: []
      summary: Decline a pending membership request
      tags:
        - Project Members
  /api/project-member-api-keys:
    get:
      operationId: ProjectMemberApiKeysController_list
      parameters:
        - name: includeRevoked
          required: false
          in: query
          description: Include revoked keys in the response
          schema:
            type: boolean
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProjectMemberApiKeyResponseDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: List API keys for the current project member
      tags:
        - Project Member API Keys
    post:
      operationId: ProjectMemberApiKeysController_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProjectMemberApiKeyRequestDto'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateProjectMemberApiKeyResponseDto'
        '400':
          description: Invalid request body
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Create a new API key for the current project member
      tags:
        - Project Member API Keys
  /api/project-member-api-keys/{apiKeyId}:
    patch:
      operationId: ProjectMemberApiKeysController_update
      parameters:
        - name: apiKeyId
          required: true
          in: path
          description: API key identifier
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateProjectMemberApiKeyRequestDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectMemberApiKeyResponseDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '404':
          description: API key not found
      security:
        - bearer: []
      summary: Update an existing API key name
      tags:
        - Project Member API Keys
    delete:
      description: >-
        Permanently revokes the API key. Any integrations using this key will
        stop working immediately.
      operationId: ProjectMemberApiKeysController_revoke
      parameters:
        - name: apiKeyId
          required: true
          in: path
          description: API key identifier
          schema:
            type: string
      responses:
        '204':
          description: API key revoked
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
        '404':
          description: API key not found
      security:
        - bearer: []
      summary: Revoke an API key
      tags:
        - Project Member API Keys
  /api/external/http-data/data-marts/{dataMartId}.ndjson:
    get:
      description: >-
        Streams rows of a published Data Mart as newline-delimited JSON (one
        data row per line, no envelope). Columns are chosen via the repeated
        `column` query parameter; row objects use those column names as keys in
        the requested order. Omit `column` (or pass `*`) for all native columns,
        or pass `**` for all native plus all reporting-visible blended columns.
        Authenticated with the ODM member token via `x-owox-authorization`.
        Creates one DataMartRun of type HTTP_DATA per request, available through
        the run history endpoint.
      operationId: HttpDataController_stream
      parameters:
        - name: dataMartId
          required: true
          in: path
          description: >-
            Data Mart identifier (UUID for native Data Marts, free-form string
            for legacy ones)
          schema:
            type: string
        - name: x-owox-authorization
          in: header
          description: ODM member token
          required: true
          schema:
            type: string
        - name: column
          required: false
          in: query
          description: >-
            Column to include in the output. Repeat the parameter to select
            multiple columns; the order of repetition is preserved in row
            objects. Two reserved values expand to column sets: `*` = all native
            columns, `**` = all native plus all reporting-visible blended
            columns. `*` may be combined with explicit columns (e.g.
            `column=*&column=orders__revenue` = all native plus that blended
            field). Omitting the parameter is equivalent to `*`. Overlaps are
            de-duplicated.
          schema:
            example:
              - date
              - revenue
            type: array
            items:
              type: string
        - name: filter
          required: false
          in: query
          description: >-
            Optional base64url-encoded JSON matching the `FilterConfig` schema
            (same shape as Reports), applied server-side before streaming.
            Encode the JSON array with base64url (URL-safe base64: `-`/`_`
            instead of `+`/`/`, no `=` padding) so it survives the query string.
            Example JSON:
            `[{"column":"date","operator":"gte","value":"2026-01-01"}]` →
            base64url
            `W3siY29sdW1uIjoiZGF0ZSIsIm9wZXJhdG9yIjoiZ3RlIiwidmFsdWUiOiIyMDI2LTAxLTAxIn1d`.
          schema:
            example: >-
              W3siY29sdW1uIjoiZGF0ZSIsIm9wZXJhdG9yIjoiZ3RlIiwidmFsdWUiOiIyMDI2LTAxLTAxIn1d
            type: string
        - name: sort
          required: false
          in: query
          description: >-
            Optional base64url-encoded JSON matching the `SortConfig` schema,
            applied server-side. Encode the JSON array with base64url (URL-safe
            base64: `-`/`_` instead of `+`/`/`, no `=` padding). Example JSON:
            `[{"column":"date","direction":"desc"}]` → base64url
            `W3siY29sdW1uIjoiZGF0ZSIsImRpcmVjdGlvbiI6ImRlc2MifV0`.
          schema:
            example: W3siY29sdW1uIjoiZGF0ZSIsImRpcmVjdGlvbiI6ImRlc2MifV0
            type: string
        - name: limit
          required: false
          in: query
          description: Optional row cap (positive integer).
          schema:
            type: number
      responses:
        '200':
          description: >-
            NDJSON stream of row objects. Each line is a complete JSON object
            whose keys match the requested columns, in the requested order. The
            response includes the `x-owox-run-id` header with the created
            DataMartRun ID.
          headers:
            x-owox-run-id:
              description: ID of the created DataMartRun (HTTP_DATA) for traceability
              schema:
                type: string
          content:
            application/x-ndjson:
              schema:
                type: string
                example: |
                  {"date":"2026-05-01","revenue":42.5}
                  {"date":"2026-05-02","revenue":51.0}
        '400':
          description: >-
            Invalid request: unknown column, forbidden pagination parameter
            (`pageToken`/`offset`), malformed filter/sort/limit, or unsupported
            storage type.
        '401':
          description: |-
            Missing or invalid `x-owox-authorization` token.

            Authentication required
        '403':
          description: >-
            Caller is authenticated but lacks `Action.USE` on the requested Data
            Mart.


            Forbidden. Required role: Business User
        '404':
          description: Data Mart not visible in the caller’s project, or not published.
      security:
        - bearer: []
      summary: Stream Data Mart data as NDJSON
      tags:
        - HTTP Data
  /api/auth/api-keys/exchange:
    post:
      operationId: ApiKeyExchangeController_exchange
      parameters:
        - name: X-OWOX-Api-Key-Id
          in: header
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExchangeProjectMemberApiKeyRequestApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExchangeProjectMemberApiKeyResponseApiDto'
      summary: Exchange a project member API key for an ODM access token
      tags:
        - Project Member API Keys
  /api/intercom/jwt:
    post:
      operationId: IntercomController_issueJwt
      parameters: []
      responses:
        '200':
          description: JWT token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntercomTokenResponseApiDto'
        '400':
          description: Missing INTERCOM_SECRET_KEY
        '401':
          description: |-
            Unauthorized

            Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Returns Intercom user verification JWT
      tags:
        - Intercom
  /api/projects/notification-settings:
    get:
      operationId: ProjectNotificationSettingsController_getSettings
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationSettingsResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get notification settings for a project
      tags:
        - ProjectNotificationSettings
  /api/projects/notification-settings/members:
    get:
      operationId: ProjectNotificationSettingsController_getProjectMembers
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectMembersResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Business User'
      security:
        - bearer: []
      summary: Get project members for receiver selection
      tags:
        - ProjectNotificationSettings
  /api/projects/notification-settings/{notificationType}:
    put:
      operationId: ProjectNotificationSettingsController_updateSetting
      parameters:
        - name: notificationType
          required: true
          in: path
          description: Notification type
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateNotificationSettingApiDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationSettingsItemResponseApiDto'
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Update a specific notification setting
      tags:
        - ProjectNotificationSettings
  /api/projects/notification-settings/{notificationType}/test-webhook:
    post:
      operationId: ProjectNotificationSettingsController_testWebhook
      parameters:
        - name: notificationType
          required: true
          in: path
          description: Notification type
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              properties:
                webhookUrl:
                  type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
        '401':
          description: Authentication required
        '403':
          description: 'Forbidden. Required role: Technical User'
      security:
        - bearer: []
      summary: Send a test webhook for a notification type
      tags:
        - ProjectNotificationSettings
info:
  title: OWOX Data Marts API
  description: REST API used by frontend clients and service integrations.
  version: '1.0'
  contact: {}
tags: []
servers: []
components:
  schemas:
    CreateDataMartRequestApiDto:
      type: object
      properties:
        title:
          type: string
          example: First Data Mart
        storageId:
          type: string
      required:
        - title
        - storageId
    CreateDataMartResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        title:
          type: string
          example: First Data Mart
      required:
        - id
        - title
    DataMartListItemStorageApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - GOOGLE_BIGQUERY
            - AWS_ATHENA
            - SNOWFLAKE
            - AWS_REDSHIFT
            - DATABRICKS
            - LEGACY_GOOGLE_BIGQUERY
          example: GOOGLE_BIGQUERY
        title:
          type: string
          example: My Storage
          nullable: true
      required:
        - type
        - title
    UserProjectionDto:
      type: object
      properties: {}
    DataMartListItemResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        title:
          type: string
          example: First Data Mart
        status:
          type: string
          enum:
            - DRAFT
            - PUBLISHED
          example: DRAFT
        storage:
          $ref: '#/components/schemas/DataMartListItemStorageApiDto'
        definitionType:
          type: string
          enum:
            - SQL
            - TABLE
            - VIEW
            - TABLE_PATTERN
            - CONNECTOR
          example: SQL
        connectorSourceName:
          type: string
          example: OpenExchangeRates
        triggersCount:
          type: number
          example: 1
        reportsCount:
          type: number
          example: 2
        createdByUser:
          type: object
        businessOwnerUsers:
          type: array
          items:
            $ref: '#/components/schemas/UserProjectionDto'
        technicalOwnerUsers:
          type: array
          items:
            $ref: '#/components/schemas/UserProjectionDto'
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
        contexts:
          type: array
          items:
            type: object
        availableForReporting:
          type: boolean
          example: true
        availableForMaintenance:
          type: boolean
          example: true
      required:
        - id
        - title
        - status
        - storage
        - definitionType
        - connectorSourceName
        - triggersCount
        - reportsCount
        - createdByUser
        - businessOwnerUsers
        - technicalOwnerUsers
        - createdAt
        - modifiedAt
        - contexts
        - availableForReporting
        - availableForMaintenance
    PaginatedDataMartsResponseApiDto:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/DataMartListItemResponseApiDto'
        total:
          type: number
          example: 120
        nextOffset:
          type: object
          example: 50
          nullable: true
          description: Next offset to fetch, null if no more data
      required:
        - items
        - total
        - nextOffset
    DataStorageResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: abc123e4-5678-90ab-cdef-1234567890ab
        title:
          type: string
          example: title
        type:
          type: string
          enum:
            - GOOGLE_BIGQUERY
            - AWS_ATHENA
            - SNOWFLAKE
            - AWS_REDSHIFT
            - DATABRICKS
            - LEGACY_GOOGLE_BIGQUERY
          example: GOOGLE_BIGQUERY
        projectId:
          type: string
          example: my-project
        credentials:
          type: object
          additionalProperties: true
          description: Credentials without sensitive fields
        config:
          type: object
          additionalProperties: true
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
        credentialId:
          type: object
          example: abc123e4-5678-90ab-cdef-1234567890ab
          nullable: true
        createdByUser:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/UserProjectionDto'
        ownerUsers:
          type: array
          items:
            $ref: '#/components/schemas/UserProjectionDto'
        availableForUse:
          type: boolean
          example: true
        availableForMaintenance:
          type: boolean
          example: true
        contexts:
          type: array
          items:
            type: object
      required:
        - id
        - title
        - type
        - projectId
        - credentials
        - config
        - createdAt
        - modifiedAt
        - ownerUsers
        - availableForUse
        - availableForMaintenance
        - contexts
    ConnectorStateItemResponseApiDto:
      type: object
      properties:
        _id:
          type: string
          example: 2861dd75-6a3a-434e-86e6-e4757808ac9d
        state:
          type: object
          additionalProperties: true
          example:
            date: '2024-04-05T00:00:00.000Z'
        at:
          type: string
          example: '2025-10-31 11:39:44'
      required:
        - _id
        - state
        - at
    ConnectorStateResponseApiDto:
      type: object
      properties:
        state:
          type: object
          additionalProperties: true
        at:
          type: string
          example: '2025-10-31T11:39:44.377Z'
        states:
          type: array
          items:
            $ref: '#/components/schemas/ConnectorStateItemResponseApiDto'
    DataMartResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        title:
          type: string
          example: First Data Mart
        status:
          type: string
          enum:
            - DRAFT
            - PUBLISHED
          example: DRAFT
        storage:
          $ref: '#/components/schemas/DataStorageResponseApiDto'
        definitionType:
          type: string
          enum:
            - SQL
            - TABLE
            - VIEW
            - TABLE_PATTERN
            - CONNECTOR
          example: SQL
        definition:
          type: object
        description:
          type: string
        schema:
          type: object
        connectorState:
          $ref: '#/components/schemas/ConnectorStateResponseApiDto'
        triggersCount:
          type: number
          example: 1
        reportsCount:
          type: number
          example: 2
        createdByUser:
          type: object
        businessOwnerUsers:
          type: array
          items:
            $ref: '#/components/schemas/UserProjectionDto'
        technicalOwnerUsers:
          type: array
          items:
            $ref: '#/components/schemas/UserProjectionDto'
        blendedFieldsConfig:
          type: object
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
        availableForReporting:
          type: boolean
          example: true
        availableForMaintenance:
          type: boolean
          example: true
        contexts:
          type: array
          items:
            type: object
      required:
        - id
        - title
        - status
        - storage
        - definitionType
        - definition
        - description
        - schema
        - triggersCount
        - reportsCount
        - createdByUser
        - businessOwnerUsers
        - technicalOwnerUsers
        - createdAt
        - modifiedAt
        - availableForReporting
        - availableForMaintenance
        - contexts
    DataMartAiHelperAvailabilityResponseApiDto:
      type: object
      properties:
        enabled:
          type: boolean
          description: >-
            Whether AI-powered metadata generation is configured on this
            deployment. When false, frontend SHOULD hide the AI-helper buttons.
      required:
        - enabled
    UpdateDataMartDefinitionApiDto:
      type: object
      properties:
        definitionType:
          type: string
          enum:
            - SQL
            - TABLE
            - VIEW
            - TABLE_PATTERN
            - CONNECTOR
          example: SQL
        definition:
          type: object
        sourceDataMartId:
          type: string
          description: Source Data Mart ID to copy secrets from
        sourceConfigurationId:
          type: string
          description: Source configuration ID to copy from
      required:
        - definitionType
        - definition
    UpdateDataMartTitleApiDto:
      type: object
      properties:
        title:
          type: string
      required:
        - title
    UpdateDataMartDescriptionApiDto:
      type: object
      properties:
        description:
          type: string
          nullable: true
    UpdateDataMartOwnersApiDto:
      type: object
      properties:
        businessOwnerIds:
          type: array
          items:
            type: string
        technicalOwnerIds:
          type: array
          items:
            type: string
      required:
        - businessOwnerIds
        - technicalOwnerIds
    UpdateEntityContextsRequestApiDto:
      type: object
      properties:
        contextIds:
          type: array
          items:
            type: string
      required:
        - contextIds
    RunDataMartRequestApiDto:
      type: object
      properties:
        payload:
          type: object
          example:
            key: value
          description: |-
            Payload for the manual run.
                If not provided, the data mart will be run with the default payload.
                The payload is specific to the data mart definition type.
                For example, for a connector data mart, the payload is the connector configuration fields with unknown structure.
    DataMartValidationResponseApiDto:
      type: object
      properties:
        valid:
          type: boolean
        errorMessage:
          type: string
        reason:
          type: object
        details:
          type: object
      required:
        - valid
        - errorMessage
        - reason
        - details
    UpdateDataMartSchemaApiDto:
      type: object
      properties:
        schema:
          type: object
          description: Updated schema of the data mart
      required:
        - schema
    BlendedFieldOverrideApiDto:
      type: object
      properties:
        alias:
          type: string
          description: Optional custom alias shown in reports for this blended field.
        isHidden:
          type: boolean
        aggregateFunction:
          type: string
          enum:
            - STRING_AGG
            - MAX
            - MIN
            - SUM
            - COUNT
            - COUNT_DISTINCT
            - ANY_VALUE
    BlendedSourceApiDto:
      type: object
      properties:
        path:
          type: string
          description: >-
            Dot-separated chain of target aliases identifying the blended data
            mart.
          example: orders.items
          pattern: ^[a-z0-9_]+(\.[a-z0-9_]+)*$
        alias:
          type: string
          description: Display label shown in report column headers.
          example: Orders
        isExcluded:
          type: boolean
        fields:
          type: object
          description: >-
            Per-field overrides keyed by original field name. Values must match
            the blended field override shape.
          additionalProperties:
            $ref: '#/components/schemas/BlendedFieldOverrideApiDto'
      required:
        - path
        - alias
    BlendedFieldsConfigApiDto:
      type: object
      properties:
        sources:
          type: array
          items:
            $ref: '#/components/schemas/BlendedSourceApiDto'
      required:
        - sources
    UpdateBlendedFieldsConfigApiDto:
      type: object
      properties:
        blendedFieldsConfig:
          nullable: true
          description: Pass `null` to clear the blended fields config.
          type: object
          allOf:
            - $ref: '#/components/schemas/BlendedFieldsConfigApiDto'
    DataMartRunsResponseApiDto:
      type: object
      properties:
        runs:
          type: array
          items:
            type: string
      required:
        - runs
    DataMartRunStatus:
      type: string
      enum:
        - PENDING
        - RUNNING
        - SUCCESS
        - FAILED
        - CANCELLED
        - INTERRUPTED
        - RESTRICTED
      description: Final status of the run
    DataMartRunType:
      type: string
      enum:
        - CONNECTOR
        - GOOGLE_SHEETS_EXPORT
        - LOOKER_STUDIO
        - EMAIL
        - SLACK
        - MS_TEAMS
        - GOOGLE_CHAT
        - INSIGHT
        - INSIGHT_TEMPLATE
        - AI_ASSISTANT
        - HTTP_DATA
      description: Run type (connector, report, insight)
    RunType:
      type: string
      enum:
        - manual
        - scheduled
      description: Run trigger type (manual, scheduled)
    DataMartRunResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 0b0f5a1e-6f66-4a7d-8b8d-123456789abc
        status:
          example: SUCCESS
          description: Final status of the run
          allOf:
            - $ref: '#/components/schemas/DataMartRunStatus'
        type:
          example: CONNECTOR
          description: Run type (connector, report, insight)
          allOf:
            - $ref: '#/components/schemas/DataMartRunType'
        runType:
          example: manual
          description: Run trigger type (manual, scheduled)
          allOf:
            - $ref: '#/components/schemas/RunType'
        dataMartId:
          type: string
          example: a5c9b1d2-3456-7890-abcd-ef0123456789
        definitionRun:
          type: object
          example:
            connector:
              source:
                name: Example
          description: Masked definition snapshot at run time
          nullable: true
        reportId:
          type: object
          example: 44c7b3e4-5d6f-7a8b-9c0d-112233445566
          nullable: true
        reportDefinition:
          type: object
          example:
            title: Quarterly export
            destination:
              type: GOOGLE_SHEETS
          nullable: true
        insightId:
          type: object
          example: a1b2c3d4-e5f6-7890-abcd-ef0123456789
          nullable: true
        insightDefinition:
          type: object
          example:
            title: Analysis Q4 2025
            template: Template text with prompts
          nullable: true
        insightTemplateId:
          type: object
          example: a1b2c3d4-e5f6-7890-abcd-ef0123456789
          nullable: true
        insightTemplateDefinition:
          type: object
          example:
            title: Summary
            template: '### Summary\n{{table source="main"}}'
            sources:
              - key: main
                type: CURRENT_DATA_MART
                kind: TABLE
          nullable: true
        aiSourceDefinition:
          type: object
          example:
            sessionId: e7f7e087-2042-4de0-b1fc-67dddbaf88dd
            scope: template
            route: full_generation
            templateId: 6f093b03-30c1-43e0-b9ed-6d87d33edf15
            artifactId: null
            turnId: 6742f3e8-1a02-4642-bbf4-e7f8710f9507
          nullable: true
        logs:
          type: object
          example:
            - '{"type":"log","at":"2025-10-09T15:13:06.930Z","message":"Started"}'
          nullable: true
        errors:
          type: object
          example:
            - '{"type":"error","at":"2025-10-09T15:14:06.930Z","error":"Failure"}'
          nullable: true
        createdAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
        startedAt:
          type: object
          example: '2025-10-09T15:14:06.930Z'
          nullable: true
        finishedAt:
          type: object
          example: '2025-10-09T15:20:06.930Z'
          nullable: true
        additionalParams:
          type: object
          example:
            httpData:
              format: ndjson
              columns:
                - date
              rowCount: 10
              completed: true
          description: >-
            Run-type-specific metadata captured by the use case (e.g. `httpData`
            for HTTP Data API runs)
          nullable: true
      required:
        - id
        - status
        - type
        - runType
        - dataMartId
        - createdAt
    BatchDataMartHealthStatusRequestApiDto:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
      required:
        - ids
    BatchDataMartHealthStatusItemApiDto:
      type: object
      properties:
        dataMartId:
          type: string
        connector:
          type: object
          nullable: true
        report:
          type: object
          nullable: true
        insight:
          type: object
          nullable: true
      required:
        - dataMartId
    BatchDataMartHealthStatusResponseApiDto:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/BatchDataMartHealthStatusItemApiDto'
      required:
        - items
    UpdateDataMartAvailabilityApiDto:
      type: object
      properties:
        availableForReporting:
          type: boolean
          description: Whether the DataMart is available for reporting
          example: true
        availableForMaintenance:
          type: boolean
          description: Whether the DataMart is available for maintenance
          example: false
      required:
        - availableForReporting
        - availableForMaintenance
    BlendableSchemaDto:
      type: object
      properties: {}
    DataStorageListResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: abc123e4-5678-90ab-cdef-1234567890ab
        title:
          type: string
          example: title
        type:
          type: string
          enum:
            - GOOGLE_BIGQUERY
            - AWS_ATHENA
            - SNOWFLAKE
            - AWS_REDSHIFT
            - DATABRICKS
            - LEGACY_GOOGLE_BIGQUERY
          example: GOOGLE_BIGQUERY
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
        publishedDataMartsCount:
          type: number
          example: 0
        draftDataMartsCount:
          type: number
          example: 0
        createdByUser:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/UserProjectionDto'
        ownerUsers:
          type: array
          items:
            $ref: '#/components/schemas/UserProjectionDto'
        contexts:
          type: array
          items:
            type: object
        availableForUse:
          type: boolean
          example: true
        availableForMaintenance:
          type: boolean
          example: true
      required:
        - id
        - title
        - type
        - createdAt
        - modifiedAt
        - publishedDataMartsCount
        - draftDataMartsCount
        - ownerUsers
        - contexts
        - availableForUse
        - availableForMaintenance
    UpdateDataStorageApiDto:
      type: object
      properties:
        title:
          type: string
          description: Custom title for the data storage
          maxLength: 255
        credentials:
          type: object
          additionalProperties: true
          description: Credentials required for the selected storage type
        config:
          type: object
          additionalProperties: true
          description: Configuration specific to the storage type
        credentialId:
          type: string
          nullable: true
        sourceStorageId:
          type: string
          description: >-
            Source Storage ID to copy credentials from (mutually exclusive with
            credentials)
        ownerIds:
          type: array
          items:
            type: string
        availableForUse:
          type: boolean
          description: Whether this storage is available for use by project members
        availableForMaintenance:
          type: boolean
          description: Whether this storage is available for maintenance by project members
        contextIds:
          description: Context IDs attached to this storage (full replacement)
          type: array
          items:
            type: string
      required:
        - title
        - credentials
        - config
    CreateDataStorageApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - GOOGLE_BIGQUERY
            - AWS_ATHENA
            - SNOWFLAKE
            - AWS_REDSHIFT
            - DATABRICKS
            - LEGACY_GOOGLE_BIGQUERY
        ownerIds:
          type: array
          items:
            type: string
      required:
        - type
    DataStorageByTypeResponseApiDto:
      type: object
      properties:
        id:
          type: string
          description: Data Storage ID
        title:
          type: string
          description: Data Storage title
        dataMartName:
          type: string
          description: Name of the Data Mart that uses this storage (null if none)
          nullable: true
        identity:
          type: object
          description: Credential identity (display info, no secrets)
          additionalProperties: true
          nullable: true
      required:
        - id
        - title
        - dataMartName
        - identity
    GoogleOAuthSettingsResponseDto:
      type: object
      properties:
        available:
          type: boolean
          example: true
          description: Whether OAuth is configured for this resource type
        authorizationEndpoint:
          type: string
          example: https://accounts.google.com/o/oauth2/v2/auth
          description: Google OAuth authorization endpoint
        clientId:
          type: string
          example: 123456789-abcdefghijklmnop.apps.googleusercontent.com
          description: OAuth client ID (public, safe to expose to frontend)
        redirectUri:
          type: string
          example: https://app.owox.com/api/google-oauth/callback
          description: OAuth redirect URI configured in Google Console
        availableScopes:
          example:
            - https://www.googleapis.com/auth/bigquery
          description: Available OAuth scopes for this resource type
          type: array
          items:
            type: string
      required:
        - available
    ExchangeAuthorizationCodeRequestDto:
      type: object
      properties:
        code:
          type: string
          example: 4/0AfJohXk1234567890abcdefghijklmnopqrstuvwxyz
          description: Authorization code from Google OAuth callback
        state:
          type: string
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9qZWN0SWQiOiJ...
          description: State token from authorization URL (CSRF validation)
      required:
        - code
        - state
    GoogleOAuthUserDto:
      type: object
      properties:
        id:
          type: string
          example: '1234567890'
          description: Google user ID
        name:
          type: string
          example: John Doe
          description: User display name
        email:
          type: string
          example: john.doe@example.com
          description: User email address
        picture:
          type: string
          example: https://lh3.googleusercontent.com/a/default-user
          description: User profile picture URL
    ExchangeAuthorizationCodeResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
          description: Whether token exchange was successful
        credentialId:
          type: string
          example: 550e8400-e29b-41d4-a716-446655440000
          description: Created credential ID (UUID)
        user:
          description: Google user who authorized the app
          allOf:
            - $ref: '#/components/schemas/GoogleOAuthUserDto'
        warnings:
          example:
            - >-
              Token will expire in 1 hour. Refresh token available for automatic
              renewal.
          description: Optional warnings or informational messages
          type: array
          items:
            type: string
      required:
        - success
        - credentialId
    StorageNamespaceNodeDto:
      type: object
      properties:
        id:
          type: string
          description: Namespace identifier (e.g. GCP project ID, Snowflake database name)
          example: my-gcp-project
        label:
          type: string
          description: Human-friendly name when different from id
          example: My GCP Project
      required:
        - id
    StorageResourceLeafDto:
      type: object
      properties:
        id:
          type: string
          description: Resource identifier (table or view name)
          example: orders
        groupId:
          type: string
          description: Parent group identifier (dataset, schema, …)
          example: analytics_prod
        type:
          type: string
          description: Resource type
          enum:
            - TABLE
            - VIEW
        fullyQualifiedName:
          type: string
          description: Fully qualified name ready to use in a Data Mart definition
          example: my-gcp-project.analytics_prod.orders
      required:
        - id
        - groupId
        - type
        - fullyQualifiedName
    ListStorageResourcesResponseDto:
      type: object
      properties:
        namespaces:
          type: array
          items:
            $ref: '#/components/schemas/StorageNamespaceNodeDto'
        resources:
          type: array
          items:
            $ref: '#/components/schemas/StorageResourceLeafDto'
    DataStorageAccessValidationResponseApiDto:
      type: object
      properties:
        valid:
          type: boolean
        errorMessage:
          type: string
        code:
          type: string
          enum:
            - UNCONFIGURED
          description: Machine-readable validation result code
      required:
        - valid
        - errorMessage
    GenerateAuthorizationUrlRequestDto:
      type: object
      properties:
        redirectUri:
          type: string
          example: https://app.owox.com/oauth-callback
          description: >-
            Frontend callback URL (must match registered redirect URI in Google
            Console)
      required:
        - redirectUri
    GenerateAuthorizationUrlResponseDto:
      type: object
      properties:
        authorizationUrl:
          type: string
          example: >-
            https://accounts.google.com/o/oauth2/v2/auth?client_id=123...&redirect_uri=https%3A%2F%2Fapp.owox.com%2Foauth-callback&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fbigquery&state=eyJhbGc...
          description: Complete authorization URL (redirect user to this URL)
        state:
          type: string
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9qZWN0SWQiOiJ...
          description: State token for CSRF protection (validate on OAuth callback)
      required:
        - authorizationUrl
        - state
    GoogleOAuthStatusResponseDto:
      type: object
      properties:
        isValid:
          type: boolean
          example: true
          description: Whether OAuth credentials exist and have a valid refresh token
        user:
          description: Google user who authorized the app
          allOf:
            - $ref: '#/components/schemas/GoogleOAuthUserDto'
        credentialId:
          type: string
          example: 550e8400-e29b-41d4-a716-446655440000
          description: Credential ID (UUID)
      required:
        - isValid
    UpdateStorageAvailabilityApiDto:
      type: object
      properties:
        availableForUse:
          type: boolean
          description: Whether the Data Storage is available for use
          example: true
        availableForMaintenance:
          type: boolean
          description: Whether the Data Storage is available for maintenance
          example: false
      required:
        - availableForUse
        - availableForMaintenance
    CreateDataDestinationApiDto:
      type: object
      properties:
        title:
          type: string
          example: My Google Sheets Destination
        type:
          type: string
          enum:
            - GOOGLE_SHEETS
            - LOOKER_STUDIO
            - EMAIL
            - SLACK
            - MS_TEAMS
            - GOOGLE_CHAT
        credentials:
          type: object
          additionalProperties: true
          description: >-
            Credentials required for the selected destination type (optional
            when sourceDestinationId is provided)
        credentialId:
          type: string
          description: Pre-created OAuth credential ID
        sourceDestinationId:
          type: string
          description: >-
            Source Destination ID to copy credentials from (mutually exclusive
            with credentials)
        ownerIds:
          type: array
          items:
            type: string
      required:
        - title
        - type
        - credentials
    DataDestinationResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: abc123e4-5678-90ab-cdef-1234567890ab
        title:
          type: string
          example: My Google Sheets Destination
        type:
          type: string
          enum:
            - GOOGLE_SHEETS
            - LOOKER_STUDIO
            - EMAIL
            - SLACK
            - MS_TEAMS
            - GOOGLE_CHAT
          example: GOOGLE_SHEETS
        projectId:
          type: string
          example: my-project
        credentials:
          type: object
          additionalProperties: true
          description: Credentials without sensitive fields
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
        credentialId:
          type: object
          example: abc123e4-5678-90ab-cdef-1234567890ab
          nullable: true
        createdByUser:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/UserProjectionDto'
        ownerUsers:
          type: array
          items:
            $ref: '#/components/schemas/UserProjectionDto'
        availableForUse:
          type: boolean
          example: true
        availableForMaintenance:
          type: boolean
          example: true
        contexts:
          type: array
          items:
            type: object
      required:
        - id
        - title
        - type
        - projectId
        - credentials
        - createdAt
        - modifiedAt
        - ownerUsers
        - availableForUse
        - availableForMaintenance
        - contexts
    DataDestinationByTypeResponseApiDto:
      type: object
      properties:
        id:
          type: string
          description: Data Destination ID
        title:
          type: string
          description: Data Destination title
        dataMartName:
          type: string
          description: Name of the Data Mart that uses this destination (null if none)
          nullable: true
        identity:
          type: object
          description: Credential identity (display info, no secrets)
          additionalProperties: true
          nullable: true
      required:
        - id
        - title
        - dataMartName
        - identity
    UpdateDataDestinationApiDto:
      type: object
      properties:
        title:
          type: string
          example: My Updated Google Sheets Destination
        credentials:
          type: object
          additionalProperties: true
          description: Credentials required for the selected destination type
        credentialId:
          type: object
          example: abc123e4-5678-90ab-cdef-1234567890ab
          nullable: true
          description: Credential ID for OAuth-based authentication (null to disconnect)
        sourceDestinationId:
          type: string
          description: >-
            Source Destination ID to copy credentials from (mutually exclusive
            with credentials)
        ownerIds:
          type: array
          items:
            type: string
        availableForUse:
          type: boolean
          description: Whether this destination is available for use by project members
        availableForMaintenance:
          type: boolean
          description: >-
            Whether this destination is available for maintenance by project
            members
        contextIds:
          description: Context IDs attached to this destination (full replacement)
          type: array
          items:
            type: string
      required:
        - title
        - credentials
    DataDestinationImpactResponseApiDto:
      type: object
      properties:
        destinationId:
          type: string
          example: abc123e4-5678-90ab-cdef-1234567890ab
        destinationTitle:
          type: string
          example: My Google Sheets Destination
        reportsCount:
          type: number
          example: 5
          description: Total number of reports referencing this destination.
        dataMartCount:
          type: number
          example: 3
          description: >-
            Number of distinct data marts whose reports reference this
            destination.
      required:
        - destinationId
        - destinationTitle
        - reportsCount
        - dataMartCount
    UpdateDestinationAvailabilityApiDto:
      type: object
      properties:
        availableForUse:
          type: boolean
          description: Whether the Data Destination is available for use
          example: true
        availableForMaintenance:
          type: boolean
          description: Whether the Data Destination is available for maintenance
          example: false
      required:
        - availableForUse
        - availableForMaintenance
    ReportBetweenFilterValueApiDto:
      type: object
      properties:
        from:
          oneOf:
            - type: string
            - type: number
            - type: boolean
        to:
          oneOf:
            - type: string
            - type: number
            - type: boolean
      required:
        - from
        - to
    ReportCustomMessageTemplateSourceApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - CUSTOM_MESSAGE
        config:
          type: object
          required:
            - messageTemplate
          properties:
            messageTemplate:
              type: string
              minLength: 1
      required:
        - type
    ReportEmailDestinationConfigApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - email-config
        subject:
          type: string
          minLength: 1
        templateSource:
          oneOf:
            - $ref: '#/components/schemas/ReportCustomMessageTemplateSourceApiDto'
            - $ref: '#/components/schemas/ReportInsightTemplateSourceApiDto'
        reportCondition:
          type: string
          enum:
            - ALWAYS
            - RESULT_IS_EMPTY
            - RESULT_IS_NOT_EMPTY
      required:
        - type
        - subject
        - templateSource
        - reportCondition
    ReportFilterRuleApiDto:
      type: object
      properties:
        column:
          type: string
          minLength: 1
        operator:
          type: string
          enum:
            - eq
            - neq
            - contains
            - not_contains
            - starts_with
            - ends_with
            - gt
            - lt
            - gte
            - lte
            - regex
            - not_regex
            - is_empty
            - is_not_empty
            - is_null
            - is_not_null
            - is_true
            - is_false
            - between
            - relative_date
        value:
          description: >-
            Required for scalar, between, and relative_date operators. Omit for
            is_empty/is_null-style operators.
          oneOf:
            - oneOf:
                - type: string
                - type: number
                - type: boolean
            - $ref: '#/components/schemas/ReportBetweenFilterValueApiDto'
            - $ref: '#/components/schemas/ReportRelativeDateFilterValueApiDto'
        placement:
          type: string
          enum:
            - pre-join
            - post-join
          description: Use pre-join for slice filters. Omit for normal output filters.
        aliasPath:
          type: string
          minLength: 1
          maxLength: 255
          pattern: ^[a-z0-9_]+(\.[a-z0-9_]+)*$
          description: Required for slice filters when placement is pre-join.
      required:
        - column
        - operator
    ReportGoogleSheetsDestinationConfigApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - google-sheets-config
        spreadsheetId:
          type: string
          minLength: 1
        sheetId:
          type: number
          minimum: 0
      required:
        - type
        - spreadsheetId
        - sheetId
    ReportInsightTemplateSourceApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - INSIGHT_TEMPLATE
        config:
          type: object
          required:
            - insightTemplateId
          properties:
            insightTemplateId:
              type: string
              minLength: 1
      required:
        - type
    ReportLegacyEmailDestinationConfigApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - email-config
        subject:
          type: string
          minLength: 1
        messageTemplate:
          type: string
          minLength: 1
        reportCondition:
          type: string
          enum:
            - ALWAYS
            - RESULT_IS_EMPTY
            - RESULT_IS_NOT_EMPTY
      required:
        - type
        - subject
        - messageTemplate
        - reportCondition
    ReportLookerStudioDestinationConfigApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - looker-studio-config
        cacheLifetime:
          type: number
          minimum: 60
      required:
        - type
        - cacheLifetime
    ReportRelativeDateFilterValueApiDto:
      type: object
      properties:
        kind:
          type: string
          enum:
            - today
            - yesterday
            - this_month
            - last_month
            - this_year
            - last_n_days
            - last_n_months
        'n':
          type: number
          description: Required when kind is last_n_days or last_n_months.
          minimum: 1
          maximum: 3650
      required:
        - kind
    ReportSortRuleApiDto:
      type: object
      properties:
        column:
          type: string
          minLength: 1
          description: Output column name to sort by.
          example: date
        direction:
          type: string
          enum:
            - asc
            - desc
          description: Sort direction for this column.
      required:
        - column
        - direction
    ReportResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        title:
          type: string
          example: My Report
        dataMart:
          $ref: '#/components/schemas/DataMartResponseApiDto'
        dataDestinationAccess:
          $ref: '#/components/schemas/DataDestinationResponseApiDto'
        destinationConfig:
          type: object
          additionalProperties: true
          description: Configuration for the data destination
        columnConfig:
          nullable: true
          type: array
          items:
            type: string
        filterConfig:
          type: array
          nullable: true
          description: Filter rules
          items:
            type: object
        sortConfig:
          type: array
          nullable: true
          description: Sort rules
          items:
            type: object
        limitConfig:
          type: integer
          nullable: true
          description: Row limit
        lastRunAt:
          format: date-time
          type: string
          nullable: true
        lastRunStatus:
          type: string
          enum:
            - SUCCESS
            - ERROR
            - RUNNING
            - CANCELLED
            - RESTRICTED
          nullable: true
        lastRunError:
          type: string
          nullable: true
        runsCount:
          type: number
          example: 0
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
        createdByUser:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/UserProjectionDto'
        ownerUsers:
          type: array
          items:
            $ref: '#/components/schemas/UserProjectionDto'
        canRun:
          type: boolean
          example: true
          description: Whether the caller can manually run this report
        canManageTriggers:
          type: boolean
          example: true
          description: >-
            Whether the caller can create / edit / delete report triggers. Equal
            to canRun today.
        canEditConfig:
          type: boolean
          example: false
          description: >-
            Whether the caller can edit the report configuration (columns,
            filters, owners, destination)
      required:
        - id
        - title
        - dataMart
        - dataDestinationAccess
        - destinationConfig
        - lastRunAt
        - lastRunStatus
        - lastRunError
        - runsCount
        - createdAt
        - modifiedAt
        - ownerUsers
        - canRun
        - canManageTriggers
        - canEditConfig
    CreateInsightRequestApiDto:
      type: object
      properties:
        title:
          type: string
          example: Analysis Q4 2025
          maxLength: 255
        template:
          type: string
          example: Template text with prompts
      required:
        - title
    InsightResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: b1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890
        title:
          type: string
          example: Analysis Q4 2025
        template:
          type: object
          example: Template text with prompts
          nullable: true
        output:
          type: object
          example: 'Executive summary: ...'
          nullable: true
        outputUpdatedAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
          nullable: true
          description: Timestamp when the output field was last updated
        createdById:
          type: string
          example: 540734f6-8eb1-48a9-bf86-22010d3bddfd
        createdAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
        modifiedAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
        lastManualDataMartRun:
          nullable: true
          description: Latest manual DataMart run for this Insight
          type: object
          allOf:
            - $ref: '#/components/schemas/DataMartRunResponseApiDto'
      required:
        - id
        - title
        - createdById
        - createdAt
        - modifiedAt
    InsightListItemResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: b1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890
        title:
          type: string
          example: Analysis Q4 2025
        outputUpdatedAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
          nullable: true
          description: Timestamp when the output field was last updated
        createdById:
          type: string
          example: 540734f6-8eb1-48a9-bf86-22010d3bddfd
        createdAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
        modifiedAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
      required:
        - id
        - title
        - createdById
        - createdAt
        - modifiedAt
    UpdateInsightRequestApiDto:
      type: object
      properties:
        title:
          type: string
          example: New Title for Analysis Q4 2025
          maxLength: 255
        template:
          type: string
          example: New template text with prompts
      required:
        - title
    UpdateInsightTitleApiDto:
      type: object
      properties:
        title:
          type: string
          maxLength: 255
      required:
        - title
    AiAssistantScope:
      type: string
      enum:
        - template
    CreateAiAssistantSessionRequestApiDto:
      type: object
      properties:
        scope:
          example: template
          allOf:
            - $ref: '#/components/schemas/AiAssistantScope'
        templateId:
          type: string
          description: Insight Template id context for template scope
          example: 6f093b03-30c1-43e0-b9ed-6d87d33edf15
      required:
        - scope
        - templateId
    CreateAiAssistantSessionResponseApiDto:
      type: object
      properties:
        sessionId:
          type: string
          example: e7f7e087-2042-4de0-b1fc-67dddbaf88dd
          description: Created AI source assistant session id
      required:
        - sessionId
    AiAssistantSessionListItemResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: e7f7e087-2042-4de0-b1fc-67dddbaf88dd
        dataMartId:
          type: string
          example: a5c9b1d2-3456-7890-abcd-ef0123456789
        scope:
          example: template
          allOf:
            - $ref: '#/components/schemas/AiAssistantScope'
        title:
          type: object
          nullable: true
          example: Revenue by source
        templateId:
          type: object
          nullable: true
          example: 6f093b03-30c1-43e0-b9ed-6d87d33edf15
        createdAt:
          type: object
          example: '2026-02-15T16:10:06.930Z'
        updatedAt:
          type: object
          example: '2026-02-15T16:10:07.930Z'
      required:
        - id
        - dataMartId
        - scope
        - createdAt
        - updatedAt
    AiAssistantMessageRole:
      type: string
      enum:
        - user
        - assistant
        - system
    AiAssistantMessageApplyStatus:
      type: string
      enum:
        - none
        - pending
        - applied
      description: Apply lifecycle state for this assistant message
    AiAssistantMessageResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 4fce612f-6a4c-4ccf-a97d-92c69fd6230a
        sessionId:
          type: string
          example: e7f7e087-2042-4de0-b1fc-67dddbaf88dd
        role:
          example: user
          allOf:
            - $ref: '#/components/schemas/AiAssistantMessageRole'
        content:
          type: string
          example: Show monthly consumption by product for 2025
        proposedActions:
          type: array
          items:
            type: object
          nullable: true
          description: Explicit list of available actions proposed by the assistant
        sqlCandidate:
          type: object
          nullable: true
          description: SQL candidate generated by assistant for apply/preview
          example: SELECT date, SUM(revenue) FROM orders GROUP BY date
        applyStatus:
          example: pending
          description: Apply lifecycle state for this assistant message
          allOf:
            - $ref: '#/components/schemas/AiAssistantMessageApplyStatus'
        appliedAt:
          type: object
          nullable: true
          example: '2026-02-20T18:20:00.000Z'
          description: Timestamp of successful apply
        appliedRequestId:
          type: object
          nullable: true
          example: act_123
          description: Action request id that was applied
        createdAt:
          type: object
          example: '2026-02-15T16:10:06.930Z'
      required:
        - id
        - sessionId
        - role
        - content
        - applyStatus
        - createdAt
    AiAssistantSessionResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: e7f7e087-2042-4de0-b1fc-67dddbaf88dd
        dataMartId:
          type: string
          example: a5c9b1d2-3456-7890-abcd-ef0123456789
        scope:
          example: template
          allOf:
            - $ref: '#/components/schemas/AiAssistantScope'
        title:
          type: object
          nullable: true
          example: Revenue by source
        templateId:
          type: object
          nullable: true
          example: 6f093b03-30c1-43e0-b9ed-6d87d33edf15
        createdById:
          type: string
          example: '0'
        createdAt:
          type: object
          example: '2026-02-15T16:10:06.930Z'
        updatedAt:
          type: object
          example: '2026-02-15T16:10:07.930Z'
        messages:
          type: array
          items:
            $ref: '#/components/schemas/AiAssistantMessageResponseApiDto'
      required:
        - id
        - dataMartId
        - scope
        - createdById
        - createdAt
        - updatedAt
        - messages
    UpdateAiAssistantSessionTitleRequestApiDto:
      type: object
      properties:
        title:
          type: string
          maxLength: 255
      required:
        - title
    CreateAiAssistantMessageRequestApiDto:
      type: object
      properties:
        text:
          type: string
          description: New user message text
          example: Build SQL source with monthly product consumption for 2025
      required:
        - text
    AiAssistantExecutionModeApi:
      type: string
      enum:
        - lightweight
        - heavy
    CreateAiAssistantMessageResponseApiDto:
      type: object
      properties:
        mode:
          example: lightweight
          allOf:
            - $ref: '#/components/schemas/AiAssistantExecutionModeApi'
        triggerId:
          type: object
          nullable: true
          description: Trigger id for heavy route execution
          example: 550e8400-e29b-41d4-a716-446655440000
        response:
          type: object
          nullable: true
          description: Lightweight assistant response payload
          example:
            status: cannot_answer
            decision: explain_or_status
            explanation: AI source orchestration is not configured yet.
            meta:
              lastUserMessage: Build SQL source
              sanitizedLastUserMessage: Build SQL source
              reasonDescription: Session API endpoint is available.
              telemetry:
                llmCalls: []
                toolCalls: []
                messageHistory: []
        userMessage:
          $ref: '#/components/schemas/AiAssistantMessageResponseApiDto'
        assistantMessage:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/AiAssistantMessageResponseApiDto'
      required:
        - mode
        - userMessage
    ApplyAiAssistantSessionRequestApiDto:
      type: object
      properties:
        requestId:
          type: string
          description: Apply action id returned in assistant response.proposedActions[].id
          example: act_7ce2f8ad0ea74745a43fc3ae59f2f8f8_0
        assistantMessageId:
          type: string
          description: Assistant message id that owns selected apply action
          example: 57bba70a-8ad8-4edc-8b3e-ec45f51dc486
        sql:
          type: string
          description: >-
            SQL override. When omitted, latest SQL candidate from assistant
            message is used
          example: SELECT * FROM ${DATA_MART_TABLE}
        sourceTitle:
          type: string
          description: Title override for created or updated source
          example: Monthly product consumption source
      required:
        - requestId
        - assistantMessageId
    ApplyAiAssistantSessionResponseApiDto:
      type: object
      properties:
        requestId:
          type: string
          description: Idempotency key associated with apply operation
          example: 8ea56dbc-f6ad-47a4-9f05-f7c4e7594ecb
        artifactId:
          type: object
          description: Artifact id that received SQL apply
          nullable: true
          example: 6742f3e8-1a02-4642-bbf4-e7f8710f9507
        sourceTitle:
          type: object
          description: Source title after apply
          nullable: true
          example: Monthly product consumption source
        templateUpdated:
          type: boolean
          description: Whether template sources/template text changed
          example: true
        templateId:
          type: object
          description: Template id that was updated
          nullable: true
          example: 6f093b03-30c1-43e0-b9ed-6d87d33edf15
        sourceKey:
          type: object
          description: Source key added/used in template
          nullable: true
          example: monthly_consumption
        status:
          type: string
          description: Structured apply status
          enum:
            - updated
            - already_present
            - no_op
            - validation_failed
          example: updated
        reason:
          type: object
          description: Optional structured reason for apply status
          nullable: true
          example: replace_template_document
      required:
        - requestId
        - templateUpdated
        - status
    CreateInsightArtifactRequestApiDto:
      type: object
      properties:
        title:
          type: string
          example: Source
          maxLength: 255
        sql:
          type: string
          example: SELECT * FROM table LIMIT 100
      required:
        - title
        - sql
    InsightArtifactResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: fd6b79dd-72f5-4c8b-aec9-cf12024259d4
        title:
          type: string
          example: Source
        sql:
          type: string
          example: SELECT * FROM table LIMIT 100
        validationStatus:
          type: string
          enum:
            - VALID
            - ERROR
        validationError:
          type: object
          nullable: true
          example: null
        createdById:
          type: string
          example: 540734f6-8eb1-48a9-bf86-22010d3bddfd
        createdAt:
          type: object
          example: '2026-02-14T15:13:06.930Z'
        modifiedAt:
          type: object
          example: '2026-02-14T15:13:06.930Z'
      required:
        - id
        - title
        - sql
        - validationStatus
        - createdById
        - createdAt
        - modifiedAt
    InsightArtifactListItemResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: fd6b79dd-72f5-4c8b-aec9-cf12024259d4
        title:
          type: string
          example: Source
        validationStatus:
          type: string
          enum:
            - VALID
            - ERROR
        validationError:
          type: object
          nullable: true
          example: null
        createdById:
          type: string
          example: 540734f6-8eb1-48a9-bf86-22010d3bddfd
        createdAt:
          type: object
          example: '2026-02-14T15:13:06.930Z'
        modifiedAt:
          type: object
          example: '2026-10-14T15:13:06.930Z'
      required:
        - id
        - title
        - validationStatus
        - createdById
        - createdAt
        - modifiedAt
    UpdateInsightArtifactRequestApiDto:
      type: object
      properties:
        title:
          type: string
          example: Source (updated)
          maxLength: 255
        sql:
          type: string
          example: SELECT order_id, amount FROM table LIMIT 100
      required:
        - title
        - sql
    UpdateInsightArtifactTitleApiDto:
      type: object
      properties:
        title:
          type: string
          maxLength: 255
      required:
        - title
    RunInsightArtifactSqlPreviewRequestApiDto:
      type: object
      properties:
        sql:
          type: string
          description: Optional SQL override. If omitted, saved artifact SQL is executed.
          example: SELECT * FROM table LIMIT 10
    InsightTemplateSourceApiDto:
      type: object
      properties:
        templateSourceId:
          type: object
          nullable: true
        key:
          type: string
          example: last_30d
          maxLength: 64
        type:
          type: string
          enum:
            - CURRENT_DATA_MART
            - INSIGHT_ARTIFACT
        artifactId:
          type: object
          nullable: true
      required:
        - key
        - type
    CreateInsightTemplateRequestApiDto:
      type: object
      properties:
        title:
          type: string
          example: Summary
          maxLength: 255
        template:
          type: string
          example: |-
            ### Summary
            {{table source="main"}}
        sources:
          type: array
          items:
            $ref: '#/components/schemas/InsightTemplateSourceApiDto'
      required:
        - title
    InsightTemplateResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: b1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890
        title:
          type: string
          example: Summary
        template:
          type: object
          example: |-
            ### Summary
            {{table source="main"}}
          nullable: true
        sources:
          type: array
          items:
            $ref: '#/components/schemas/InsightTemplateSourceApiDto'
        lastRenderedTemplate:
          type: object
          nullable: true
        lastRenderedTemplateUpdatedAt:
          type: object
          nullable: true
        createdById:
          type: string
          example: 540734f6-8eb1-48a9-bf86-22010d3bddfd
        createdAt:
          type: object
          example: '2026-02-14T15:13:06.930Z'
        modifiedAt:
          type: object
          example: '2026-02-14T15:13:06.930Z'
        lastManualDataMartRun:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/DataMartRunResponseApiDto'
        createdByUser:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/UserProjectionDto'
      required:
        - id
        - title
        - template
        - sources
        - lastRenderedTemplate
        - lastRenderedTemplateUpdatedAt
        - createdById
        - createdAt
        - modifiedAt
        - lastManualDataMartRun
    InsightTemplateListItemResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: b1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890
        title:
          type: string
          example: Summary
        sourcesCount:
          type: number
          example: 1
          description: Number of configured sources in template
        lastRenderedTemplateUpdatedAt:
          type: object
          nullable: true
        createdById:
          type: string
          example: 540734f6-8eb1-48a9-bf86-22010d3bddfd
        createdAt:
          type: object
          example: '2026-02-14T15:13:06.930Z'
        modifiedAt:
          type: object
          example: '2026-02-14T15:13:06.930Z'
        createdByUser:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/UserProjectionDto'
      required:
        - id
        - title
        - sourcesCount
        - lastRenderedTemplateUpdatedAt
        - createdById
        - createdAt
        - modifiedAt
    UpdateInsightTemplateRequestApiDto:
      type: object
      properties:
        title:
          type: string
          example: Summary (updated)
          maxLength: 255
        template:
          type: string
          example: |-
            ## Updated
            {{table source="main"}}
        sources:
          type: array
          items:
            $ref: '#/components/schemas/InsightTemplateSourceApiDto'
      required:
        - title
    UpdateInsightTemplateTitleApiDto:
      type: object
      properties:
        title:
          type: string
          maxLength: 255
      required:
        - title
    InsightTemplateSourceDetailsApiDto:
      type: object
      properties:
        templateSourceId:
          type: string
          example: 2c8f6b71-7f8f-4e8e-8f31-5f6fd4e2a0f4
        key:
          type: string
          example: projects_2025
        artifactId:
          type: string
          example: be08ff51-8d9f-4a4f-9751-7fc534835755
        title:
          type: string
          example: Projects created in 2025
        sql:
          type: string
          example: >-
            SELECT COUNT(*) AS value FROM projects WHERE EXTRACT(YEAR FROM
            created_at) = 2025
        validationStatus:
          type: string
          enum:
            - VALID
            - ERROR
        validationError:
          type: object
          nullable: true
          example: null
        createdById:
          type: string
          example: 540734f6-8eb1-48a9-bf86-22010d3bddfd
        createdAt:
          type: object
          example: '2026-03-03T11:28:33.000Z'
        modifiedAt:
          type: object
          example: '2026-03-03T11:31:47.000Z'
      required:
        - templateSourceId
        - key
        - artifactId
        - title
        - sql
        - validationStatus
        - createdById
        - createdAt
        - modifiedAt
    CreateInsightTemplateSourceRequestApiDto:
      type: object
      properties:
        key:
          type: string
          example: projects_2025
          maxLength: 64
        title:
          type: string
          example: Projects created in 2025
          maxLength: 255
        sql:
          type: string
          example: >-
            SELECT COUNT(*) AS value FROM projects WHERE EXTRACT(YEAR FROM
            created_at) = 2025
      required:
        - key
        - title
        - sql
    UpdateInsightTemplateSourceRequestApiDto:
      type: object
      properties:
        title:
          type: string
          example: Projects created in 2025 (updated)
          maxLength: 255
        sql:
          type: string
          example: >-
            SELECT COUNT(1) AS value FROM projects WHERE created_at >=
            '2025-01-01' AND created_at < '2026-01-01'
      required:
        - title
        - sql
    ConnectorDefinitionResponseApiDto:
      type: object
      properties:
        name:
          type: string
          example: FacebookMarketing
        title:
          type: string
          example: Facebook Marketing
        description:
          type: object
          example: Connect to Facebook Marketing API
          nullable: true
        logo:
          type: object
          example: base64-encoded-logo
          nullable: true
        docUrl:
          type: object
          example: >-
            https://docs.owox.com/packages/connectors/src/sources/tik-tok-ads/readme/
          nullable: true
      required:
        - name
        - title
        - description
        - logo
        - docUrl
    ConnectorSpecificationItemResponseApiDto:
      type: object
      properties:
        name:
          type: string
          example: accessToken
        title:
          type: string
          example: Access Token
        description:
          type: string
          example: Your Facebook access token
        default:
          type: object
          example: default_value
        requiredType:
          type: string
          enum:
            - string
            - number
            - boolean
            - bool
            - object
            - array
            - date
          example: string
        required:
          type: boolean
          example: true
        options:
          example:
            - option1
            - option2
          type: array
          items:
            type: string
        placeholder:
          type: string
          example: Enter your access token...
        attributes:
          example:
            - MANUAL_BACKFILL
            - HIDE_IN_UI
          type: array
          items:
            type: string
      required:
        - name
    ConnectorSpecificationOneOfOptionResponseApiDto:
      type: object
      properties:
        label:
          type: string
          example: Access Token
        value:
          type: string
          example: accessToken
        requiredType:
          type: string
          enum:
            - string
            - number
            - boolean
            - bool
            - object
            - array
            - date
          example: string
        attributes:
          example:
            - SECRET
            - OAUTH_FLOW
          type: array
          items:
            type: string
        items:
          example:
            - name: apiKey
              title: API Key
              description: Your API key
              default: default_value
              requiredType: string
              required: true
              options:
                - option1
                - option2
              placeholder: Enter your API key...
              attributes:
                - MANUAL_BACKFILL
                - HIDE_IN_UI
          type: array
          items:
            $ref: '#/components/schemas/ConnectorSpecificationItemResponseApiDto'
      required:
        - label
        - value
        - items
    ConnectorSpecificationResponseApiDto:
      type: object
      properties:
        name:
          type: string
          example: accessToken
        title:
          type: string
          example: Access Token
        description:
          type: string
          example: Your Facebook access token
        default:
          type: object
          example: default_value
        requiredType:
          type: string
          enum:
            - string
            - number
            - boolean
            - bool
            - object
            - array
            - date
          example: string
        required:
          type: boolean
          example: true
        options:
          example:
            - option1
            - option2
          type: array
          items:
            type: string
        placeholder:
          type: string
          example: Enter your access token...
        attributes:
          example:
            - MANUAL_BACKFILL
            - HIDE_IN_UI
          type: array
          items:
            type: string
        oneOf:
          example:
            - label: Access Token
              value: accessToken
              requiredType: string
              items:
                - name: apiKey
                  title: API Key
                  description: Your API key
                  default: default_value
                  requiredType: string
                  required: true
                  options:
                    - option1
                    - option2
                  placeholder: Enter your API key...
                  attributes:
                    - MANUAL_BACKFILL
                    - HIDE_IN_UI
          type: array
          items:
            $ref: >-
              #/components/schemas/ConnectorSpecificationOneOfOptionResponseApiDto
      required:
        - name
    ConnectorFieldsResponseApiDto:
      type: object
      properties:
        name:
          type: string
          example: field_name
        overview:
          type: string
          example: Field Overview
        description:
          type: string
          example: Field Description
        documentation:
          type: string
          example: Field Documentation
        defaultFields:
          example:
            - field1
            - field2
          type: array
          items:
            type: string
        fields:
          example: Field Fields
          type: array
          items:
            type: string
      required:
        - name
    ConnectorOAuthSettingsResponseApiDto:
      type: object
      properties:
        vars:
          type: object
          example:
            AppId: '718780528197362'
            Scopes: ads_read,business_management
          description: OAuth UI variables with resolved environment variable templates
        isEnabled:
          type: boolean
          example: true
          description: >-
            Whether OAuth is enabled (all required environment variables are
            configured)
      required:
        - vars
        - isEnabled
    ExchangeOAuthCredentialsDto:
      type: object
      properties:
        fieldPath:
          type: string
          example: AuthType.oauth2
        payload:
          type: object
          example:
            accessToken: '1234567890'
      required:
        - fieldPath
        - payload
    ConnectorOAuthStatusUserApiDto:
      type: object
      properties:
        id:
          type: string
          example: '1234567890'
        name:
          type: string
          example: John Doe
        email:
          type: string
          example: john.doe@example.com
        picture:
          type: string
          example: https://example.com/picture.jpg
      required:
        - id
        - name
        - email
        - picture
    ConnectorOAuthCredentialsResponseApiDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
        credentialId:
          type: string
          example: '1234567890'
        user:
          $ref: '#/components/schemas/ConnectorOAuthStatusUserApiDto'
        additional:
          type: object
          example:
            scope: read,write
        reasons:
          example:
            - Invalid credentials
          type: array
          items:
            type: string
      required:
        - success
        - credentialId
        - user
        - additional
        - reasons
    ConnectorOAuthStatusResponseApiDto:
      type: object
      properties:
        valid:
          type: boolean
          example: true
        expiresAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
        user:
          $ref: '#/components/schemas/ConnectorOAuthStatusUserApiDto'
        additional:
          type: object
          example:
            scope: read,write
      required:
        - valid
        - expiresAt
        - user
        - additional
    CreateScheduledTriggerRequestApiDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - REPORT_RUN
            - CONNECTOR_RUN
          example: CONNECTOR_RUN
        cronExpression:
          type: string
          example: 0 0 * * *
        timeZone:
          type: string
          example: UTC
        isActive:
          type: boolean
          example: true
        triggerConfig:
          type: object
      required:
        - type
        - cronExpression
        - timeZone
        - isActive
    ScheduledTriggerResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        type:
          type: string
          enum:
            - REPORT_RUN
            - CONNECTOR_RUN
          example: CONNECTOR_RUN
        cronExpression:
          type: string
          example: 0 0 * * *
        timeZone:
          type: string
          example: UTC
        isActive:
          type: boolean
          example: true
        nextRunTimestamp:
          type: object
          example: '2024-01-01T12:00:00.000Z'
          nullable: true
        lastRunTimestamp:
          type: object
          example: '2024-01-01T12:00:00.000Z'
          nullable: true
        triggerConfig:
          type: object
          nullable: true
        createdById:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
        createdByUser:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/UserProjectionDto'
      required:
        - id
        - type
        - cronExpression
        - timeZone
        - isActive
        - nextRunTimestamp
        - lastRunTimestamp
        - triggerConfig
        - createdById
        - createdAt
        - modifiedAt
    UpdateScheduledTriggerRequestApiDto:
      type: object
      properties:
        cronExpression:
          type: string
          example: 0 0 * * *
        timeZone:
          type: string
          example: UTC
        isActive:
          type: boolean
          example: true
      required:
        - cronExpression
        - timeZone
        - isActive
    SqlDryRunRequestApiDto:
      type: object
      properties:
        sql:
          type: string
          description: SQL query to validate
          example: SELECT * FROM table_name
      required:
        - sql
    SqlDryRunResponseApiDto:
      type: object
      properties:
        isValid:
          type: boolean
          description: Whether the SQL query is valid
          example: true
        error:
          type: string
          description: Error message if validation failed
          example: Syntax error at line 1
        bytes:
          type: number
          description: Estimated bytes to be processed
          example: 1024
      required:
        - isValid
    CreateAiHelperTriggerRequestApiDto:
      type: object
      properties:
        scope:
          type: string
          enum:
            - title
            - description
            - field_alias
            - field_description
            - all_field_descriptions
            - all_field_aliases
            - all_field_metadata
          description: >-
            What metadata to generate. Use "all_field_*" scopes to populate
            every field; use "field_alias" or "field_description" together with
            `fieldName` to generate a single field value.
        useSample:
          type: boolean
          description: >-
            When true, the data mart is run to fetch up to 30 sample rows that
            ground the AI in real values. When false, generation uses only
            column names and types (lower quality).
          default: true
        fieldName:
          type: string
          description: >-
            Required when scope is "field_alias" or "field_description". Must
            match an existing field name in the data mart schema.
      required:
        - scope
        - useSample
    GeneratedFieldMetadataApiDto:
      type: object
      properties:
        name:
          type: string
          description: Exact field name as in the data mart schema
        alias:
          type: string
          description: Business-friendly display name
        description:
          type: string
          description: Business-friendly description, one sentence
    GenerateDataMartMetadataResponseApiDto:
      type: object
      properties:
        title:
          type: string
          description: Suggested data mart title
        description:
          type: string
          description: Suggested data mart description
        fields:
          description: Per-field suggestions
          type: array
          items:
            $ref: '#/components/schemas/GeneratedFieldMetadataApiDto'
    AiHelperTriggerResponseApiDto:
      type: object
      properties:
        result:
          description: AI-generated metadata. Present when the trigger succeeded.
          allOf:
            - $ref: '#/components/schemas/GenerateDataMartMetadataResponseApiDto'
        error:
          type: string
          description: >-
            Human-readable error message. Present when the trigger errored.
            Surfaced to the user as a toast.
    InsightRunTriggerListItemResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 550e8400-e29b-41d4-a716-446655440000
        insightId:
          type: string
          example: 8a0d9a7c-4a1d-4a5d-8f2a-9b6f3d1c2e4b
        status:
          type: string
          enum:
            - IDLE
            - READY
            - PROCESSING
            - SUCCESS
            - ERROR
            - CANCELLING
            - CANCELLED
          example: IDLE
          description: Current trigger status
        uiResponse:
          type: object
          description: UI response for this trigger (e.g., { runId } or { error })
          nullable: true
        createdAt:
          type: object
          example: '2025-10-09T15:13:06.930Z'
        modifiedAt:
          type: object
          example: '2025-10-09T15:20:11.525Z'
      required:
        - id
        - insightId
        - status
        - uiResponse
        - createdAt
        - modifiedAt
    CreateInsightTemplateRunTriggerRequestApiDto:
      type: object
      properties:
        type:
          type: string
          description: Source of the Run Insight request
          enum:
            - manual
            - chat
          example: manual
        assistantMessageId:
          type: string
          description: Assistant message id that initiated Apply & Run
          example: 57bba70a-8ad8-4edc-8b3e-ec45f51dc486
      required:
        - type
    InsightTemplateRunTriggerListItemResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 550e8400-e29b-41d4-a716-446655440000
        insightTemplateId:
          type: string
          example: 8a0d9a7c-4a1d-4a5d-8f2a-9b6f3d1c2e4b
        status:
          type: string
          enum:
            - IDLE
            - READY
            - PROCESSING
            - SUCCESS
            - ERROR
            - CANCELLING
            - CANCELLED
          example: IDLE
        uiResponse:
          type: object
          nullable: true
        createdAt:
          type: object
          example: '2026-02-14T15:13:06.930Z'
        modifiedAt:
          type: object
          example: '2026-02-14T15:20:11.525Z'
      required:
        - id
        - insightTemplateId
        - status
        - uiResponse
        - createdAt
        - modifiedAt
    JoinConditionApiDto:
      type: object
      properties:
        sourceFieldName:
          type: string
          example: user_id
          description: Field name in the source data mart
        targetFieldName:
          type: string
          example: user_id
          description: Field name in the target data mart
      required:
        - sourceFieldName
        - targetFieldName
    CreateRelationshipRequestApiDto:
      type: object
      properties:
        targetDataMartId:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
          description: ID of the target data mart to blend with
        targetAlias:
          type: string
          example: orders
          description: Alias for the target data mart in the blend
          pattern: ^[a-z0-9_]+$
        joinConditions:
          description: Conditions used to join the data marts
          type: array
          items:
            $ref: '#/components/schemas/JoinConditionApiDto'
      required:
        - targetDataMartId
        - targetAlias
        - joinConditions
    DataMartRefApiDto:
      type: object
      properties:
        id:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        title:
          type: string
          example: My Data Mart
        description:
          type: string
          example: Revenue by channel
        status:
          type: string
          enum:
            - DRAFT
            - PUBLISHED
          example: PUBLISHED
      required:
        - id
        - title
        - status
    RelationshipResponseApiDto:
      type: object
      properties:
        id:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        dataStorageId:
          type: string
          example: 9cabc24e-1234-4a5a-8b12-abcdef123456
        sourceDataMart:
          $ref: '#/components/schemas/DataMartRefApiDto'
        targetDataMart:
          $ref: '#/components/schemas/DataMartRefApiDto'
        targetAlias:
          type: string
          example: orders
        joinConditions:
          type: array
          items:
            type: string
        createdById:
          type: string
          example: user-id-123
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
        createdByUser:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/UserProjectionDto'
      required:
        - id
        - dataStorageId
        - sourceDataMart
        - targetDataMart
        - targetAlias
        - joinConditions
        - createdById
        - createdAt
        - modifiedAt
    UpdateRelationshipRequestApiDto:
      type: object
      properties:
        targetAlias:
          type: string
          example: orders
          description: Alias for the target data mart in the blend
          pattern: ^[a-z0-9_]+$
        joinConditions:
          description: Conditions used to join the data marts
          type: array
          items:
            $ref: '#/components/schemas/JoinConditionApiDto'
    CreateContextRequestApiDto:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
      required:
        - name
    ContextResponseApiDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: object
        createdById:
          type: object
        createdByUser:
          $ref: '#/components/schemas/UserProjectionDto'
        createdAt:
          format: date-time
          type: string
          example: '2024-01-01T12:00:00.000Z'
        modifiedAt:
          format: date-time
          type: string
          example: '2024-01-02T15:30:00.000Z'
      required:
        - id
        - name
        - createdAt
        - modifiedAt
    UpdateContextRequestApiDto:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
      required:
        - name
    ContextImpactResponseApiDto:
      type: object
      properties:
        contextId:
          type: string
        contextName:
          type: string
        dataMartCount:
          type: number
        storageCount:
          type: number
        destinationCount:
          type: number
        memberCount:
          type: number
        affectedMemberIds:
          type: array
          items:
            type: string
      required:
        - contextId
        - contextName
        - dataMartCount
        - storageCount
        - destinationCount
        - memberCount
        - affectedMemberIds
    UpdateContextMembersRequestApiDto:
      type: object
      properties:
        assignedUserIds:
          description: >-
            Project member user ids to bind to this context. Admin ids are
            ignored.
          type: array
          items:
            type: string
      required:
        - assignedUserIds
    UpdateContextMembersResponseApiDto:
      type: object
      properties:
        assignedUserIds:
          type: array
          items:
            type: string
        droppedAdminIds:
          description: >-
            Admin user ids the caller tried to attach. Admins always have
            project-wide scope, so binding them to a context is a no-op. UI may
            surface a warning.
          type: array
          items:
            type: string
      required:
        - assignedUserIds
        - droppedAdminIds
    ProjectMemberResponseApiDto:
      type: object
      properties:
        userId:
          type: string
        email:
          type: string
        displayName:
          type: string
        avatarUrl:
          type: string
        role:
          type: string
          enum:
            - admin
            - editor
            - viewer
        roleScope:
          type: string
          enum:
            - entire_project
            - selected_contexts
        contextIds:
          type: array
          items:
            type: string
      required:
        - userId
        - email
        - role
        - roleScope
        - contextIds
    InviteMemberRequestApiDto:
      type: object
      properties:
        email:
          type: string
        role:
          type: string
          enum:
            - admin
            - editor
            - viewer
        roleScope:
          type: string
          enum:
            - entire_project
            - selected_contexts
          description: >-
            Explicit role scope for non-admin invitees. Ignored when role=admin
            (admins are always entire_project). If omitted, scope is inferred
            from contextIds (non-empty → selected_contexts, empty →
            entire_project) for backwards compatibility.
        contextIds:
          type: array
          items:
            type: string
      required:
        - email
        - role
    InviteMemberResponseApiDto:
      type: object
      properties:
        email:
          type: string
        kind:
          type: string
          enum:
            - email-sent
            - magic-link
        role:
          type: string
          enum:
            - admin
            - editor
            - viewer
        magicLink:
          type: string
          description: >-
            Present when `kind` is `magic-link`. Admin shares this link
            manually.
        expiresAt:
          type: string
        message:
          type: string
        userId:
          type: string
          description: >-
            Pre-provisioned user id from the IDP. Present when the backend could
            attach authorization scope immediately. Absent for IDPs that only
            materialise the user on first sign-in.
      required:
        - email
        - kind
        - role
    UpdateMemberRequestApiDto:
      type: object
      properties:
        role:
          type: string
          enum:
            - admin
            - editor
            - viewer
        roleScope:
          type: string
          enum:
            - entire_project
            - selected_contexts
        contextIds:
          type: array
          items:
            type: string
      required:
        - role
        - roleScope
        - contextIds
    UpdateMemberResponseApiDto:
      type: object
      properties:
        userId:
          type: string
        role:
          type: string
          enum:
            - admin
            - editor
            - viewer
        roleScope:
          type: string
          enum:
            - entire_project
            - selected_contexts
        contextIds:
          type: array
          items:
            type: string
        roleStatus:
          type: string
          enum:
            - ok
            - pending
        message:
          type: string
      required:
        - userId
        - role
        - roleScope
        - contextIds
        - roleStatus
    MembershipRequestApiDto:
      type: object
      properties:
        requestId:
          type: string
        email:
          type: string
        fullName:
          type: string
        avatar:
          type: string
        userId:
          type: string
        requestedRole:
          type: string
          enum:
            - admin
            - editor
            - viewer
        createdAt:
          type: string
      required:
        - requestId
        - email
        - requestedRole
        - createdAt
    ApproveMembershipRequestApiDto:
      type: object
      properties:
        role:
          type: string
          enum:
            - admin
            - editor
            - viewer
        roleScope:
          type: string
          enum:
            - entire_project
            - selected_contexts
        contextIds:
          type: array
          items:
            type: string
      required:
        - role
    ApproveMembershipRequestResponseApiDto:
      type: object
      properties:
        userId:
          type: string
        role:
          type: string
          enum:
            - admin
            - editor
            - viewer
        roleScope:
          type: string
          enum:
            - entire_project
            - selected_contexts
        contextIds:
          type: array
          items:
            type: string
      required:
        - userId
        - role
        - roleScope
        - contextIds
    ProjectMemberApiKeyResponseDto:
      type: object
      properties:
        apiKeyId:
          type: string
        name:
          type: string
        expiresAt:
          type: object
          nullable: true
        createdAt:
          type: string
        lastAuthenticatedAt:
          type: object
          nullable: true
      required:
        - apiKeyId
        - name
        - expiresAt
        - createdAt
        - lastAuthenticatedAt
    CreateProjectMemberApiKeyRequestDto:
      type: object
      properties:
        name:
          type: string
          description: User-facing name for the API key
        expiresAt:
          type: string
          description: Optional expiration date (ISO 8601)
      required:
        - name
    CreateProjectMemberApiKeyResponseDto:
      type: object
      properties:
        apiKeyId:
          type: string
        name:
          type: string
        expiresAt:
          type: object
          nullable: true
        createdAt:
          type: string
        lastAuthenticatedAt:
          type: object
          nullable: true
        apiKeySecret:
          type: string
          description: Shown only once at creation time
      required:
        - apiKeyId
        - name
        - expiresAt
        - createdAt
        - lastAuthenticatedAt
        - apiKeySecret
    UpdateProjectMemberApiKeyRequestDto:
      type: object
      properties:
        name:
          type: string
          description: New name for the API key
      required:
        - name
    ExchangeProjectMemberApiKeyRequestApiDto:
      type: object
      properties:
        apiKeySecret:
          type: string
          example: vjqmM5GfJ6QklV8mFqM5Ior2hK6vK4mY8pE9T7aZr6Q
      required:
        - apiKeySecret
    ExchangeProjectMemberApiKeyResponseApiDto:
      type: object
      properties:
        accessToken:
          type: string
          example: regular-odm-access-token
      required:
        - accessToken
    IntercomTokenResponseApiDto:
      type: object
      properties:
        token:
          type: string
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
      required:
        - token
    ReceiverInfoApiDto:
      type: object
      properties:
        userId:
          type: string
        email:
          type: string
        displayName:
          type: string
        avatarUrl:
          type: string
        hasNotificationsEnabled:
          type: boolean
      required:
        - userId
        - email
        - hasNotificationsEnabled
    NotificationSettingsItemResponseApiDto:
      type: object
      properties:
        id:
          type: string
        notificationType:
          type: string
          enum:
            - FAILED_RUNS_ALL_DM
            - SUCCESSFUL_RUNS_ALL_DM
        title:
          type: string
        enabled:
          type: boolean
        receivers:
          type: array
          items:
            $ref: '#/components/schemas/ReceiverInfoApiDto'
        webhookUrl:
          type: object
          nullable: true
        groupingDelayCron:
          type: string
        lastRunAt:
          type: object
          nullable: true
        nextRunAt:
          type: object
          nullable: true
        createdAt:
          type: string
        modifiedAt:
          type: string
      required:
        - id
        - notificationType
        - title
        - enabled
        - receivers
        - groupingDelayCron
        - createdAt
        - modifiedAt
    NotificationSettingsResponseApiDto:
      type: object
      properties:
        settings:
          type: array
          items:
            $ref: '#/components/schemas/NotificationSettingsItemResponseApiDto'
      required:
        - settings
    ProjectMemberApiDto:
      type: object
      properties:
        userId:
          type: string
        email:
          type: string
        displayName:
          type: string
        avatarUrl:
          type: string
        role:
          type: string
        hasNotificationsEnabled:
          type: boolean
        isOutbound:
          type: boolean
      required:
        - userId
        - email
        - role
        - hasNotificationsEnabled
        - isOutbound
    ProjectMembersResponseApiDto:
      type: object
      properties:
        members:
          type: array
          items:
            $ref: '#/components/schemas/ProjectMemberApiDto'
      required:
        - members
    UpdateNotificationSettingApiDto:
      type: object
      properties:
        enabled:
          type: boolean
        receivers:
          description: User IDs of receivers
          type: array
          items:
            type: string
        webhookUrl:
          type: object
          nullable: true
        groupingDelayCron:
          type: string
          enum:
            - '*/5 * * * *'
            - '*/15 * * * *'
            - '*/30 * * * *'
            - 0 * * * *
            - 0 */2 * * *
            - 0 */6 * * *
            - 0 */12 * * *
            - 0 0 * * *
          description: Grouping delay cron expression
