asyncapi: "2.6.0"
info:
  title: Subscriptions Service Async API
  version: 1.0.0
  description: |
    AsyncAPI specification for the EventZR Subscriptions Service.
    Defines all Kafka events published (produced) and consumed by subscriptions-svc.
    All events follow the CloudEvents 1.0 specification and use tenant_id as the Kafka partition key.
  contact:
    name: EventZR Platform Team
    url: https://eventzr.com
  license:
    name: Proprietary

servers:
  staging:
    url: b-1.eventzr-msk.xxxx.kafka.ap-south-1.amazonaws.com:9098
    protocol: kafka-secure
    description: Amazon MSK Serverless (staging)
    security:
      - saslScram: []

defaultContentType: application/json

channels:
  # ============================================================
  # PUBLISHED EVENTS (Producers) - 14 topics
  # ============================================================

  eventzr.subscription.created.v1:
    description: Emitted when a new subscription is created.
    publish:
      operationId: publishSubscriptionCreated
      summary: Subscription Created
      message:
        $ref: "#/components/messages/SubscriptionCreatedEvent"

  eventzr.subscription.upgraded.v1:
    description: Emitted when a subscription is upgraded to a higher tier.
    publish:
      operationId: publishSubscriptionUpgraded
      summary: Subscription Upgraded
      message:
        $ref: "#/components/messages/SubscriptionUpgradedEvent"

  eventzr.subscription.downgraded.v1:
    description: Emitted when a subscription is downgraded to a lower tier.
    publish:
      operationId: publishSubscriptionDowngraded
      summary: Subscription Downgraded
      message:
        $ref: "#/components/messages/SubscriptionDowngradedEvent"

  eventzr.subscription.cancelled.v1:
    description: Emitted when a subscription is cancelled.
    publish:
      operationId: publishSubscriptionCancelled
      summary: Subscription Cancelled
      message:
        $ref: "#/components/messages/SubscriptionCancelledEvent"

  eventzr.subscription.paused.v1:
    description: Emitted when a subscription is paused by the subscriber or admin.
    publish:
      operationId: publishSubscriptionPaused
      summary: Subscription Paused
      message:
        $ref: "#/components/messages/SubscriptionPausedEvent"

  eventzr.subscription.resumed.v1:
    description: Emitted when a paused subscription is resumed.
    publish:
      operationId: publishSubscriptionResumed
      summary: Subscription Resumed
      message:
        $ref: "#/components/messages/SubscriptionResumedEvent"

  eventzr.subscription.reactivated.v1:
    description: Emitted when a cancelled or paused subscription is reactivated.
    publish:
      operationId: publishSubscriptionReactivated
      summary: Subscription Reactivated
      message:
        $ref: "#/components/messages/SubscriptionReactivatedEvent"

  eventzr.subscription.payment_succeeded.v1:
    description: Emitted when a subscription payment is successfully processed.
    publish:
      operationId: publishPaymentSucceeded
      summary: Payment Succeeded
      message:
        $ref: "#/components/messages/PaymentSucceededEvent"

  eventzr.subscription.payment_failed.v1:
    description: Emitted when a subscription payment fails.
    publish:
      operationId: publishPaymentFailed
      summary: Payment Failed
      message:
        $ref: "#/components/messages/PaymentFailedEvent"

  eventzr.subscription.quota_exceeded.v1:
    description: Emitted when a subscription quota is exceeded.
    publish:
      operationId: publishQuotaExceeded
      summary: Quota Exceeded
      message:
        $ref: "#/components/messages/QuotaExceededEvent"

  eventzr.subscription.trial_started.v1:
    description: Emitted when a trial period begins for a subscription.
    publish:
      operationId: publishTrialStarted
      summary: Trial Started
      message:
        $ref: "#/components/messages/TrialStartedEvent"

  eventzr.subscription.trial_progressed.v1:
    description: Emitted when a trial progresses to the next phase.
    publish:
      operationId: publishTrialProgressed
      summary: Trial Progressed
      message:
        $ref: "#/components/messages/TrialProgressedEvent"

  eventzr.subscription.trial_ended.v1:
    description: Emitted when a trial period ends.
    publish:
      operationId: publishTrialEnded
      summary: Trial Ended
      message:
        $ref: "#/components/messages/TrialEndedEvent"

  eventzr.subscription.referral_applied.v1:
    description: Emitted when a referral code is successfully applied.
    publish:
      operationId: publishReferralApplied
      summary: Referral Applied
      message:
        $ref: "#/components/messages/ReferralAppliedEvent"

  # ============================================================
  # CONSUMED EVENTS (Subscribers) - 5 topics
  # ============================================================

  eventzr.tenant.created.v1:
    description: Consumed when a new tenant is created. Auto-provisions a BASE-tier subscription.
    subscribe:
      operationId: consumeTenantCreated
      summary: Tenant Created
      message:
        $ref: "#/components/messages/TenantCreatedEvent"

  eventzr.user.created.v1:
    description: Consumed when a new user is created. May trigger default subscription provisioning.
    subscribe:
      operationId: consumeUserCreated
      summary: User Created
      message:
        $ref: "#/components/messages/UserCreatedEvent"

  eventzr.user.deleted.v1:
    description: Consumed when a user is deleted. Triggers subscription cleanup.
    subscribe:
      operationId: consumeUserDeleted
      summary: User Deleted
      message:
        $ref: "#/components/messages/UserDeletedEvent"

  eventzr.wallet.transaction.completed.v1:
    description: Consumed when a wallet transaction completes. Used for payment reconciliation.
    subscribe:
      operationId: consumeWalletTransactionCompleted
      summary: Wallet Transaction Completed
      message:
        $ref: "#/components/messages/WalletTransactionCompletedEvent"

  eventzr.payments.webhook.received.v1:
    description: Consumed when a payment webhook is received from external payment providers.
    subscribe:
      operationId: consumePaymentWebhookReceived
      summary: Payment Webhook Received
      message:
        $ref: "#/components/messages/PaymentWebhookReceivedEvent"

