openapi: 3.1.0
info:
  title: Operator Database Notification Presentation Contract
  version: 1.0.0
  summary: Logical internal contract for Spec 230 shared database notification presentation and preserved destination routes.
  description: |
    This contract documents the shared primary payload structure that Spec 230 must enforce
    across the current operator-facing database notification consumers. It is intentionally
    logical rather than a public HTTP API because the feature reuses existing Filament database
    notifications, existing destination routes, and existing helper seams instead of introducing
    a new controller namespace.
servers:
  - url: https://logical.internal
    description: Non-routable placeholder used to describe internal repository contracts.
paths:
  /internal/operator-database-notifications/presentation:
    post:
      summary: Build one shared operator-facing database notification payload for an in-scope consumer.
      description: |
        Logical internal contract implemented by the shared presentation seam on top of the
        existing presenter and helper paths. It standardizes title, body, status with the
        corresponding existing Filament icon treatment, one primary action, and optional
        supporting context while preserving consumer-specific metadata.
      operationId: presentOperatorDatabaseNotification
      x-not-public-http: true
      requestBody:
        required: true
        content:
          application/vnd.tenantpilot.operator-database-notification-input+json:
            schema:
              $ref: '#/components/schemas/OperatorDatabaseNotificationInput'
      responses:
        '200':
          description: Shared primary notification structure returned for storage in the existing notifications table.
          content:
            application/vnd.tenantpilot.operator-database-notification-message+json:
              schema:
                $ref: '#/components/schemas/OperatorDatabaseNotificationMessage'
  /admin/notifications:
    get:
      summary: Existing Filament drawer renders converged finding and operation notifications.
      operationId: viewOperatorDatabaseNotifications
      responses:
        '200':
          description: Existing shell renders the shared card grammar for the current in-scope consumers.
          content:
            text/html:
              schema:
                type: string
            application/vnd.tenantpilot.operator-notification-drawer+json:
              schema:
                $ref: '#/components/schemas/NotificationDrawerSurface'
  /admin/t/{tenant}/findings/{finding}:
    get:
      summary: Finding notification action opens the existing tenant finding detail route.
      operationId: openFindingNotificationTarget
      parameters:
        - name: tenant
          in: path
          required: true
          schema:
            type: integer
        - name: finding
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Existing finding detail route renders for an entitled tenant operator.
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Recipient remains in scope but lacks current capability to inspect the finding.
        '404':
          description: Recipient no longer has tenant or record visibility.
  /admin/operations/{run}:
    get:
      summary: Admin or tenantless operation notification action opens the existing run detail route.
      operationId: openAdminOperationNotificationTarget
      parameters:
        - name: run
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Existing admin-plane or tenantless operation detail route renders for an entitled operator.
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Recipient is in scope but lacks current operation-view capability.
        '404':
          description: Recipient no longer has access to the route scope or the run.
  /system/ops/runs/{run}:
    get:
      summary: Platform-user operation notification action opens the existing system-panel run detail route.
      operationId: openSystemOperationNotificationTarget
      parameters:
        - name: run
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Existing system-panel run detail renders for an entitled platform user.
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Platform user lacks the required operations capability.
        '404':
          description: Platform user cannot access the run in the current plane.
components:
  schemas:
    NotificationConsumer:
      type: string
      enum:
        - finding_event
        - operation_run_queued
        - operation_run_completed
    NotificationStatus:
      type: string
      description: Shared status emphasis that also drives the existing Filament icon treatment for the card.
      enum:
        - info
        - success
        - warning
        - danger
    NotificationTarget:
      type: string
      enum:
        - finding_detail
        - admin_operation_run
        - tenantless_operation_run
        - system_operation_run
    NotificationPrimaryAction:
      type: object
      required:
        - label
        - url
        - target
      properties:
        label:
          type: string
        url:
          type: string
        target:
          $ref: '#/components/schemas/NotificationTarget'
    OperatorDatabaseNotificationInput:
      type: object
      required:
        - consumer
        - title
        - body
        - status
        - primaryAction
      properties:
        consumer:
          $ref: '#/components/schemas/NotificationConsumer'
        title:
          type: string
        body:
          type: string
        status:
          $ref: '#/components/schemas/NotificationStatus'
        primaryAction:
          $ref: '#/components/schemas/NotificationPrimaryAction'
        supportingLines:
          type: array
          items:
            type: string
        metadata:
          type: object
          additionalProperties: true
      description: |
        Shared input model for the bounded presentation seam. Metadata remains consumer-specific,
        but the primary title, body, status with the existing Filament icon treatment, and action structure must stay consistent.
    OperatorDatabaseNotificationMessage:
      type: object
      required:
        - title
        - body
        - status
        - actions
      properties:
        title:
          type: string
        body:
          type: string
        status:
          $ref: '#/components/schemas/NotificationStatus'
        actions:
          type: array
          minItems: 1
          maxItems: 1
          items:
            $ref: '#/components/schemas/NotificationPrimaryAction'
        supportingLines:
          type: array
          items:
            type: string
        metadata:
          type: object
          additionalProperties: true
      description: |
        Shared persisted message shape stored in the existing notifications table and rendered by
        the current Filament database-notification drawer.
    NotificationDrawerSurface:
      type: object
      required:
        - consumers
        - structureGuarantees
      properties:
        consumers:
          type: array
          items:
            $ref: '#/components/schemas/NotificationConsumer'
        structureGuarantees:
          type: array
          items:
            type: string
          example:
            - one primary title
            - one primary body summarizing the change
            - one status emphasis with the existing Filament icon treatment
            - exactly one primary action
            - optional supporting lines remain secondary