asyncapi: 2.6.0
info:
  title: marketplace-svc Async API
  version: 2.1.0
  description: |
    Kafka event specification for the EventZR Marketplace Service.
    All events use CloudEvents 1.0 format and are partitioned by tenantId.
  contact:
    name: EventZR Platform Team
    email: platform@eventzr.com
  license:
    name: PROPRIETARY

servers:
  staging:
    url: boot-gpm4u49z.c2.kafka-serverless.us-east-1.amazonaws.com:9098
    protocol: kafka-secure
    description: Amazon MSK Serverless (staging)
    security:
      - saslAwsIam: []

defaultContentType: application/json

channels:
  # ─── PRODUCER CHANNELS (12) ───────────────────────────────────────

  eventzr.marketplace.listing.created.v1:
    description: Emitted when a new listing is created
    publish:
      operationId: onListingCreated
      summary: Listing created
      message:
        $ref: '#/components/messages/ListingEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.listing.published.v1:
    description: Emitted when a listing transitions from draft to published
    publish:
      operationId: onListingPublished
      summary: Listing published
      message:
        $ref: '#/components/messages/ListingEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.listing.updated.v1:
    description: Emitted when a listing is updated
    publish:
      operationId: onListingUpdated
      summary: Listing updated
      message:
        $ref: '#/components/messages/ListingEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.listing.closed.v1:
    description: Emitted when a listing is closed
    publish:
      operationId: onListingClosed
      summary: Listing closed
      message:
        $ref: '#/components/messages/ListingEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.quote.submitted.v1:
    description: Emitted when a new quote/proposal is submitted
    publish:
      operationId: onQuoteSubmitted
      summary: Quote submitted
      message:
        $ref: '#/components/messages/QuoteEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.quote.accepted.v1:
    description: Emitted when a quote is accepted by the listing owner
    publish:
      operationId: onQuoteAccepted
      summary: Quote accepted
      message:
        $ref: '#/components/messages/QuoteEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.order.created.v1:
    description: Emitted when a new order is created from an accepted quote
    publish:
      operationId: onOrderCreated
      summary: Order created
      message:
        $ref: '#/components/messages/OrderEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.order.completed.v1:
    description: Emitted when an order is confirmed complete by the buyer
    publish:
      operationId: onOrderCompleted
      summary: Order completed
      message:
        $ref: '#/components/messages/OrderEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.order.cancelled.v1:
    description: Emitted when an order is cancelled
    publish:
      operationId: onOrderCancelled
      summary: Order cancelled
      message:
        $ref: '#/components/messages/OrderEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.dispute.opened.v1:
    description: Emitted when a dispute is opened on an order
    publish:
      operationId: onDisputeOpened
      summary: Dispute opened
      message:
        $ref: '#/components/messages/DisputeEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.dispute.resolved.v1:
    description: Emitted when a dispute is resolved by an admin
    publish:
      operationId: onDisputeResolved
      summary: Dispute resolved
      message:
        $ref: '#/components/messages/DisputeEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  eventzr.marketplace.rfp.broadcast.v1:
    description: Emitted when an RFP is broadcast to matching sellers
    publish:
      operationId: onRfpBroadcast
      summary: RFP broadcast
      message:
        $ref: '#/components/messages/RfpEvent'
      bindings:
        kafka:
          key:
            type: string
            description: tenantId (partition key)

  # ─── CONSUMER CHANNELS (6) ────────────────────────────────────────

  eventzr.event.created.v1:
    description: Consumed from event-svc to auto-suggest marketplace listings for new events
    subscribe:
      operationId: handleEventCreated
      summary: Auto-suggest marketplace listings
      message:
        $ref: '#/components/messages/EventCreatedInbound'
      bindings:
        kafka:
          groupId: marketplace-svc-events

  eventzr.reviews.review.created.v1:
    description: Consumed from reviews-svc to update listing averageRating and totalReviews
    subscribe:
      operationId: handleReviewCreated
      summary: Update listing rating
      message:
        $ref: '#/components/messages/ReviewCreatedInbound'
      bindings:
        kafka:
          groupId: marketplace-svc-reviews

  eventzr.wallet.payment.completed.v1:
    description: Consumed from wallet-svc to update order payment status
    subscribe:
      operationId: handlePaymentCompleted
      summary: Update order payment
      message:
        $ref: '#/components/messages/PaymentCompletedInbound'
      bindings:
        kafka:
          groupId: marketplace-svc-wallet

  eventzr.wallet.escrow.released.v1:
    description: Consumed from wallet-svc to update seller payout on order
    subscribe:
      operationId: handleEscrowReleased
      summary: Update seller payout
      message:
        $ref: '#/components/messages/EscrowReleasedInbound'
      bindings:
        kafka:
          groupId: marketplace-svc-wallet

  eventzr.subscriptions.subscription.changed.v1:
    description: Consumed from subscriptions-svc to update seller tier limits
    subscribe:
      operationId: handleSubscriptionChanged
      summary: Update seller tier
      message:
        $ref: '#/components/messages/SubscriptionChangedInbound'
      bindings:
        kafka:
          groupId: marketplace-svc-subscriptions

  eventzr.user.profile.updated.v1:
    description: Consumed from user-svc to update seller profile cache
    subscribe:
      operationId: handleUserProfileUpdated
      summary: Update seller profile cache
      message:
        $ref: '#/components/messages/UserProfileUpdatedInbound'
      bindings:
        kafka:
          groupId: marketplace-svc-users

