openapi: 3.0.3
info:
  title: Transaction Orchestrator API
  version: 1.0.0
  description: |
    REST API wrapper for the SettlementOrchestrator smart contract.
    
    Coordinates settlement lifecycle including trigger validation, fund locking,
    rail submission, and settlement confirmation. Supports both vault and lien
    escrow modes for different payment rails.
    
    This API provides a harmonized integration layer for:
    - Settlement creation and validation
    - Fund escrow management (vault or lien modes)
    - Rail transaction submission
    - Settlement confirmation and finalization
    - Compliance and policy checks
    
  contact:
    name: DBIS API Support
    email: api-support@dbis.org
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: https://api.d-bis.org/api/v1/orchestrator
    description: Production server
  - url: https://sandbox.d-bis.org/api/v1/orchestrator
    description: Sandbox server
  - url: http://localhost:8080/api/v1/orchestrator
    description: Development server

security:
  - BearerAuth: []
  - OAuth2MTLS: []

tags:
  - name: Settlements
    description: Settlement lifecycle operations
  - name: Configuration
    description: Orchestrator configuration
  - name: Health
    description: Health check endpoints

paths:
  /health:
    get:
      tags: [Health]
      summary: Health check
      description: Returns the health status of the Transaction Orchestrator API and contract connection
      operationId: getHealth
      security: []
      responses:
        '200':
          description: Service is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "healthy"
                  contract:
                    type: object
                    properties:
                      address:
                        type: string
                        example: "0x1234567890123456789012345678901234567890"
                      connected:
                        type: boolean
                      chainId:
                        type: integer
                        example: 138
                  registries:
                    type: object
                    properties:
                      triggerRegistry:
                        type: string
                      escrowVault:
                        type: string
                      accountWalletRegistry:
                        type: string
                      policyManager:
                        type: string
                      debtRegistry:
                        type: string
                      complianceRegistry:
                        type: string
                  timestamp:
                    type: string
                    format: date-time

  /settlements:
    post:
      tags: [Settlements]
      summary: Create settlement trigger
      description: Creates a new settlement trigger in the trigger registry
      operationId: createSettlement
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSettlementRequest'
            examples:
              outbound:
                value:
                  accountRefId: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
                  walletRefId: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb5"
                  token: "0x0000000000000000000000000000000000000000"
                  amount: "1000000000000000000"
                  rail: "FEDWIRE"
                  msgType: "pacs.008"
                  direction: "OUTBOUND"
                  metadata:
                    description: "Payment to supplier"
      responses:
        '201':
          description: Settlement trigger created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementResponse'
              example:
                success: true
                data:
                  triggerId: 1
                  accountRefId: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
                  state: "CREATED"
                  createdAt: 1704067200
                  transactionHash: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
                timestamp: "2024-01-01T00:00:00Z"
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'

    get:
      tags: [Settlements]
      summary: List settlements
      description: Returns a paginated list of settlements with optional filters
      operationId: listSettlements
      parameters:
        - name: accountRefId
          in: query
          description: Filter by account reference ID
          required: false
          schema:
            type: string
            pattern: '^0x[a-fA-F0-9]{64}$'
        - name: state
          in: query
          description: Filter by settlement state
          required: false
          schema:
            type: string
            enum: [CREATED, VALIDATED, SUBMITTED_TO_RAIL, PENDING, SETTLED, REJECTED, CANCELLED, RECALLED]
        - name: rail
          in: query
          description: Filter by payment rail
          required: false
          schema:
            type: string
            enum: [FEDWIRE, SWIFT, SEPA, RTGS, ACH, FPS, OTHER]
        - name: page
          in: query
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: pageSize
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: List of settlements
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementListResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /settlements/{triggerId}:
    get:
      tags: [Settlements]
      summary: Get settlement status
      description: Returns the current status and details of a settlement
      operationId: getSettlement
      parameters:
        - $ref: '#/components/parameters/TriggerId'
      responses:
        '200':
          description: Settlement details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /settlements/{triggerId}/validate:
    post:
      tags: [Settlements]
      summary: Validate and lock funds
      description: Validates a settlement trigger and locks funds via vault or lien
      operationId: validateAndLock
      parameters:
        - $ref: '#/components/parameters/TriggerId'
      responses:
        '200':
          description: Settlement validated and funds locked
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementResponse'
              example:
                success: true
                data:
                  triggerId: 1
                  state: "VALIDATED"
                  escrowMode: "VAULT"
                  lockedAt: 1704067260
                  transactionHash: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
                timestamp: "2024-01-01T00:01:00Z"
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /settlements/{triggerId}/submit:
    post:
      tags: [Settlements]
      summary: Mark as submitted to rail
      description: Marks a settlement as submitted to the payment rail
      operationId: markSubmitted
      parameters:
        - $ref: '#/components/parameters/TriggerId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubmitSettlementRequest'
            example:
              railTxRef: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
      responses:
        '200':
          description: Settlement marked as submitted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /settlements/{triggerId}/confirm:
    post:
      tags: [Settlements]
      summary: Confirm settlement
      description: Confirms a settlement as settled, releasing escrow or minting tokens
      operationId: confirmSettled
      parameters:
        - $ref: '#/components/parameters/TriggerId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConfirmSettlementRequest'
            example:
              railTxRef: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
      responses:
        '200':
          description: Settlement confirmed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementResponse'
              example:
                success: true
                data:
                  triggerId: 1
                  state: "SETTLED"
                  settledAt: 1704067320
                  transactionHash: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
                timestamp: "2024-01-01T00:02:00Z"
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /settlements/{triggerId}/reject:
    post:
      tags: [Settlements]
      summary: Reject settlement
      description: Rejects a settlement and releases escrow/lien
      operationId: rejectSettlement
      parameters:
        - $ref: '#/components/parameters/TriggerId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RejectSettlementRequest'
            example:
              reason: "INSUFFICIENT_FUNDS"
      responses:
        '200':
          description: Settlement rejected
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /settlements/{triggerId}/cancel:
    post:
      tags: [Settlements]
      summary: Cancel settlement
      description: Cancels a settlement and releases escrow/lien if locked
      operationId: cancelSettlement
      parameters:
        - $ref: '#/components/parameters/TriggerId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancelSettlementRequest'
            example:
              reason: "USER_CANCELLED"
      responses:
        '200':
          description: Settlement cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /settlements/{triggerId}/recall:
    post:
      tags: [Settlements]
      summary: Recall settlement
      description: Recalls a pending settlement and releases escrow/lien
      operationId: recallSettlement
      parameters:
        - $ref: '#/components/parameters/TriggerId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecallSettlementRequest'
            example:
              reason: "FRAUD_DETECTED"
      responses:
        '200':
          description: Settlement recalled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SettlementResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /settlements/{triggerId}/escrow-mode:
    get:
      tags: [Settlements]
      summary: Get escrow mode
      description: Returns the escrow mode (vault or lien) for a settlement
      operationId: getEscrowMode
      parameters:
        - $ref: '#/components/parameters/TriggerId'
      responses:
        '200':
          description: Escrow mode
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      triggerId:
                        type: integer
                      escrowMode:
                        type: string
                        enum: [VAULT, LIEN]
                  timestamp:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'

  /configuration/rails/{rail}/escrow-mode:
    get:
      tags: [Configuration]
      summary: Get rail escrow mode
      description: Returns the escrow mode configuration for a payment rail
      operationId: getRailEscrowMode
      parameters:
        - $ref: '#/components/parameters/Rail'
      responses:
        '200':
          description: Rail escrow mode
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      rail:
                        type: string
                      escrowMode:
                        type: string
                        enum: [VAULT, LIEN]
                  timestamp:
                    type: string
                    format: date-time

    put:
      tags: [Configuration]
      summary: Set rail escrow mode
      description: Sets the escrow mode for a payment rail (requires admin role)
      operationId: setRailEscrowMode
      parameters:
        - $ref: '#/components/parameters/Rail'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - escrowMode
              properties:
                escrowMode:
                  type: string
                  enum: [VAULT, LIEN]
      responses:
        '200':
          description: Escrow mode updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaseResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token for authentication
    OAuth2MTLS:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.d-bis.org/oauth2/token
          scopes:
            orchestrator:read: Read access to orchestrator
            orchestrator:write: Write access to orchestrator

  parameters:
    TriggerId:
      name: triggerId
      in: path
      required: true
      description: Settlement trigger ID
      schema:
        type: integer
        minimum: 1
        example: 1
    
    Rail:
      name: rail
      in: path
      required: true
      description: Payment rail identifier
      schema:
        type: string
        enum: [FEDWIRE, SWIFT, SEPA, RTGS, ACH, FPS, OTHER]
        example: "FEDWIRE"

  schemas:
    CreateSettlementRequest:
      type: object
      required:
        - accountRefId
        - token
        - amount
        - rail
        - msgType
        - direction
      properties:
        accountRefId:
          type: string
          description: Hashed account reference ID
          pattern: '^0x[a-fA-F0-9]{64}$'
          example: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
        walletRefId:
          type: string
          description: Hashed wallet reference ID (optional)
          pattern: '^0x[a-fA-F0-9]{40,64}$'
        token:
          type: string
          description: Token contract address
          pattern: '^0x[a-fA-F0-9]{40}$'
          example: "0x0000000000000000000000000000000000000000"
        amount:
          type: string
          description: Amount in token units (wei for native tokens)
          pattern: '^[0-9]+$'
          example: "1000000000000000000"
        rail:
          type: string
          enum: [FEDWIRE, SWIFT, SEPA, RTGS, ACH, FPS, OTHER]
          example: "FEDWIRE"
        msgType:
          type: string
          description: ISO 20022 message type
          example: "pacs.008"
        direction:
          type: string
          enum: [INBOUND, OUTBOUND]
          example: "OUTBOUND"
        metadata:
          type: object
          description: Additional metadata
          properties:
            description:
              type: string
            reference:
              type: string

    SubmitSettlementRequest:
      type: object
      required:
        - railTxRef
      properties:
        railTxRef:
          type: string
          description: Rail transaction reference
          pattern: '^0x[a-fA-F0-9]{64}$'
          example: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"

    ConfirmSettlementRequest:
      type: object
      required:
        - railTxRef
      properties:
        railTxRef:
          type: string
          description: Rail transaction reference for verification
          pattern: '^0x[a-fA-F0-9]{64}$'

    RejectSettlementRequest:
      type: object
      required:
        - reason
      properties:
        reason:
          type: string
          enum: [INSUFFICIENT_FUNDS, COMPLIANCE_FAILED, POLICY_VIOLATION, INVALID_ACCOUNT, OTHER]
          example: "INSUFFICIENT_FUNDS"

    CancelSettlementRequest:
      type: object
      required:
        - reason
      properties:
        reason:
          type: string
          enum: [USER_CANCELLED, TIMEOUT, SYSTEM_ERROR, OTHER]
          example: "USER_CANCELLED"

    RecallSettlementRequest:
      type: object
      required:
        - reason
      properties:
        reason:
          type: string
          enum: [FRAUD_DETECTED, COMPLIANCE_REQUIRED, SYSTEM_ERROR, OTHER]
          example: "FRAUD_DETECTED"

    Settlement:
      type: object
      properties:
        triggerId:
          type: integer
        accountRefId:
          type: string
        walletRefId:
          type: string
        token:
          type: string
        amount:
          type: string
        rail:
          type: string
        msgType:
          type: string
        direction:
          type: string
        state:
          type: string
          enum: [CREATED, VALIDATED, SUBMITTED_TO_RAIL, PENDING, SETTLED, REJECTED, CANCELLED, RECALLED]
        escrowMode:
          type: string
          enum: [VAULT, LIEN]
        railTxRef:
          type: string
        createdAt:
          type: integer
          format: int64
        validatedAt:
          type: integer
          format: int64
        submittedAt:
          type: integer
          format: int64
        settledAt:
          type: integer
          format: int64
        reason:
          type: string
        metadata:
          type: object

    SettlementResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/Settlement'

    SettlementListResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              type: object
              properties:
                settlements:
                  type: array
                  items:
                    $ref: '#/components/schemas/Settlement'
                pagination:
                  $ref: '#/components/schemas/Pagination'

    BaseResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        timestamp:
          type: string
          format: date-time

    Pagination:
      type: object
      properties:
        page:
          type: integer
        pageSize:
          type: integer
        total:
          type: integer
        totalPages:
          type: integer

    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              example: "VALIDATION_ERROR"
            message:
              type: string
              example: "Invalid request parameters"
            details:
              type: object
        timestamp:
          type: string
          format: date-time

  responses:
    BadRequest:
      description: Bad request - validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

    Unauthorized:
      description: Unauthorized - missing or invalid authentication
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

    Forbidden:
      description: Forbidden - insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

    Conflict:
      description: Conflict - invalid state transition
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
