asyncapi: 3.0.0
info:
  title: MMonster WebSocket API
  version: 1.0.0
  description: |
    Real-time updates via Socket.IO with Redis adapter for horizontal scaling.

    ## Authentication
    The `/admin` namespace requires JWT token authentication:
    - Via `auth.token` in connection options
    - Via `Authorization: Bearer <token>` header

    ## Connection Example
    ```javascript
    import { io } from 'socket.io-client';

    const socket = io('https://api.mmonster.co/admin', {
      auth: { token: 'your-jwt-token' }
    });

    socket.on('connect', () => {
      // Subscribe to entities
      socket.emit('subscribe', {
        entities: { orders: [101, 102], deals: [555] },
        channels: ['logs', 'order_feed']
      });
    });

    socket.on('orderUpdated', (data) => {
      console.log('Order updated:', data);
    });
    ```

servers:
  production:
    host: api.mmonster.co
    protocol: wss
    description: Production WebSocket server
  development:
    host: localhost:1337
    protocol: ws
    description: Development WebSocket server

channels:
  admin:
    address: /admin
    description: |
      Admin namespace for real-time entity updates.
      Requires JWT authentication.
    messages:
      subscribe:
        $ref: '#/components/messages/Subscribe'
      unsubscribe:
        $ref: '#/components/messages/Unsubscribe'
      orderCreated:
        $ref: '#/components/messages/OrderCreated'
      orderUpdated:
        $ref: '#/components/messages/OrderUpdated'
      dealCreated:
        $ref: '#/components/messages/DealCreated'
      dealUpdated:
        $ref: '#/components/messages/DealUpdated'
      dealStatusUpdated:
        $ref: '#/components/messages/DealStatusUpdated'
      customerCreated:
        $ref: '#/components/messages/CustomerCreated'
      customerUpdated:
        $ref: '#/components/messages/CustomerUpdated'
      providerUpdated:
        $ref: '#/components/messages/ProviderUpdated'
      providerWalletUpdated:
        $ref: '#/components/messages/ProviderWalletUpdated'
      payoutStatusUpdated:
        $ref: '#/components/messages/PayoutStatusUpdated'
      chatMessage:
        $ref: '#/components/messages/ChatMessage'
      chatMentioned:
        $ref: '#/components/messages/ChatMentioned'
      chatStatsUpdated:
        $ref: '#/components/messages/ChatStatsUpdated'

  widget:
    address: /widget
    description: |
      Widget namespace for customer-facing embedded widgets.
      No authentication required.
    messages:
      widgetUpdate:
        $ref: '#/components/messages/WidgetUpdate'
      discordRequestSend:
        $ref: '#/components/messages/DiscordRequestSend'

  stat:
    address: /stat
    description: |
      Statistics namespace for real-time stats updates.
      No authentication required.
    messages:
      statUpdate:
        $ref: '#/components/messages/StatUpdate'

