openapi: 3.1.0
info:
  title: Regen Therapy Distribution Platform API
  description: |
    Enterprise-grade RESTful API for the Regen Therapy multi-tenant distribution platform.
    
    ## Overview
    This API enables programmatic access to orders, products, inventory, commissions, 
    webhooks, and more. It's designed for partners, integrators, and developers building
    custom solutions on top of the Regen Therapy platform.
    
    ## Authentication
    All API requests require authentication using either:
    - **API Keys**: Passed via `X-API-Key` header
    - **JWT Tokens**: Passed via `Authorization: Bearer <token>` header
    
    ## Rate Limiting
    - Standard: 100 requests/hour per API key
    - Burst: 10 requests/minute
    - Rate limit headers are included in all responses
    
    ## Pagination
    List endpoints support pagination via `page` and `limit` query parameters.
    Responses include pagination metadata.
    
    ## Errors
    Errors follow a consistent JSON structure with `success: false` and an `error` object.
    
  version: 1.0.0
  contact:
    name: Regen Therapy Developer Support
    email: api-support@regentherapy.com
    url: https://developers.regentherapy.com
  license:
    name: Proprietary
    url: https://regentherapy.com/terms
  termsOfService: https://regentherapy.com/api-terms

servers:
  - url: https://gateway.regentherapy.com/api/v1
    description: Production server
  - url: https://sandbox.regentherapy.com/api/v1
    description: Sandbox/Testing server
  - url: http://localhost:3000/api/v1
    description: Local development

tags:
  - name: Authentication
    description: Authentication and authorization endpoints
  - name: Orders
    description: Order management operations
  - name: Products
    description: Product catalog operations
  - name: Inventory
    description: Inventory management operations
  - name: Commissions
    description: Commission tracking and payouts
  - name: Webhooks
    description: Webhook endpoint configuration
  - name: API Keys
    description: API key management

security:
  - ApiKeyAuth: []
  - BearerAuth: []

