{
  "swagger": "2.0",
  "info": {
    "title": "EB Case Study Pricing API",
    "description": "API for managing hardware store products and prices",
    "contact": {
      "name": "EnterBridge LLC",
      "url": "https://enterbridge.com"
    },
    "version": "v1"
  },
  "paths": {
    "/api/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Check API health",
        "description": "Returns the health status of the API including database connectivity and whether seed data is loaded.",
        "operationId": "GetHealth",
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "429": {
            "description": "Too Many Requests",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          }
        }
      }
    },
    "/api/prices": {
      "get": {
        "tags": [
          "Prices"
        ],
        "summary": "Get a paginated list of prices",
        "description": "Retrieves a paginated list of prices with optional filtering by date range, product ID, and other criteria.",
        "operationId": "GetPrices",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "PageNumber",
            "description": "Page number (1-based)",
            "type": "integer",
            "format": "int32",
            "maximum": 2147483647,
            "minimum": 1
          },
          {
            "in": "query",
            "name": "PageSize",
            "description": "Number of items per page",
            "type": "integer",
            "format": "int32",
            "maximum": 1000,
            "minimum": 1
          },
          {
            "in": "query",
            "name": "productId",
            "description": "Filter by product ID",
            "type": "integer",
            "format": "int32"
          },
          {
            "in": "query",
            "name": "startDate",
            "description": "Filter by start date, inclusive (format YYYY-MM-DD)",
            "type": "string",
            "format": "date-time"
          },
          {
            "in": "query",
            "name": "endDate",
            "description": "Filter by end date, inclusive (format YYYY-MM-DD)",
            "type": "string",
            "format": "date-time"
          },
          {
            "in": "query",
            "name": "minAmount",
            "description": "Filter by minimum amount",
            "type": "number",
            "format": "double"
          },
          {
            "in": "query",
            "name": "maxAmount",
            "description": "Filter by maximum amount",
            "type": "number",
            "format": "double"
          },
          {
            "in": "query",
            "name": "unitOfMeasure",
            "description": "Filter by unit of measure"
          },
          {
            "in": "query",
            "name": "sortBy",
            "description": "Sort by field (DateTime, Amount)",
            "type": "string",
            "default": "DateTime"
          },
          {
            "in": "query",
            "name": "sortDirection",
            "description": "Sort direction (asc, desc)",
            "type": "string",
            "default": "desc"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "$ref": "#/definitions/PriceDtoPaginatedResponse"
            }
          },
          "429": {
            "description": "Too Many Requests",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          }
        }
      }
    },
    "/api/prices/{id}": {
      "get": {
        "tags": [
          "Prices"
        ],
        "summary": "Get a price by ID",
        "description": "Retrieves a specific price by its ID",
        "operationId": "GetPrice",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "type": "integer",
            "format": "int32"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "$ref": "#/definitions/PriceDto"
            }
          },
          "404": {
            "description": "Not Found",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          },
          "429": {
            "description": "Too Many Requests",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          }
        }
      }
    },
    "/api/products": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get a paginated list of products",
        "description": "Retrieves a paginated list of products with filtering and sorting capabilities.",
        "operationId": "GetProducts",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "PageNumber",
            "description": "Page number (1-based)",
            "type": "integer",
            "format": "int32",
            "maximum": 2147483647,
            "minimum": 1
          },
          {
            "in": "query",
            "name": "PageSize",
            "description": "Number of items per page",
            "type": "integer",
            "format": "int32",
            "maximum": 1000,
            "minimum": 1
          },
          {
            "in": "query",
            "name": "name",
            "description": "Filter by product name (case-insensitive contains)",
            "type": "string"
          },
          {
            "in": "query",
            "name": "description",
            "description": "Filter by product description (case-insensitive contains)",
            "type": "string"
          },
          {
            "in": "query",
            "name": "sku",
            "description": "Filter by product SKU (case-insensitive contains)",
            "type": "string"
          },
          {
            "in": "query",
            "name": "category",
            "description": "Filter by product category"
          },
          {
            "in": "query",
            "name": "sortBy",
            "description": "Sort by field (Name, Description, Sku, Category)",
            "type": "string"
          },
          {
            "in": "query",
            "name": "sortDirection",
            "description": "Sort direction (asc, desc)",
            "type": "string",
            "default": "asc"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "$ref": "#/definitions/ProductDtoPaginatedResponse"
            }
          },
          "429": {
            "description": "Too Many Requests",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          }
        }
      }
    },
    "/api/products/{id}": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get a product by ID",
        "description": "Retrieves a specific product by its ID",
        "operationId": "GetProduct",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "type": "integer",
            "format": "int32"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "$ref": "#/definitions/ProductDto"
            }
          },
          "404": {
            "description": "Not Found",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          },
          "429": {
            "description": "Too Many Requests",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          }
        }
      }
    },
    "/api/products/categories": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get all product categories",
        "description": "Retrieves all available product categories",
        "operationId": "GetProductCategories",
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Category"
              }
            }
          }
        }
      }
    },
    "/api/stats": {
      "get": {
        "tags": [
          "Stats"
        ],
        "summary": "Get dataset summary statistics",
        "description": "Returns an overview of the dataset: total products, products by category, total prices, price data date range, and available units of measure. Useful for orienting yourself before querying specific endpoints.",
        "operationId": "GetStats",
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "429": {
            "description": "Too Many Requests",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          }
        }
      }
    },
    "/api/unit-of-measures": {
      "get": {
        "tags": [
          "UnitOfMeasures"
        ],
        "summary": "Get all unit of measures",
        "description": "Retrieves all available units of measure",
        "operationId": "GetUnitOfMeasures",
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/UnitOfMeasure"
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "schema": {
              "$ref": "#/definitions/ProblemDetails"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "Category": {
      "description": "Product categories for hardware store inventory",
      "enum": [
        "Lumber",
        "Plumbing",
        "Electrical",
        "Tools",
        "Paint",
        "Hardware",
        "Garden",
        "Concrete",
        "Insulation",
        "Other"
      ],
      "type": "string"
    },
    "PriceDto": {
      "description": "Data Transfer Object for Price with nested Product (without Prices)",
      "type": "object",
      "properties": {
        "id": {
          "format": "int32",
          "description": "Unique identifier for the price record",
          "type": "integer",
          "example": 1
        },
        "amount": {
          "format": "double",
          "description": "The price amount",
          "type": "number",
          "example": 5.99
        },
        "dateTime": {
          "format": "date-time",
          "description": "The date and time when the price was recorded",
          "type": "string",
          "example": "2023-06-15T00:00:00"
        },
        "quantity": {
          "format": "double",
          "description": "The quantity of the product",
          "type": "number",
          "example": 1
        },
        "unitOfMeasure": {
          "$ref": "#/definitions/UnitOfMeasure"
        },
        "productId": {
          "format": "int32",
          "description": "The ID of the product this price belongs to",
          "type": "integer"
        },
        "product": {
          "$ref": "#/definitions/ProductDto"
        }
      },
      "additionalProperties": false
    },
    "PriceDtoPaginatedResponse": {
      "description": "Generic paginated response for API endpoints",
      "type": "object",
      "properties": {
        "pageNumber": {
          "format": "int32",
          "description": "The current page number (1-based)",
          "type": "integer"
        },
        "pageSize": {
          "format": "int32",
          "description": "The number of items per page",
          "type": "integer"
        },
        "totalCount": {
          "format": "int32",
          "description": "The total number of items available",
          "type": "integer"
        },
        "totalPages": {
          "format": "int32",
          "description": "The total number of pages",
          "type": "integer"
        },
        "hasPreviousPage": {
          "description": "Whether there is a previous page",
          "type": "boolean",
          "readOnly": true
        },
        "hasNextPage": {
          "description": "Whether there is a next page",
          "type": "boolean",
          "readOnly": true
        },
        "items": {
          "description": "The items for the current page",
          "type": "array",
          "items": {
            "$ref": "#/definitions/PriceDto"
          }
        }
      },
      "additionalProperties": false
    },
    "ProblemDetails": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "status": {
          "format": "int32",
          "type": "integer"
        },
        "detail": {
          "type": "string"
        },
        "instance": {
          "type": "string"
        }
      },
      "additionalProperties": { }
    },
    "ProductDto": {
      "description": "Data Transfer Object for Product without nested Prices",
      "type": "object",
      "properties": {
        "id": {
          "format": "int32",
          "description": "Unique identifier for the product",
          "type": "integer",
          "example": 1
        },
        "name": {
          "description": "The name of the product",
          "type": "string",
          "example": "2x4 Lumber 8ft"
        },
        "description": {
          "description": "Detailed description of the product",
          "type": "string",
          "example": "Kiln-dried spruce-pine-fir, suitable for framing and general construction"
        },
        "sku": {
          "description": "Product SKU or model number",
          "type": "string",
          "example": "LBR-2X4-8"
        },
        "category": {
          "$ref": "#/definitions/Category"
        }
      },
      "additionalProperties": false
    },
    "ProductDtoPaginatedResponse": {
      "description": "Generic paginated response for API endpoints",
      "type": "object",
      "properties": {
        "pageNumber": {
          "format": "int32",
          "description": "The current page number (1-based)",
          "type": "integer"
        },
        "pageSize": {
          "format": "int32",
          "description": "The number of items per page",
          "type": "integer"
        },
        "totalCount": {
          "format": "int32",
          "description": "The total number of items available",
          "type": "integer"
        },
        "totalPages": {
          "format": "int32",
          "description": "The total number of pages",
          "type": "integer"
        },
        "hasPreviousPage": {
          "description": "Whether there is a previous page",
          "type": "boolean",
          "readOnly": true
        },
        "hasNextPage": {
          "description": "Whether there is a next page",
          "type": "boolean",
          "readOnly": true
        },
        "items": {
          "description": "The items for the current page",
          "type": "array",
          "items": {
            "$ref": "#/definitions/ProductDto"
          }
        }
      },
      "additionalProperties": false
    },
    "UnitOfMeasure": {
      "description": "Units of measure for product quantities",
      "enum": [
        "Each",
        "LinearFeet",
        "SquareFeet",
        "CubicFeet",
        "BoardFeet",
        "Pound",
        "Ounce",
        "Gallon",
        "Quart",
        "Pint",
        "FluidOunce",
        "SquareYard",
        "CubicYard",
        "Roll",
        "Box",
        "Bundle",
        "Case",
        "Pallet",
        "Ton",
        "Kilogram",
        "Gram",
        "Liter",
        "Milliliter",
        "Meter",
        "Centimeter",
        "Millimeter",
        "SquareMeter",
        "CubicMeter"
      ],
      "type": "string"
    }
  },
  "tags": [
    {
      "name": "Health",
      "description": "Health check endpoint for monitoring API status"
    },
    {
      "name": "Stats",
      "description": "Dataset summary statistics for quick orientation"
    }
  ]
}