components:
  securitySchemes:
    saslScram:
      type: scramSha256
      description: SASL/SCRAM-SHA-256 authentication for Amazon MSK

  messages:
    # ---- Published Messages ----

    SubscriptionCreatedEvent:
      name: SubscriptionCreatedEvent
      title: Subscription Created
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/SubscriptionCreatedPayload"

    SubscriptionUpgradedEvent:
      name: SubscriptionUpgradedEvent
      title: Subscription Upgraded
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/SubscriptionUpgradedPayload"

    SubscriptionDowngradedEvent:
      name: SubscriptionDowngradedEvent
      title: Subscription Downgraded
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/SubscriptionDowngradedPayload"

    SubscriptionCancelledEvent:
      name: SubscriptionCancelledEvent
      title: Subscription Cancelled
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/SubscriptionCancelledPayload"

    SubscriptionPausedEvent:
      name: SubscriptionPausedEvent
      title: Subscription Paused
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/SubscriptionPausedPayload"

    SubscriptionResumedEvent:
      name: SubscriptionResumedEvent
      title: Subscription Resumed
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/SubscriptionResumedPayload"

    SubscriptionReactivatedEvent:
      name: SubscriptionReactivatedEvent
      title: Subscription Reactivated
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/SubscriptionReactivatedPayload"

    PaymentSucceededEvent:
      name: PaymentSucceededEvent
      title: Payment Succeeded
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/PaymentSucceededPayload"

    PaymentFailedEvent:
      name: PaymentFailedEvent
      title: Payment Failed
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/PaymentFailedPayload"

    QuotaExceededEvent:
      name: QuotaExceededEvent
      title: Quota Exceeded
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/QuotaExceededPayload"

    TrialStartedEvent:
      name: TrialStartedEvent
      title: Trial Started
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/TrialStartedPayload"

    TrialProgressedEvent:
      name: TrialProgressedEvent
      title: Trial Progressed
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/TrialProgressedPayload"

    TrialEndedEvent:
      name: TrialEndedEvent
      title: Trial Ended
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/TrialEndedPayload"

    ReferralAppliedEvent:
      name: ReferralAppliedEvent
      title: Referral Applied
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/ReferralAppliedPayload"

    # ---- Consumed Messages ----

    TenantCreatedEvent:
      name: TenantCreatedEvent
      title: Tenant Created
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/TenantCreatedPayload"

    UserCreatedEvent:
      name: UserCreatedEvent
      title: User Created
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/UserCreatedPayload"

    UserDeletedEvent:
      name: UserDeletedEvent
      title: User Deleted
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/UserDeletedPayload"

    WalletTransactionCompletedEvent:
      name: WalletTransactionCompletedEvent
      title: Wallet Transaction Completed
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/WalletTransactionCompletedPayload"

    PaymentWebhookReceivedEvent:
      name: PaymentWebhookReceivedEvent
      title: Payment Webhook Received
      contentType: application/json
      headers:
        $ref: "#/components/schemas/CloudEventHeaders"
      payload:
        $ref: "#/components/schemas/PaymentWebhookReceivedPayload"

  schemas:
    # ---- CloudEvents envelope ----

    CloudEventHeaders:
      type: object
      required:
        - specversion
        - id
        - type
        - source
        - time
        - datacontenttype
      properties:
        specversion:
          type: string
          const: "1.0"
          description: CloudEvents specification version
        id:
          type: string
          format: ulid
          description: Unique event ID (ULID)
        type:
          type: string
          description: "Event type URI (e.g., com.eventzr.subscription.created.v1)"
        source:
          type: string
          description: Source service identifier
          example: subscriptions-svc
        subject:
          type: string
          description: "Subject of the event (e.g., subscription/uuid)"
        time:
          type: string
          format: date-time
          description: Event timestamp (ISO 8601)
        datacontenttype:
          type: string
          const: application/json

    # ---- Published Event Payloads ----

    SubscriptionCreatedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - actorId
        - actorType
        - planId
        - status
        - billingCycle
        - startDate
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        actorId:
          type: string
          format: uuid
        actorType:
          type: string
          enum: [user, team]
        planId:
          type: string
          format: uuid
        status:
          type: string
          enum: [active, trial]
        billingCycle:
          type: string
          enum: [monthly, annually]
        startDate:
          type: string
          format: date-time
        trialEndDate:
          type: string
          format: date-time
          nullable: true

    SubscriptionUpgradedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - previousPlanId
        - newPlanId
        - upgradedBy
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        previousPlanId:
          type: string
          format: uuid
        newPlanId:
          type: string
          format: uuid
        upgradedBy:
          type: string
          format: uuid
        immediate:
          type: boolean
        proratedAmount:
          type: number

    SubscriptionDowngradedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - previousPlanId
        - newPlanId
        - downgradedBy
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        previousPlanId:
          type: string
          format: uuid
        newPlanId:
          type: string
          format: uuid
        downgradedBy:
          type: string
          format: uuid
        immediate:
          type: boolean
        effectiveDate:
          type: string
          format: date-time

    SubscriptionCancelledPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - cancelReason
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        cancelReason:
          type: string
          enum:
            [
              user_requested,
              payment_failed,
              trial_ended,
              upgraded,
              downgraded,
              admin_action,
              other,
            ]
        cancelledAt:
          type: string
          format: date-time
        cancelAtPeriodEnd:
          type: boolean

    SubscriptionPausedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - actorId
        - actorType
        - planId
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        actorId:
          type: string
          format: uuid
        actorType:
          type: string
          enum: [user, team]
        planId:
          type: string
          format: uuid
        pausedAt:
          type: string
          format: date-time

    SubscriptionResumedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - actorId
        - actorType
        - planId
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        actorId:
          type: string
          format: uuid
        actorType:
          type: string
          enum: [user, team]
        planId:
          type: string
          format: uuid
        resumedAt:
          type: string
          format: date-time

    SubscriptionReactivatedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        reactivatedAt:
          type: string
          format: date-time
        newPeriodEnd:
          type: string
          format: date-time

    PaymentSucceededPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - amount
        - currency
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        invoiceId:
          type: string
          format: uuid
        amount:
          type: number
          description: Amount in cents
        currency:
          type: string
          example: USD
        paymentMethod:
          type: string
        paidAt:
          type: string
          format: date-time

    PaymentFailedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - amount
        - currency
        - failureReason
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        invoiceId:
          type: string
          format: uuid
        amount:
          type: number
        currency:
          type: string
        failureReason:
          type: string
        retryCount:
          type: integer
        nextRetryAt:
          type: string
          format: date-time
          nullable: true

    QuotaExceededPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - featureKey
        - currentUsage
        - limit
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        featureKey:
          type: string
        currentUsage:
          type: integer
        limit:
          type: integer
        exceededAt:
          type: string
          format: date-time

    TrialStartedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - trialEndDate
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        trialEndDate:
          type: string
          format: date-time

    TrialProgressedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - fromPhase
        - toPhase
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        fromPhase:
          type: string
          description: Previous trial phase
        toPhase:
          type: string
          description: New trial phase
        daysRemaining:
          type: integer

    TrialEndedPayload:
      type: object
      required:
        - subscriptionId
        - tenantId
        - converted
      properties:
        subscriptionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        converted:
          type: boolean
          description: Whether the trial converted to a paid subscription
        finalTier:
          type: string
        endedAt:
          type: string
          format: date-time

    ReferralAppliedPayload:
      type: object
      required:
        - referralCode
        - referrerId
        - referredUserId
        - subscriptionId
      properties:
        referralCode:
          type: string
        referrerId:
          type: string
          format: uuid
        referredUserId:
          type: string
          format: uuid
        subscriptionId:
          type: string
          format: uuid
        rewardAmount:
          type: number
        tenantId:
          type: string
          format: uuid

    # ---- Consumed Event Payloads ----

    TenantCreatedPayload:
      type: object
      required:
        - tenantId
        - userId
      properties:
        tenantId:
          type: string
          format: uuid
          description: The newly created tenant ID
        userId:
          type: string
          format: uuid
          description: The owner/creator user ID
        tenantName:
          type: string
        plan:
          type: string
          description: Requested plan tier (defaults to BASE)

    UserCreatedPayload:
      type: object
      required:
        - userId
        - tenantId
      properties:
        userId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        email:
          type: string
          format: email
        role:
          type: string

    UserDeletedPayload:
      type: object
      required:
        - userId
        - tenantId
      properties:
        userId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        deletedAt:
          type: string
          format: date-time

    WalletTransactionCompletedPayload:
      type: object
      required:
        - transactionId
        - walletId
        - amount
        - type
      properties:
        transactionId:
          type: string
          format: uuid
        walletId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        amount:
          type: number
        currency:
          type: string
        type:
          type: string
          enum: [credit, debit]
        reference:
          type: string
          description: Reference to subscription or invoice

    PaymentWebhookReceivedPayload:
      type: object
      required:
        - provider
        - eventType
        - payload
      properties:
        provider:
          type: string
          description: "Payment provider (e.g., stripe, razorpay)"
        eventType:
          type: string
          description: "Provider event type (e.g., payment_intent.succeeded)"
        payload:
          type: object
          additionalProperties: true
          description: Raw webhook payload from the payment provider
        tenantId:
          type: string
          format: uuid
        subscriptionId:
          type: string
          format: uuid