paths:
  /orders:
    get:
      operationId: listOrders
      summary: List orders
      description: |
        Retrieve a paginated list of orders for your tenant. Supports filtering by status,
        date range, and other criteria.
      tags:
        - Orders
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: status
          in: query
          description: Filter by order status
          schema:
            type: string
            enum: [PENDING, CONFIRMED, PROCESSING, SHIPPED, DELIVERED, CANCELLED, REFUNDED]
        - name: startDate
          in: query
          description: Filter orders created after this date (ISO 8601)
          schema:
            type: string
            format: date-time
        - name: endDate
          in: query
          description: Filter orders created before this date (ISO 8601)
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/PaginatedOrders'
              example:
                success: true
                data:
                  data:
                    - id: "550e8400-e29b-41d4-a716-446655440000"
                      orderNumber: "ORD-1713456789-ABCD12"
                      status: "PROCESSING"
                      totalAmount: 1520.00
                      itemCount: 8
                      createdAt: "2026-04-18T10:30:00Z"
                  pagination:
                    page: 1
                    limit: 10
                    total: 156
                    pages: 16
                meta:
                  timestamp: "2026-04-18T14:30:00Z"
                  requestId: "req_abc123"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
    
    post:
      operationId: createOrder
      summary: Create order
      description: |
        Create a new order. The order will be created in PENDING status and
        inventory will be reserved for the items.
      tags:
        - Orders
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrderRequest'
            example:
              customerId: "cust_123"
              items:
                - productId: "550e8400-e29b-41d4-a716-446655440001"
                  quantity: 5
                - productId: "550e8400-e29b-41d4-a716-446655440002"
                  quantity: 3
              shippingAddress:
                firstName: "John"
                lastName: "Smith"
                address1: "123 Main St"
                city: "Austin"
                state: "TX"
                postalCode: "78701"
                country: "US"
              notes: "Please ship ASAP"
      responses:
        '201':
          description: Order created successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Order'
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

  /orders/{orderId}:
    get:
      operationId: getOrder
      summary: Get order details
      description: Retrieve complete details for a specific order including all items.
      tags:
        - Orders
      parameters:
        - $ref: '#/components/parameters/OrderIdParam'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/OrderDetail'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'

    put:
      operationId: updateOrder
      summary: Update order
      description: Update an existing order. Some fields may not be editable depending on order status.
      tags:
        - Orders
      parameters:
        - $ref: '#/components/parameters/OrderIdParam'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrderRequest'
      responses:
        '200':
          description: Order updated successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Order'
        '400':
          $ref: '#/components/responses/ValidationError'
        '404':
          $ref: '#/components/responses/NotFound'

  /products:
    get:
      operationId: listProducts
      summary: List products
      description: Retrieve the product catalog with inventory information.
      tags:
        - Products
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: category
          in: query
          description: Filter by category name
          schema:
            type: string
        - name: active
          in: query
          description: Filter by active status
          schema:
            type: boolean
        - name: search
          in: query
          description: Search by name or SKU
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/PaginatedProducts'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      operationId: createProduct
      summary: Create product
      description: Create a new product in the catalog. Requires admin permissions.
      tags:
        - Products
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProductRequest'
      responses:
        '201':
          description: Product created successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Product'
        '400':
          $ref: '#/components/responses/ValidationError'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'

  /products/{productId}:
    get:
      operationId: getProduct
      summary: Get product details
      description: Retrieve complete details for a specific product.
      tags:
        - Products
      parameters:
        - $ref: '#/components/parameters/ProductIdParam'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Product'
        '404':
          $ref: '#/components/responses/NotFound'

  /inventory:
    get:
      operationId: listInventory
      summary: List inventory
      description: Retrieve inventory levels across warehouses with low stock alerts.
      tags:
        - Inventory
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: warehouseId
          in: query
          description: Filter by warehouse
          schema:
            type: string
            format: uuid
        - name: productId
          in: query
          description: Filter by product
          schema:
            type: string
            format: uuid
        - name: lowStock
          in: query
          description: Only show low stock items
          schema:
            type: boolean
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/InventoryResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'

    put:
      operationId: adjustInventory
      summary: Adjust inventory
      description: |
        Record an inventory adjustment. Supports various adjustment reasons
        like stock count corrections, damage, returns, etc.
      tags:
        - Inventory
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InventoryAdjustmentRequest'
            example:
              productId: "550e8400-e29b-41d4-a716-446655440001"
              quantity: -5
              reason: "DAMAGE"
              notes: "Items damaged in transit"
      responses:
        '200':
          description: Inventory adjusted successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/InventoryTransaction'
        '400':
          $ref: '#/components/responses/ValidationError'
        '404':
          $ref: '#/components/responses/NotFound'

  /commissions:
    get:
      operationId: listCommissions
      summary: List commissions
      description: Retrieve commission records with summary statistics.
      tags:
        - Commissions
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: status
          in: query
          description: Filter by commission status
          schema:
            type: string
            enum: [PENDING, ACCRUED, SCHEDULED, PAID]
        - name: startDate
          in: query
          schema:
            type: string
            format: date-time
        - name: endDate
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/CommissionsResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      operationId: createPayout
      summary: Create commission payout
      description: Schedule a commission payout for a partner. Requires finance permissions.
      tags:
        - Commissions
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePayoutRequest'
      responses:
        '201':
          description: Payout scheduled successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Payout'
        '400':
          $ref: '#/components/responses/ValidationError'
        '403':
          $ref: '#/components/responses/Forbidden'

  /webhooks:
    get:
      operationId: listWebhooks
      summary: List webhook endpoints
      description: Retrieve configured webhook endpoints and delivery statistics.
      tags:
        - Webhooks
      parameters:
        - name: endpointId
          in: query
          description: Get deliveries for a specific endpoint
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/WebhooksResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      operationId: createWebhook
      summary: Create webhook endpoint
      description: |
        Register a new webhook endpoint to receive event notifications.
        A signing secret will be returned - store it securely.
      tags:
        - Webhooks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWebhookRequest'
            example:
              name: "Production Events"
              url: "https://api.example.com/webhooks/regen"
              subscribedEvents:
                - "order.created"
                - "order.shipped"
                - "inventory.low_stock"
      responses:
        '201':
          description: Webhook created successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/WebhookEndpointCreated'
        '400':
          $ref: '#/components/responses/ValidationError'

  /webhooks/{webhookId}:
    delete:
      operationId: deleteWebhook
      summary: Delete webhook endpoint
      description: Remove a webhook endpoint. Pending deliveries will be cancelled.
      tags:
        - Webhooks
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Webhook deleted successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /api-keys:
    get:
      operationId: listApiKeys
      summary: List API keys
      description: Retrieve all API keys for your tenant. Key secrets are not returned.
      tags:
        - API Keys
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/ApiKeysResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      operationId: createApiKey
      summary: Create API key
      description: |
        Generate a new API key. The full key is only returned once upon creation.
        Store it securely - it cannot be retrieved again.
      tags:
        - API Keys
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateApiKeyRequest'
            example:
              name: "Production Integration"
              scopes:
                - "read:orders"
                - "write:orders"
                - "read:products"
              expiresAt: "2027-04-18T00:00:00Z"
      responses:
        '201':
          description: API key created successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/ApiKeyCreated'
        '400':
          $ref: '#/components/responses/ValidationError'

  /api-keys/{keyId}:
    delete:
      operationId: deleteApiKey
      summary: Revoke API key
      description: Immediately revoke an API key. All subsequent requests will be rejected.
      tags:
        - API Keys
      parameters:
        - name: keyId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: API key revoked successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '404':
          $ref: '#/components/responses/NotFound'

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for authentication
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token from login

  parameters:
    PageParam:
      name: page
      in: query
      description: Page number (1-indexed)
      schema:
        type: integer
        minimum: 1
        default: 1
    LimitParam:
      name: limit
      in: query
      description: Items per page (max 100)
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    OrderIdParam:
      name: orderId
      in: path
      required: true
      description: Order UUID
      schema:
        type: string
        format: uuid
    ProductIdParam:
      name: productId
      in: path
      required: true
      description: Product UUID
      schema:
        type: string
        format: uuid

  responses:
    Unauthorized:
      description: Authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "UNAUTHORIZED"
              message: "Authentication required"
            meta:
              timestamp: "2026-04-18T14:30:00Z"
              requestId: "req_abc123"
    
    Forbidden:
      description: Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "FORBIDDEN"
              message: "Insufficient permissions"
            meta:
              timestamp: "2026-04-18T14:30:00Z"
              requestId: "req_abc123"
    
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "NOT_FOUND"
              message: "Resource not found"
            meta:
              timestamp: "2026-04-18T14:30:00Z"
              requestId: "req_abc123"
    
    ValidationError:
      description: Validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "VALIDATION_ERROR"
              message: "Invalid request body"
              details:
                field: "items"
                issue: "Must contain at least one item"
            meta:
              timestamp: "2026-04-18T14:30:00Z"
              requestId: "req_abc123"
    
    Conflict:
      description: Resource conflict
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "CONFLICT"
              message: "SKU already exists"
            meta:
              timestamp: "2026-04-18T14:30:00Z"
              requestId: "req_abc123"
    
    RateLimited:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
          description: Request limit per hour
        X-RateLimit-Remaining:
          schema:
            type: integer
          description: Remaining requests
        X-RateLimit-Reset:
          schema:
            type: integer
          description: Unix timestamp when limit resets
        Retry-After:
          schema:
            type: integer
          description: Seconds until retry is allowed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "RATE_LIMITED"
              message: "Too many requests"
            meta:
              timestamp: "2026-04-18T14:30:00Z"
              requestId: "req_abc123"
    
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "INTERNAL_ERROR"
              message: "An unexpected error occurred"
            meta:
              timestamp: "2026-04-18T14:30:00Z"
              requestId: "req_abc123"

  schemas:
    SuccessResponse:
      type: object
      required:
        - success
        - meta
      properties:
        success:
          type: boolean
          example: true
        meta:
          $ref: '#/components/schemas/ResponseMeta'

    ErrorResponse:
      type: object
      required:
        - success
        - error
        - meta
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - UNAUTHORIZED
                - FORBIDDEN
                - NOT_FOUND
                - VALIDATION_ERROR
                - CONFLICT
                - RATE_LIMITED
                - INTERNAL_ERROR
            message:
              type: string
            details:
              type: object
              additionalProperties: true
        meta:
          $ref: '#/components/schemas/ResponseMeta'

    ResponseMeta:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        requestId:
          type: string

    Pagination:
      type: object
      properties:
        page:
          type: integer
        limit:
          type: integer
        total:
          type: integer
        pages:
          type: integer

    # Orders
    Order:
      type: object
      properties:
        id:
          type: string
          format: uuid
        orderNumber:
          type: string
        tenantId:
          type: string
          format: uuid
        customerId:
          type: string
          format: uuid
        customerEmail:
          type: string
          format: email
        customerName:
          type: string
        status:
          type: string
          enum: [PENDING, CONFIRMED, PROCESSING, SHIPPED, DELIVERED, CANCELLED, REFUNDED]
        paymentStatus:
          type: string
          enum: [PENDING, PAID, PARTIALLY_PAID, REFUNDED]
        subtotal:
          type: number
          format: double
        taxAmount:
          type: number
          format: double
        shippingAmount:
          type: number
          format: double
        discountAmount:
          type: number
          format: double
        totalAmount:
          type: number
          format: double
        currency:
          type: string
          default: USD
        itemCount:
          type: integer
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    OrderDetail:
      allOf:
        - $ref: '#/components/schemas/Order'
        - type: object
          properties:
            items:
              type: array
              items:
                $ref: '#/components/schemas/OrderItem'
            shippingAddress:
              $ref: '#/components/schemas/Address'
            billingAddress:
              $ref: '#/components/schemas/Address'
            notes:
              type: string

    OrderItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
        productId:
          type: string
          format: uuid
        productName:
          type: string
        sku:
          type: string
        quantity:
          type: integer
        unitPrice:
          type: number
          format: double
        lineTotal:
          type: number
          format: double

    PaginatedOrders:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Order'
        pagination:
          $ref: '#/components/schemas/Pagination'

    CreateOrderRequest:
      type: object
      required:
        - items
        - shippingAddress
      properties:
        customerId:
          type: string
          format: uuid
        items:
          type: array
          minItems: 1
          items:
            type: object
            required:
              - productId
              - quantity
            properties:
              productId:
                type: string
                format: uuid
              quantity:
                type: integer
                minimum: 1
              price:
                type: number
                description: Optional override price
        shippingAddress:
          $ref: '#/components/schemas/Address'
        billingAddress:
          $ref: '#/components/schemas/Address'
        taxRate:
          type: number
          minimum: 0
          maximum: 1
        shippingAmount:
          type: number
        discountAmount:
          type: number
        currency:
          type: string
          default: USD
        notes:
          type: string

    UpdateOrderRequest:
      type: object
      properties:
        status:
          type: string
          enum: [CONFIRMED, PROCESSING, SHIPPED, DELIVERED, CANCELLED]
        shippingAddress:
          $ref: '#/components/schemas/Address'
        notes:
          type: string

    Address:
      type: object
      properties:
        firstName:
          type: string
        lastName:
          type: string
        company:
          type: string
        address1:
          type: string
        address2:
          type: string
        city:
          type: string
        state:
          type: string
        postalCode:
          type: string
        country:
          type: string
        phone:
          type: string

    # Products
    Product:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        sku:
          type: string
        barcode:
          type: string
        description:
          type: string
        shortDescription:
          type: string
        basePrice:
          type: number
          format: double
        costPrice:
          type: number
          format: double
        compareAtPrice:
          type: number
          format: double
        isActive:
          type: boolean
        isControlled:
          type: boolean
        requiresPrescription:
          type: boolean
        weight:
          type: number
        weightUnit:
          type: string
          enum: [oz, lb, g, kg]
        dimensions:
          type: object
          properties:
            length:
              type: number
            width:
              type: number
            height:
              type: number
            unit:
              type: string
        category:
          type: object
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
        inventory:
          type: object
          properties:
            total:
              type: integer
            available:
              type: integer
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    PaginatedProducts:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Product'
        pagination:
          $ref: '#/components/schemas/Pagination'

    CreateProductRequest:
      type: object
      required:
        - name
        - sku
        - basePrice
      properties:
        name:
          type: string
        sku:
          type: string
        barcode:
          type: string
        description:
          type: string
        shortDescription:
          type: string
        basePrice:
          type: number
          minimum: 0
        costPrice:
          type: number
        compareAtPrice:
          type: number
        categoryId:
          type: string
          format: uuid
        isActive:
          type: boolean
          default: true
        isControlled:
          type: boolean
          default: false
        requiresPrescription:
          type: boolean
          default: false
        weight:
          type: number
        weightUnit:
          type: string
          enum: [oz, lb, g, kg]
        dimensions:
          type: object

    # Inventory
    InventoryItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
        productId:
          type: string
          format: uuid
        productName:
          type: string
        sku:
          type: string
        warehouseId:
          type: string
          format: uuid
        warehouseName:
          type: string
        warehouseLocation:
          type: string
        quantity:
          type: integer
        reservedQuantity:
          type: integer
        availableQuantity:
          type: integer
        reorderPoint:
          type: integer
        reorderQuantity:
          type: integer
        binLocation:
          type: string
        lotNumber:
          type: string
        expirationDate:
          type: string
          format: date
        unitCost:
          type: number
        lastCountedAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    InventoryResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/InventoryItem'
        summary:
          type: object
          properties:
            totalItems:
              type: integer
            lowStockCount:
              type: integer
            outOfStockCount:
              type: integer
            totalValue:
              type: number
        pagination:
          $ref: '#/components/schemas/Pagination'

    InventoryAdjustmentRequest:
      type: object
      required:
        - productId
        - quantity
        - reason
      properties:
        productId:
          type: string
          format: uuid
        warehouseId:
          type: string
          format: uuid
        quantity:
          type: integer
          description: Positive to add, negative to remove
        reason:
          type: string
          enum: [STOCK_IN, RECOUNT, DAMAGE, THEFT, RETURN, CORRECTION, ADJUSTMENT, TRANSFER]
        notes:
          type: string

    InventoryTransaction:
      type: object
      properties:
        id:
          type: string
          format: uuid
        productId:
          type: string
          format: uuid
        transactionType:
          type: string
        quantityChange:
          type: integer
        previousQuantity:
          type: integer
        newQuantity:
          type: integer
        reason:
          type: string
        notes:
          type: string
        createdBy:
          type: string
        createdAt:
          type: string
          format: date-time

    # Commissions
    Commission:
      type: object
      properties:
        id:
          type: string
          format: uuid
        orderId:
          type: string
          format: uuid
        orderNumber:
          type: string
        orderValue:
          type: number
        commissionRate:
          type: number
        commissionAmount:
          type: number
        status:
          type: string
          enum: [PENDING, ACCRUED, SCHEDULED, PAID]
        payoutId:
          type: string
          format: uuid
        notes:
          type: string
        accruedAt:
          type: string
          format: date-time
        paidAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    CommissionsResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Commission'
        summary:
          type: object
          properties:
            totalCount:
              type: integer
            accruedTotal:
              type: number
            paidTotal:
              type: number
            pendingTotal:
              type: number
            allTimeTotal:
              type: number
        pagination:
          $ref: '#/components/schemas/Pagination'

    CreatePayoutRequest:
      type: object
      required:
        - tenantId
        - amount
      properties:
        tenantId:
          type: string
          format: uuid
        amount:
          type: number
          minimum: 0.01
        payoutMethod:
          type: string
          enum: [ACH, WIRE, CHECK, CREDIT]
          default: ACH
        scheduledDate:
          type: string
          format: date-time
        commissionIds:
          type: array
          items:
            type: string
            format: uuid
        notes:
          type: string

    Payout:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        amount:
          type: number
        payoutMethod:
          type: string
        scheduledDate:
          type: string
          format: date-time
        status:
          type: string
          enum: [SCHEDULED, PROCESSING, COMPLETED, FAILED]
        notes:
          type: string
        createdBy:
          type: string
        createdAt:
          type: string
          format: date-time

    # Webhooks
    WebhookEndpoint:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        url:
          type: string
          format: uri
        subscribedEvents:
          type: array
          items:
            type: string
        isActive:
          type: boolean
        lastDeliveredAt:
          type: string
          format: date-time
        successRate:
          type: number
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    WebhooksResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/WebhookEndpoint'
        availableEvents:
          type: array
          items:
            type: string
        count:
          type: integer

    CreateWebhookRequest:
      type: object
      required:
        - url
        - subscribedEvents
      properties:
        name:
          type: string
        url:
          type: string
          format: uri
        subscribedEvents:
          type: array
          minItems: 1
          items:
            type: string
            enum:
              - order.created
              - order.updated
              - order.confirmed
              - order.processing
              - order.shipped
              - order.delivered
              - order.cancelled
              - order.refunded
              - inventory.adjusted
              - inventory.low_stock
              - inventory.out_of_stock
              - inventory.restocked
              - commission.accrued
              - commission.adjusted
              - commission.payout.scheduled
              - commission.payout.completed
              - commission.payout.failed
              - shipment.created
              - shipment.picked_up
              - shipment.in_transit
              - shipment.delivered
              - shipment.exception
              - return.requested
              - return.approved
              - return.received
              - return.completed

    WebhookEndpointCreated:
      allOf:
        - $ref: '#/components/schemas/WebhookEndpoint'
        - type: object
          properties:
            signingSecret:
              type: string
              description: Store this securely. Used to verify webhook signatures.

    # API Keys
    ApiKey:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        prefix:
          type: string
        scopes:
          type: array
          items:
            type: string
        isActive:
          type: boolean
        expiresAt:
          type: string
          format: date-time
        lastUsedAt:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        createdBy:
          type: string

    ApiKeysResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ApiKey'
        count:
          type: integer
        availableScopes:
          type: array
          items:
            type: string

    CreateApiKeyRequest:
      type: object
      required:
        - name
        - scopes
      properties:
        name:
          type: string
        scopes:
          type: array
          minItems: 1
          items:
            type: string
            enum:
              - read:*
              - write:*
              - read:orders
              - write:orders
              - read:products
              - write:products
              - read:inventory
              - write:inventory
              - read:commissions
              - write:commissions
              - read:customers
              - write:customers
              - read:webhooks
              - write:webhooks
              - read:analytics
        expiresAt:
          type: string
          format: date-time

    ApiKeyCreated:
      allOf:
        - $ref: '#/components/schemas/ApiKey'
        - type: object
          required:
            - key
            - warning
          properties:
            key:
              type: string
              description: Full API key. Only shown once on creation.
            warning:
              type: string
              example: "Store this key securely. It will not be shown again."
