asyncapi: 3.0.0
info:
  title: User Service
  version: 1.0.0
  description: This service handles user-related events and operations
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0

servers:
  production:
    host: mqtt://api.example.com
    protocol: mqtt
    description: Production server
  development:
    host: mqtt://dev.example.com
    protocol: mqtt
    description: Development server

channels:
  userEvents:
    address: user/events
    messages:
      userCreatedMessage:
        $ref: '#/components/messages/UserCreated'
      userUpdatedMessage:
        $ref: '#/components/messages/UserUpdated'
    description: Used for broadcasting user creation and update events
  userCommands:
    address: user/commands
    messages:
      createUserMessage:
        $ref: '#/components/messages/CreateUser'
      updateUserMessage:
        $ref: '#/components/messages/UpdateUser'
    description: Used for sending commands to create or update users
  notifications:
    address: notifications
    messages:
      emailNotificationMessage:
        $ref: '#/components/messages/EmailNotification'
    description: Used for email notification events

operations:
  # UserEvents channel operations - both send and receive on same channel
  publishUserCreated:
    action: send
    channel:
      $ref: '#/channels/userEvents'
    messages:
      - $ref: '#/channels/userEvents/messages/userCreatedMessage'
  consumeUserCreated:
    action: receive
    channel:
      $ref: '#/channels/userEvents'
    messages:
      - $ref: '#/channels/userEvents/messages/userCreatedMessage'
  publishUserUpdated:
    action: send
    channel:
      $ref: '#/channels/userEvents'
    messages:
      - $ref: '#/channels/userEvents/messages/userUpdatedMessage'
  consumeUserUpdated:
    action: receive
    channel:
      $ref: '#/channels/userEvents'
    messages:
      - $ref: '#/channels/userEvents/messages/userUpdatedMessage'

  # UserCommands channel operations - both send and receive on same channel
  sendCreateUserCommand:
    action: send
    channel:
      $ref: '#/channels/userCommands'
    messages:
      - $ref: '#/channels/userCommands/messages/createUserMessage'
  receiveCreateUserCommand:
    action: receive
    channel:
      $ref: '#/channels/userCommands'
    messages:
      - $ref: '#/channels/userCommands/messages/createUserMessage'
  sendUpdateUserCommand:
    action: send
    channel:
      $ref: '#/channels/userCommands'
    messages:
      - $ref: '#/channels/userCommands/messages/updateUserMessage'
  receiveUpdateUserCommand:
    action: receive
    channel:
      $ref: '#/channels/userCommands'
    messages:
      - $ref: '#/channels/userCommands/messages/updateUserMessage'

  # Notifications channel operations
  sendEmailNotification:
    action: send
    channel:
      $ref: '#/channels/notifications'
    messages:
      - $ref: '#/channels/notifications/messages/emailNotificationMessage'
  receiveEmailNotification:
    action: receive
    channel:
      $ref: '#/channels/notifications'
    messages:
      - $ref: '#/channels/notifications/messages/emailNotificationMessage'

components:
  messages:
    UserCreated:
      name: userCreated
      title: User created event
      summary: Notification that a new user has been created
      contentType: application/json
      payload:
        $ref: '#/components/schemas/UserCreatedPayload'
    UserUpdated:
      name: userUpdated
      title: User updated event
      summary: Notification that a user has been updated
      contentType: application/json
      payload:
        $ref: '#/components/schemas/UserUpdatedPayload'
    CreateUser:
      name: createUser
      title: Create user command
      summary: Command to create a new user
      contentType: application/json
      payload:
        $ref: '#/components/schemas/CreateUserPayload'
    UpdateUser:
      name: updateUser
      title: Update user command
      summary: Command to update an existing user
      contentType: application/json
      payload:
        $ref: '#/components/schemas/UpdateUserPayload'
    EmailNotification:
      name: emailNotification
      title: Email notification event
      summary: Event indicating an email notification has been sent
      contentType: application/json
      payload:
        $ref: '#/components/schemas/EmailNotificationPayload'

  schemas:
    UserCreatedPayload:
      type: object
      properties:
        userId:
          type: string
          format: uuid
          description: Unique identifier for the user
        username:
          type: string
          description: Username of the created user
        email:
          type: string
          format: email
          description: Email address of the user
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the user was created
      required:
        - userId
        - username
        - email
        - createdAt

    UserUpdatedPayload:
      type: object
      properties:
        userId:
          type: string
          format: uuid
          description: Unique identifier for the user
        updatedFields:
          type: array
          items:
            type: string
          description: List of fields that were updated
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the user was updated
      required:
        - userId
        - updatedFields
        - updatedAt

    CreateUserPayload:
      type: object
      properties:
        username:
          type: string
          description: Username for the new user
        email:
          type: string
          format: email
          description: Email address for the new user
        firstName:
          type: string
          description: First name of the user
        lastName:
          type: string
          description: Last name of the user
      required:
        - username
        - email

    UpdateUserPayload:
      type: object
      properties:
        userId:
          type: string
          format: uuid
          description: Unique identifier for the user to update
        firstName:
          type: string
          description: Updated first name
        lastName:
          type: string
          description: Updated last name
        email:
          type: string
          format: email
          description: Updated email address
      required:
        - userId

    EmailNotificationPayload:
      type: object
      properties:
        recipient:
          type: string
          format: email
          description: Email address of the recipient
        subject:
          type: string
          description: Subject of the email
        sentAt:
          type: string
          format: date-time
          description: Timestamp when the email was sent
        status:
          type: string
          enum: [sent, failed, delivered]
          description: Delivery status of the email
      required:
        - recipient
        - subject
        - sentAt
        - status