components:
  messages:
    Subscribe:
      name: subscribe
      title: Subscribe to entities and channels
      summary: Subscribe to receive updates for specific entities or channels
      payload:
        type: object
        properties:
          entities:
            type: object
            description: Map of entity type to array of IDs
            additionalProperties:
              type: array
              items:
                type: integer
            example:
              orders: [101, 102, 103]
              deals: [555, 556]
              customers: [42]
          channels:
            type: array
            items:
              type: string
            description: Channel names to subscribe to
            example: ["logs", "order_feed"]

    Unsubscribe:
      name: unsubscribe
      title: Unsubscribe from entities and channels
      summary: Stop receiving updates for specific entities or channels
      payload:
        type: object
        properties:
          entities:
            type: object
            additionalProperties:
              type: array
              items:
                type: integer
          channels:
            type: array
            items:
              type: string

    OrderCreated:
      name: orderCreated
      title: Order created
      summary: Fired when a new order is created
      payload:
        $ref: '#/components/schemas/EntityUpdate'

    OrderUpdated:
      name: orderUpdated
      title: Order updated
      summary: Fired when an order is modified
      payload:
        $ref: '#/components/schemas/EntityUpdate'

    DealCreated:
      name: dealCreated
      title: Deal created
      summary: Fired when a new deal is created
      payload:
        $ref: '#/components/schemas/EntityUpdate'

    DealUpdated:
      name: dealUpdated
      title: Deal updated
      summary: Fired when a deal is modified
      payload:
        $ref: '#/components/schemas/EntityUpdate'

    DealStatusUpdated:
      name: dealStatusUpdated
      title: Deal status updated
      summary: Fired when a deal transitions to a new status
      payload:
        allOf:
          - $ref: '#/components/schemas/EntityUpdate'
          - type: object
            properties:
              previousStatus:
                type: string
              newStatus:
                type: string

    CustomerCreated:
      name: customerCreated
      title: Customer created
      summary: Fired when a new customer is created
      payload:
        $ref: '#/components/schemas/EntityUpdate'

    CustomerUpdated:
      name: customerUpdated
      title: Customer updated
      summary: Fired when a customer is modified
      payload:
        $ref: '#/components/schemas/EntityUpdate'

    ProviderUpdated:
      name: providerUpdated
      title: Provider updated
      summary: Fired when a provider is modified
      payload:
        $ref: '#/components/schemas/EntityUpdate'

    ProviderWalletUpdated:
      name: providerWalletUpdated
      title: Provider wallet updated
      summary: Fired when a provider's wallet balance changes
      payload:
        $ref: '#/components/schemas/WalletUpdate'

    PayoutStatusUpdated:
      name: payoutStatusUpdated
      title: Payout status updated
      summary: Fired when a payout status changes
      payload:
        allOf:
          - $ref: '#/components/schemas/EntityUpdate'
          - type: object
            properties:
              previousStatus:
                type: string
              newStatus:
                type: string

    WidgetUpdate:
      name: widget:update
      title: Widget update
      summary: Widget configuration or data update
      payload:
        type: object

    DiscordRequestSend:
      name: discord:request-send
      title: Discord request send
      summary: Request to send a Discord boost request message
      payload:
        type: object

    StatUpdate:
      name: stat:update
      title: Statistics update
      summary: Real-time statistics update
      payload:
        type: object
        properties:
          dealCount:
            type: integer
          userCount:
            type: integer
          activeProviders:
            type: integer

    ChatMessage:
      name: chatMessage
      title: Chat message
      summary: Fired when a new message arrives in a followed chat
      payload:
        type: object
        properties:
          chatId:
            type: integer
            description: Chat ID
          message:
            type: object
            description: Message content from Mattermost
            properties:
              id:
                type: string
              message:
                type: string
              userId:
                type: string
              username:
                type: string
              role:
                type: string
                enum: [admin, customer, bot]
              createdAt:
                type: string
                format: date-time
        required:
          - chatId
          - message

    ChatMentioned:
      name: chatMentioned
      title: User mentioned in chat
      summary: Fired when the current user is @mentioned in a chat
      payload:
        type: object
        properties:
          chatId:
            type: integer
            description: Chat ID where mention occurred
          messageId:
            type: string
            description: Mattermost message ID
          mentionedBy:
            type: string
            description: Username of who mentioned the user
        required:
          - chatId
          - messageId

    ChatStatsUpdated:
      name: chatStatsUpdated
      title: Chat stats updated
      summary: Fired when unread count or last message changes for followed chats
      payload:
        type: object
        properties:
          chatId:
            type: integer
            description: Chat ID
          unreadCount:
            type: integer
            description: Number of unread messages
          lastMessagePreview:
            type: string
            description: Preview of last message content
          lastMessageAt:
            type: string
            format: date-time
            description: Timestamp of last message
        required:
          - chatId

  schemas:
    EntityUpdate:
      type: object
      description: Standard entity update payload
      properties:
        id:
          type: integer
          description: Entity ID
        _ts:
          type: integer
          description: Timestamp for ordering/deduplication (Unix ms)
        data:
          type: object
          description: Updated entity data
          additionalProperties: true
      required:
        - id

    WalletUpdate:
      type: object
      description: Provider wallet balance update
      properties:
        id:
          type: integer
          description: Provider ID
        main:
          type: number
          description: Main wallet balance
        pending:
          type: number
          description: Pending balance
        requested:
          type: number
          description: Requested payout amount
        paid:
          type: number
          description: Total paid amount
        _ts:
          type: integer
          description: Timestamp for ordering/deduplication
