---
openapi: 3.0.1
info:
  title: Webhook API v3
  description: APIs for TradingView webhook integration
  version: v3
paths:
  /frontoffice/api/v3/webhook/alerts/{userId}:
    post:
      tags:
        - WebhookController
      summary: Receive TradingView alert
      description: |
        Receives and processes TradingView alert webhook.
        API key must be provided in request body and must be bound to the userId in URL path.
        Account ID must be specified in request body.
      parameters:
        - name: userId
          in: path
          required: true
          description: B2TRADER user ID (ULID format)
          schema:
            type: string
            pattern: ^[0-9A-HJKMNP-TV-Z]{26}$
            example: 01JZ3CVZKN20410JPYYH1YZJSK
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookAlertRequest'
      responses:
        '200':
          description: Alert processed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookAlertResponse'
        '400':
          description: Bad Request - validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'
        '401':
          description: Unauthorized - invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'
        '403':
          description: Forbidden - account mismatch
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'
        '429':
          description: Too Many Requests - rate limit exceeded
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum requests allowed in current window
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Remaining requests in current window
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets
            X-RateLimit-Window:
              schema:
                type: integer
              description: Window size in seconds
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'

  /frontoffice/api/v3/webhook/api-keys:
    post:
      tags:
        - WebhookApiKeyController
      summary: Create webhook API key
      description: |
        Creates a new webhook API key for the authenticated user.
        Required permission: trading-ui
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateApiKeyRequest'
      responses:
        '201':
          description: API key created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateApiKeyResponse'
        '400':
          description: Bad Request - validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'
    get:
      tags:
        - WebhookApiKeyController
      summary: List webhook API keys
      description: |
        Returns list of API keys for the authenticated user.
        Required permission: trading-ui
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListApiKeysResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'

  /frontoffice/api/v3/webhook/api-keys/{id}:
    delete:
      tags:
        - WebhookApiKeyController
      summary: Revoke webhook API key
      description: |
        Revokes an existing webhook API key by ID.
        Required permission: trading-ui
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: API key ID (ULID format)
          schema:
            type: string
            pattern: ^[0-9A-HJKMNP-TV-Z]{26}$
            example: 01JZ3CVZKN20410JPYYH1YZJSK
      responses:
        '200':
          description: API key revoked successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RevokeApiKeyResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'
        '404':
          description: API key not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookErrorResponse'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    # Enums
    WebhookApiKeyStatus:
      type: string
      enum:
        - Active
        - Revoked
        - Expired

    OrderSide:
      type: string
      enum:
        - buy
        - sell
        - long
        - short

    OrderType:
      type: string
      enum:
        - market
        - limit
        - stop
        - stop_limit
      default: market

    TimeInForce:
      type: string
      enum:
        - gtc
        - ioc
        - fok
        - day
        - retry
      default: gtc

    WebhookAction:
      type: string
      enum:
        - buy
        - sell
        - long
        - short

    MarketType:
      type: string
      enum:
        - spot
        - cfd
        - perp

    # Request/Response models
    WebhookAlertRequest:
      type: object
      required:
        - apiKey
        - accountId
        - symbol
        - side
        - quantity
      properties:
        apiKey:
          type: string
          description: Webhook API key for authentication
          example: wh_key_abc123def456ghi789jkl012mno345pqr678stu901
        accountId:
          type: string
          description: B2TRADER trading account ID (ULID format)
          example: 01JZ3CVZKN20410JPYYH1YZJSK
        action:
          $ref: '#/components/schemas/WebhookAction'
        symbol:
          type: string
          description: Trading pair symbol
          example: BTC_USDT
        marketType:
          $ref: '#/components/schemas/MarketType'
        side:
          $ref: '#/components/schemas/OrderSide'
        quantity:
          type: string
          description: Order quantity in base asset
          pattern: '^[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?$'
          example: "0.01"
        orderType:
          $ref: '#/components/schemas/OrderType'
        price:
          type: string
          description: Limit price (required for limit/stop_limit orders)
          pattern: '^[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?$'
          example: "45000"
        stopPrice:
          type: string
          description: Stop trigger price (required for stop/stop_limit orders)
          pattern: '^[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?$'
          example: "44000"
        leverage:
          type: string
          description: Position leverage (CFD/Perpetual markets only)
          pattern: '^[0-9]+(\.[0-9]+)?$'
          example: "10"
        takeProfit:
          type: string
          description: Take profit price
          pattern: '^[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?$'
          example: "46000"
        stopLoss:
          type: string
          description: Stop loss price
          pattern: '^[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?$'
          example: "44000"
        timeInForce:
          $ref: '#/components/schemas/TimeInForce'
        comment:
          type: string
          description: Order comment (max 256 chars)
          maxLength: 256
          example: TV Strategy Signal
        deduplicationId:
          type: string
          description: Client-provided ID for idempotency
          example: tv_alert_123456

    WebhookAlertResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        orderId:
          type: string
          description: Created order ID
          example: 01JZ3CVZKN20410JPYYH1YZJSK
        orderStatus:
          type: string
          description: Order status after execution
          example: Working
        message:
          type: string
          description: Human-readable result message
          example: Order placed successfully
        timestamp:
          type: string
          format: date-time
          example: "2026-02-02T12:34:56.789Z"

    WebhookErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              example: WH2001
            message:
              type: string
              example: Invalid symbol format
            details:
              type: string
              example: Symbol 'INVALID' not found or not available for trading
        retryAfter:
          type: integer
          description: Seconds to wait before retry (for rate limit errors)
        timestamp:
          type: string
          format: date-time

    CreateApiKeyRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: Key name (max 100 chars)
          maxLength: 100
          example: My TradingView Key

    CreateApiKeyResponse:
      type: object
      properties:
        id:
          type: string
          description: API key ID (ULID format)
          example: 01JZ3CVZKN20410JPYYH1YZJSK
        apiKey:
          type: string
          description: Secret key (shown only once at creation)
          example: wh_key_abc123def456ghi789jkl012mno345pqr678stu901
        name:
          type: string
          example: My TradingView Key
        userId:
          type: string
          description: User ID the key is bound to
          example: 01JZ3CVZKN20410JPYYH1YZJSK
        status:
          $ref: '#/components/schemas/WebhookApiKeyStatus'
        createdAt:
          type: string
          format: date-time
        expiresAt:
          type: string
          format: date-time
          description: Key expiration date (automatically set to 1 year from creation)

    ListApiKeysResponse:
      type: object
      properties:
        webhookUrl:
          type: string
          format: uri
          description: Full webhook URL for receiving TradingView alerts
          example: https://trading.example.com/frontoffice/api/v3/webhook/alerts/01JZ3CVZKN20410JPYYH1YZJSK
        apiKeys:
          type: array
          items:
            $ref: '#/components/schemas/ApiKeyInfo'

    ApiKeyInfo:
      type: object
      properties:
        id:
          type: string
          description: API key ID (ULID format)
          example: 01JZ3CVZKN20410JPYYH1YZJSK
        name:
          type: string
        status:
          $ref: '#/components/schemas/WebhookApiKeyStatus'
        createdAt:
          type: string
          format: date-time
        expiresAt:
          type: string
          format: date-time
          description: Key expiration date (automatically set to 1 year from creation)

    RevokeApiKeyResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
          example: API key revoked successfully