components:
  securitySchemes:
    saslAwsIam:
      type: scramSha512
      description: AWS MSK IAM authentication

  messages:
    # ─── PRODUCER MESSAGES ──────────────────────────────────────────

    ListingEvent:
      name: ListingEvent
      title: Marketplace Listing Event
      contentType: application/json
      headers:
        $ref: '#/components/schemas/CloudEventHeaders'
      payload:
        $ref: '#/components/schemas/ListingPayload'

    QuoteEvent:
      name: QuoteEvent
      title: Marketplace Quote Event
      contentType: application/json
      headers:
        $ref: '#/components/schemas/CloudEventHeaders'
      payload:
        $ref: '#/components/schemas/QuotePayload'

    OrderEvent:
      name: OrderEvent
      title: Marketplace Order Event
      contentType: application/json
      headers:
        $ref: '#/components/schemas/CloudEventHeaders'
      payload:
        $ref: '#/components/schemas/OrderPayload'

    DisputeEvent:
      name: DisputeEvent
      title: Marketplace Dispute Event
      contentType: application/json
      headers:
        $ref: '#/components/schemas/CloudEventHeaders'
      payload:
        $ref: '#/components/schemas/DisputePayload'

    RfpEvent:
      name: RfpEvent
      title: RFP Broadcast Event
      contentType: application/json
      headers:
        $ref: '#/components/schemas/CloudEventHeaders'
      payload:
        $ref: '#/components/schemas/RfpPayload'

    # ─── CONSUMER MESSAGES ──────────────────────────────────────────

    EventCreatedInbound:
      name: EventCreatedInbound
      title: Event Created (from event-svc)
      contentType: application/json
      payload:
        type: object
        properties:
          eventId:
            type: string
            format: uuid
          tenantId:
            type: string
            format: uuid

    ReviewCreatedInbound:
      name: ReviewCreatedInbound
      title: Review Created (from reviews-svc)
      contentType: application/json
      payload:
        type: object
        properties:
          listingId:
            type: string
            format: uuid
          rating:
            type: number
            minimum: 0
            maximum: 5
          tenantId:
            type: string
            format: uuid

    PaymentCompletedInbound:
      name: PaymentCompletedInbound
      title: Payment Completed (from wallet-svc)
      contentType: application/json
      payload:
        type: object
        properties:
          orderId:
            type: string
            format: uuid
          transactionId:
            type: string
            format: uuid
          tenantId:
            type: string
            format: uuid

    EscrowReleasedInbound:
      name: EscrowReleasedInbound
      title: Escrow Released (from wallet-svc)
      contentType: application/json
      payload:
        type: object
        properties:
          orderId:
            type: string
            format: uuid
          sellerId:
            type: string
            format: uuid
          amount:
            type: number
          tenantId:
            type: string
            format: uuid

    SubscriptionChangedInbound:
      name: SubscriptionChangedInbound
      title: Subscription Changed (from subscriptions-svc)
      contentType: application/json
      payload:
        type: object
        properties:
          userId:
            type: string
            format: uuid
          newTier:
            type: string
          tenantId:
            type: string
            format: uuid

    UserProfileUpdatedInbound:
      name: UserProfileUpdatedInbound
      title: User Profile Updated (from user-svc)
      contentType: application/json
      payload:
        type: object
        properties:
          userId:
            type: string
            format: uuid
          tenantId:
            type: string
            format: uuid

  schemas:
    CloudEventHeaders:
      type: object
      required:
        - specversion
        - type
        - source
        - id
        - time
        - datacontenttype
        - tenantid
      properties:
        specversion:
          type: string
          const: '1.0'
          description: CloudEvents specification version
        type:
          type: string
          description: Event type (e.g., eventzr.marketplace.listing.created.v1)
        source:
          type: string
          const: eventzr/marketplace-svc
          description: Event source service
        id:
          type: string
          format: uuid
          description: Unique event ID
        time:
          type: string
          format: date-time
          description: Event timestamp (ISO 8601)
        datacontenttype:
          type: string
          const: application/json
        tenantid:
          type: string
          format: uuid
          description: Tenant ID (partition key)

    ListingPayload:
      type: object
      properties:
        listing:
          type: object
          properties:
            id:
              type: string
              format: uuid
            tenantId:
              type: string
              format: uuid
            category:
              type: string
              enum: [spotlight, synapse, squad, meridian, portico, vendora, poper, nexus, cortex]
            sellerId:
              type: string
              format: uuid
            title:
              type: string
            status:
              type: string
              enum: [draft, published, paused, closed]
            priceMin:
              type: number
            priceMax:
              type: number
            currency:
              type: string

    QuotePayload:
      type: object
      properties:
        quote:
          type: object
          properties:
            id:
              type: string
              format: uuid
            tenantId:
              type: string
              format: uuid
            listingId:
              type: string
              format: uuid
            responderId:
              type: string
              format: uuid
            status:
              type: string
              enum: [pending, accepted, rejected, withdrawn, negotiating]
            amount:
              type: number
            currency:
              type: string

    OrderPayload:
      type: object
      properties:
        order:
          type: object
          properties:
            id:
              type: string
              format: uuid
            tenantId:
              type: string
              format: uuid
            listingId:
              type: string
              format: uuid
            buyerId:
              type: string
              format: uuid
            sellerId:
              type: string
              format: uuid
            status:
              type: string
              enum: [pending_payment, paid, in_progress, delivered, completed, cancelled, refunded]
            totalAmount:
              type: number
            currency:
              type: string

    DisputePayload:
      type: object
      properties:
        dispute:
          type: object
          properties:
            id:
              type: string
              format: uuid
            tenantId:
              type: string
              format: uuid
            orderId:
              type: string
              format: uuid
            initiatedBy:
              type: string
              enum: [buyer, seller]
            reason:
              type: string
            status:
              type: string
              enum: [open, investigating, resolved, escalated]

    RfpPayload:
      type: object
      properties:
        rfp:
          type: object
          properties:
            listingId:
              type: string
              format: uuid
            tenantId:
              type: string
              format: uuid
            matchCount:
              type: integer
            broadcastedAt:
              type: string
              format: date-time
