{
  "openapi": "3.0.3",
  "info": {
    "title": "SwitchMall Public Statistics API",
    "version": "1.2.0",
    "description": "Read-only public SwitchMall product reactions and merchant content view counts.",
    "contact": {
      "name": "SwitchMall Developer Resources",
      "url": "https://switchmall.ai/developers"
    }
  },
  "externalDocs": {
    "description": "SwitchMall Public API documentation",
    "url": "https://switchmall.ai/developers/api"
  },
  "servers": [
    {
      "url": "https://switchmall.ai"
    }
  ],
  "security": [

  ],
  "tags": [
    {
      "name": "SwitchMall Products",
      "description": "Read-only public information associated with SwitchMall product IDs."
    },
    {
      "name": "SwitchMall Merchants",
      "description": "Read-only product and offer view statistics associated with SwitchMall merchant IDs."
    }
  ],
  "paths": {
    "/api/public/v1/products/{productId}/stats": {
      "get": {
        "operationId": "getSwitchMallProductStats",
        "summary": "Get SwitchMall product statistics",
        "description": "Returns current view, like and dislike counts for a SwitchMall product ID. No authentication is required.",
        "security": [

        ],
        "tags": [
          "SwitchMall Products"
        ],
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "description": "Positive SwitchMall product ID.",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 9007199254740991
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "Current SwitchMall product statistics.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductStats"
                },
                "example": {
                  "productId": 1,
                  "viewsCount": 0,
                  "likesCount": 0,
                  "dislikesCount": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/public/v1/merchants/{merchantId}/stats": {
      "get": {
        "operationId": "getSwitchMallMerchantStats",
        "summary": "Get SwitchMall merchant view statistics",
        "description": "Returns rolling 24-hour merchant totals, comparison with the latest previous 14:00 MSK snapshot, and per-product and per-offer view tables. No authentication is required.",
        "security": [

        ],
        "tags": [
          "SwitchMall Merchants"
        ],
        "parameters": [
          {
            "name": "merchantId",
            "in": "path",
            "required": true,
            "description": "Positive integer merchant ID.",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current merchant view statistics.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MerchantStats"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadMerchantRequest"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ProductStats": {
        "type": "object",
        "required": [
          "productId",
          "viewsCount",
          "likesCount",
          "dislikesCount"
        ],
        "properties": {
          "productId": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "SwitchMall product ID supplied in the request path."
          },
          "viewsCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Recorded product view events."
          },
          "likesCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Current positive reactions."
          },
          "dislikesCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Current negative reactions."
          }
        },
        "additionalProperties": false
      },
      "MerchantContentView": {
        "type": "object",
        "required": [
          "id",
          "name",
          "viewsCount",
          "userViewsCount",
          "agentViewsCount"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "minimum": 1
          },
          "name": {
            "type": "string"
          },
          "viewsCount": {
            "type": "integer",
            "minimum": 0
          },
          "userViewsCount": {
            "type": "integer",
            "minimum": 0
          },
          "agentViewsCount": {
            "type": "integer",
            "minimum": 0
          }
        },
        "additionalProperties": false
      },
      "ActivityComparison": {
        "type": "object",
        "required": [
          "count",
          "previousCount",
          "changePercent"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 0
          },
          "previousCount": {
            "type": "integer",
            "minimum": 0
          },
          "changePercent": {
            "type": "number",
            "nullable": true,
            "description": "Percentage change, or null when the baseline is zero and the current count is positive."
          }
        },
        "additionalProperties": false
      },
      "MerchantViewComparisons": {
        "type": "object",
        "required": [
          "productViews",
          "productUserViews",
          "productAgentViews",
          "offerViews",
          "totalViews"
        ],
        "properties": {
          "productViews": {
            "$ref": "#/components/schemas/ActivityComparison"
          },
          "productUserViews": {
            "$ref": "#/components/schemas/ActivityComparison"
          },
          "productAgentViews": {
            "$ref": "#/components/schemas/ActivityComparison"
          },
          "offerViews": {
            "$ref": "#/components/schemas/ActivityComparison"
          },
          "totalViews": {
            "$ref": "#/components/schemas/ActivityComparison"
          }
        },
        "additionalProperties": false
      },
      "MerchantStats": {
        "type": "object",
        "required": [
          "merchantId",
          "merchantName",
          "productViewsCount",
          "productUserViewsCount",
          "productAgentViewsCount",
          "offerViewsCount",
          "totalViewsCount",
          "comparisons",
          "products",
          "offers",
          "period",
          "scheduledAt"
        ],
        "properties": {
          "merchantId": {
            "type": "integer",
            "format": "int64",
            "minimum": 1
          },
          "merchantName": {
            "type": "string"
          },
          "productViewsCount": {
            "type": "integer",
            "minimum": 0
          },
          "productUserViewsCount": {
            "type": "integer",
            "minimum": 0
          },
          "productAgentViewsCount": {
            "type": "integer",
            "minimum": 0
          },
          "offerViewsCount": {
            "type": "integer",
            "minimum": 0
          },
          "totalViewsCount": {
            "type": "integer",
            "minimum": 0
          },
          "comparisons": {
            "$ref": "#/components/schemas/MerchantViewComparisons"
          },
          "period": {
            "type": "string",
            "enum": [
              "24h"
            ]
          },
          "comparisonDate": {
            "type": "string",
            "format": "date",
            "description": "Date of the latest previous 14:00 MSK snapshot; omitted until a baseline exists."
          },
          "scheduledAt": {
            "type": "string",
            "enum": [
              "14:00 MSK"
            ]
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MerchantContentView"
            }
          },
          "offers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MerchantContentView"
            }
          }
        },
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "code",
          "message",
          "resolution"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Backward-compatible human-readable error message."
          },
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code.",
            "enum": [
              "INVALID_PRODUCT_ID",
              "INVALID_MERCHANT_ID",
              "METHOD_NOT_ALLOWED",
              "RATE_LIMIT_EXCEEDED",
              "INTERNAL_ERROR",
              "API_ROUTE_NOT_FOUND"
            ]
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation of the failure."
          },
          "resolution": {
            "type": "string",
            "description": "Concrete guidance for correcting or retrying the request."
          }
        },
        "additionalProperties": false
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid SwitchMall product ID.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "BadMerchantRequest": {
        "description": "Invalid merchant ID.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Merchant ID must be a positive integer",
              "code": "INVALID_MERCHANT_ID",
              "message": "Merchant ID must be a positive integer",
              "resolution": "Provide a positive integer SwitchMall merchant ID in the URL path."
            }
          }
        }
      },
      "MethodNotAllowed": {
        "description": "Unsupported HTTP method.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Method not allowed",
              "code": "METHOD_NOT_ALLOWED",
              "message": "Method not allowed",
              "resolution": "Call this endpoint with GET or OPTIONS."
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Public rate limit exceeded.",
        "headers": {
          "Retry-After": {
            "description": "Seconds until another request may be attempted.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Rate limit exceeded",
              "code": "RATE_LIMIT_EXCEEDED",
              "message": "Rate limit exceeded",
              "resolution": "Wait for the Retry-After interval before retrying."
            }
          }
        }
      },
      "ServerError": {
        "description": "Unexpected server error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Internal server error",
              "code": "INTERNAL_ERROR",
              "message": "Internal server error",
              "resolution": "Retry later or use the SwitchMall contact page if the problem continues."
            }
          }
        }
      }
    }
  }
}
