openapi: 3.0.3
info:
  title: Messaging API
  version: 1.0.0
  description: |
    REST API for messaging services including SMS, email, and portal notifications.
    
    Supports multiple providers:
    - SMS: Twilio
    - Email: SendGrid, AWS SES, SMTP
    - Portal: Internal notification system
    
    Features:
    - Template-based messaging with variable substitution
    - Provider abstraction for multi-provider support
    - Delivery status tracking
    - Webhook support for delivery events
    
  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/messaging
    description: Production server
  - url: https://sandbox.d-bis.org/api/v1/messaging
    description: Sandbox server
  - url: http://localhost:3000/api/v1/messaging
    description: Development server

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

tags:
  - name: SMS
    description: SMS messaging operations
  - name: Email
    description: Email messaging operations
  - name: Portal
    description: Portal notification operations
  - name: Templates
    description: Message template management
  - name: Providers
    description: Provider configuration and management
  - name: Webhooks
    description: Webhook management for delivery status
  - name: Health
    description: Health check endpoints

paths:
  /health:
    get:
      tags: [Health]
      summary: Health check
      description: Returns the health status of the Messaging API and provider connections
      operationId: getHealth
      security: []
      responses:
        '200':
          description: Service is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "healthy"
                  providers:
                    type: object
                    properties:
                      sms:
                        type: object
                        properties:
                          twilio:
                            type: object
                            properties:
                              status:
                                type: string
                                example: "connected"
                              accountSid:
                                type: string
                      email:
                        type: object
                        properties:
                          sendgrid:
                            type: object
                            properties:
                              status:
                                type: string
                          ses:
                            type: object
                            properties:
                              status:
                                type: string
                  timestamp:
                    type: string
                    format: date-time

  /sms/send:
    post:
      tags: [SMS]
      summary: Send SMS message
      description: Sends an SMS message using the configured SMS provider (default: Twilio)
      operationId: sendSMS
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendSMSRequest'
            examples:
              simple:
                value:
                  recipient: "+1234567890"
                  message: "Your verification code is 123456"
                  provider: "twilio"
              template:
                value:
                  recipient: "+1234567890"
                  template: "verification_code"
                  variables:
                    code: "123456"
                    expiresIn: "5 minutes"
                  provider: "twilio"
      responses:
        '200':
          description: SMS sent successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
              example:
                success: true
                data:
                  messageId: "SM1234567890abcdef"
                  recipient: "+1234567890"
                  status: "queued"
                  provider: "twilio"
                  sentAt: "2024-01-01T00:00:00Z"
                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'

  /sms/{messageId}/status:
    get:
      tags: [SMS]
      summary: Get SMS message status
      description: Returns the delivery status of an SMS message
      operationId: getSMSStatus
      parameters:
        - $ref: '#/components/parameters/MessageId'
      responses:
        '200':
          description: Message status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageStatusResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /email/send:
    post:
      tags: [Email]
      summary: Send email message
      description: Sends an email message using the configured email provider
      operationId: sendEmail
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendEmailRequest'
            examples:
              simple:
                value:
                  recipient: "user@example.com"
                  subject: "Welcome to DBIS"
                  body: "Welcome to DBIS! Your account has been created."
                  provider: "sendgrid"
              template:
                value:
                  recipient: "user@example.com"
                  template: "welcome_email"
                  variables:
                    name: "John Doe"
                    accountId: "ACC-123456"
                  provider: "sendgrid"
      responses:
        '200':
          description: Email sent successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /email/{messageId}/status:
    get:
      tags: [Email]
      summary: Get email message status
      description: Returns the delivery status of an email message
      operationId: getEmailStatus
      parameters:
        - $ref: '#/components/parameters/MessageId'
      responses:
        '200':
          description: Message status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageStatusResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /portal/notifications:
    post:
      tags: [Portal]
      summary: Create portal notification
      description: Creates a portal notification for a user
      operationId: createPortalNotification
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePortalNotificationRequest'
            example:
              recipientId: "user-123"
              template: "account_approved"
              variables:
                accountType: "Tier 1"
                approvedAt: "2024-01-01T00:00:00Z"
              priority: "normal"
      responses:
        '201':
          description: Portal notification created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /templates:
    get:
      tags: [Templates]
      summary: List message templates
      description: Returns a list of available message templates
      operationId: listTemplates
      parameters:
        - name: type
          in: query
          description: Filter by template type
          required: false
          schema:
            type: string
            enum: [sms, email, portal]
        - 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 templates
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateListResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

    post:
      tags: [Templates]
      summary: Create message template
      description: Creates a new message template
      operationId: createTemplate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTemplateRequest'
            example:
              name: "verification_code"
              type: "sms"
              subject: "Verification Code"
              body: "Your verification code is {{code}}. It expires in {{expiresIn}}."
      responses:
        '201':
          description: Template created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateResponse'
        '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'

  /templates/{templateId}:
    get:
      tags: [Templates]
      summary: Get message template
      description: Returns details of a message template
      operationId: getTemplate
      parameters:
        - $ref: '#/components/parameters/TemplateId'
      responses:
        '200':
          description: Template details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'

    put:
      tags: [Templates]
      summary: Update message template
      description: Updates an existing message template
      operationId: updateTemplate
      parameters:
        - $ref: '#/components/parameters/TemplateId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateTemplateRequest'
      responses:
        '200':
          description: Template updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'

    delete:
      tags: [Templates]
      summary: Delete message template
      description: Deletes a message template
      operationId: deleteTemplate
      parameters:
        - $ref: '#/components/parameters/TemplateId'
      responses:
        '204':
          description: Template deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /providers:
    get:
      tags: [Providers]
      summary: List available providers
      description: Returns a list of available messaging providers and their status
      operationId: listProviders
      responses:
        '200':
          description: List of providers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /webhooks:
    post:
      tags: [Webhooks]
      summary: Register webhook
      description: Registers a webhook URL for delivery status events
      operationId: registerWebhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterWebhookRequest'
            example:
              url: "https://api.example.com/webhooks/messaging"
              events:
                - "sms.delivered"
                - "sms.failed"
                - "email.delivered"
                - "email.bounced"
              secret: "webhook_secret_token"
      responses:
        '201':
          description: Webhook registered
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'

    get:
      tags: [Webhooks]
      summary: List registered webhooks
      description: Returns a list of registered webhooks
      operationId: listWebhooks
      responses:
        '200':
          description: List of webhooks
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /webhooks/{webhookId}:
    delete:
      tags: [Webhooks]
      summary: Delete webhook
      description: Deletes a registered webhook
      operationId: deleteWebhook
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Webhook deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'

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:
            messaging:read: Read access to messaging
            messaging:write: Write access to messaging

  parameters:
    MessageId:
      name: messageId
      in: path
      required: true
      description: Message ID
      schema:
        type: string
        example: "SM1234567890abcdef"
    
    TemplateId:
      name: templateId
      in: path
      required: true
      description: Template ID or name
      schema:
        type: string
        example: "verification_code"

  schemas:
    SendSMSRequest:
      type: object
      required:
        - recipient
      properties:
        recipient:
          type: string
          description: Phone number in E.164 format
          pattern: '^\+[1-9]\d{1,14}$'
          example: "+1234567890"
        message:
          type: string
          description: Message text (required if template not provided)
          maxLength: 1600
          example: "Your verification code is 123456"
        template:
          type: string
          description: Template name (required if message not provided)
          example: "verification_code"
        variables:
          type: object
          description: Template variables
          additionalProperties:
            type: string
          example:
            code: "123456"
            expiresIn: "5 minutes"
        provider:
          type: string
          description: SMS provider to use
          enum: [twilio, default]
          default: "default"
          example: "twilio"
        priority:
          type: string
          enum: [low, normal, high, urgent]
          default: "normal"

    SendEmailRequest:
      type: object
      required:
        - recipient
      properties:
        recipient:
          type: string
          format: email
          example: "user@example.com"
        subject:
          type: string
          description: Email subject (required if template not provided)
          example: "Welcome to DBIS"
        body:
          type: string
          description: Email body HTML or text (required if template not provided)
          example: "<html><body><p>Welcome to DBIS!</p></body></html>"
        template:
          type: string
          description: Template name (required if subject/body not provided)
          example: "welcome_email"
        variables:
          type: object
          description: Template variables
          additionalProperties:
            type: string
          example:
            name: "John Doe"
            accountId: "ACC-123456"
        provider:
          type: string
          description: Email provider to use
          enum: [sendgrid, ses, smtp, default]
          default: "default"
          example: "sendgrid"
        priority:
          type: string
          enum: [low, normal, high, urgent]
          default: "normal"
        from:
          type: string
          description: Sender email address (optional, uses default if not provided)
          format: email
        replyTo:
          type: string
          description: Reply-to email address
          format: email

    CreatePortalNotificationRequest:
      type: object
      required:
        - recipientId
        - template
      properties:
        recipientId:
          type: string
          description: User ID or account ID
          example: "user-123"
        template:
          type: string
          description: Template name
          example: "account_approved"
        variables:
          type: object
          description: Template variables
          additionalProperties:
            type: string
          example:
            accountType: "Tier 1"
        priority:
          type: string
          enum: [low, normal, high, urgent]
          default: "normal"

    CreateTemplateRequest:
      type: object
      required:
        - name
        - type
        - body
      properties:
        name:
          type: string
          description: Template name (unique identifier)
          example: "verification_code"
        type:
          type: string
          enum: [sms, email, portal]
          example: "sms"
        subject:
          type: string
          description: Email subject (required for email type)
          example: "Verification Code"
        body:
          type: string
          description: Message body with {{variable}} placeholders
          example: "Your verification code is {{code}}. It expires in {{expiresIn}}."
        description:
          type: string
          description: Template description
          example: "SMS template for verification codes"

    UpdateTemplateRequest:
      type: object
      properties:
        subject:
          type: string
        body:
          type: string
        description:
          type: string

    RegisterWebhookRequest:
      type: object
      required:
        - url
        - events
      properties:
        url:
          type: string
          format: uri
          description: Webhook URL
          example: "https://api.example.com/webhooks/messaging"
        events:
          type: array
          description: Events to subscribe to
          items:
            type: string
            enum: [sms.queued, sms.sent, sms.delivered, sms.failed, email.queued, email.sent, email.delivered, email.bounced, email.failed, portal.created]
          example: ["sms.delivered", "sms.failed"]
        secret:
          type: string
          description: Webhook secret for signature verification
          example: "webhook_secret_token"
        active:
          type: boolean
          default: true

    MessageResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              type: object
              properties:
                messageId:
                  type: string
                  example: "SM1234567890abcdef"
                recipient:
                  type: string
                recipientType:
                  type: string
                  enum: [email, sms, portal]
                status:
                  type: string
                  enum: [queued, sent, delivered, failed, bounced]
                provider:
                  type: string
                sentAt:
                  type: string
                  format: date-time
                deliveredAt:
                  type: string
                  format: date-time

    MessageStatusResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              type: object
              properties:
                messageId:
                  type: string
                recipient:
                  type: string
                status:
                  type: string
                  enum: [queued, sent, delivered, failed, bounced]
                provider:
                  type: string
                sentAt:
                  type: string
                  format: date-time
                deliveredAt:
                  type: string
                  format: date-time
                error:
                  type: string
                  description: Error message if status is failed

    Template:
      type: object
      properties:
        templateId:
          type: string
        name:
          type: string
        type:
          type: string
          enum: [sms, email, portal]
        subject:
          type: string
        body:
          type: string
        description:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    TemplateResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/Template'

    TemplateListResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              type: object
              properties:
                templates:
                  type: array
                  items:
                    $ref: '#/components/schemas/Template'
                pagination:
                  $ref: '#/components/schemas/Pagination'

    Provider:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        type:
          type: string
          enum: [sms, email]
        status:
          type: string
          enum: [connected, disconnected, error]
        configured:
          type: boolean

    ProviderListResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              type: object
              properties:
                providers:
                  type: array
                  items:
                    $ref: '#/components/schemas/Provider'

    Webhook:
      type: object
      properties:
        webhookId:
          type: string
        url:
          type: string
        events:
          type: array
          items:
            type: string
        active:
          type: boolean
        createdAt:
          type: string
          format: date-time

    WebhookResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/Webhook'

    WebhookListResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              type: object
              properties:
                webhooks:
                  type: array
                  items:
                    $ref: '#/components/schemas/Webhook'

    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 - resource already exists
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

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