openapi: 3.0.3
info:
  title: FDDB Exporter API
  description: |
    REST API for exporting, querying, and analyzing FDDB (Fddb.info) nutrition data.
    
    This API provides endpoints for:
    - Exporting FDDB nutrition data to a database
    - Querying stored nutrition data
    - Calculating statistics and rolling averages
    - Performing correlation analysis
    - Migrating data between storage backends
    
    ## Storage Backends
    The API supports multiple storage backends:
    - **MongoDB**: Primary storage for nutrition data
    - **InfluxDB**: Time-series database for analytics
    
    ## Authentication
    Currently, no authentication is required for API access.

  version: 2.0.0
  contact:
    name: FDDB Exporter
    url: https://github.com/itobey/fddb-exporter
  license:
    name: MIT License
    url: https://opensource.org/licenses/MIT

servers:
  - url: http://localhost:8080
    description: Local development server
  - url: https://api.example.com
    description: Production server

tags:
  - name: FDDB Data Export
    description: Export FDDB data for specified date ranges
  - name: FDDB Data Query
    description: Query FDDB nutrition data entries
  - name: FDDB Data Download
    description: Download FDDB data in various formats (CSV, JSON)
  - name: FDDB Data Statistics
    description: Statistics and analytics for FDDB data
  - name: FDDB Data Migration
    description: Data migration operations between storage backends
  - name: Correlation Analysis
    description: Correlation analysis between data series

paths:
  /api/v2/fddbdata:
    post:
      tags:
        - FDDB Data Export
      summary: Export data for a date range
      description: Export FDDB data for all days in the specified timeframe
      operationId: exportForTimerange
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DateRangeDTO'
            examples:
              dateRange:
                summary: Export data for January 2024
                value:
                  fromDate: "2024-01-01"
                  toDate: "2024-01-31"
      responses:
        '200':
          description: Export completed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExportResultDTO'
              examples:
                success:
                  summary: Successful export
                  value:
                    successfulDays:
                      - "2024-01-01"
                      - "2024-01-02"
                      - "2024-01-03"
                    unsuccessfulDays: [ ]
        '400':
          description: Invalid date range
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

    get:
      tags:
        - FDDB Data Query
      summary: Get all FDDB data entries
      description: Retrieves all FDDB nutrition data entries from the database. Requires MongoDB to be available.
      operationId: findAllEntries
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FddbDataDTO'
        '400':
          description: MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/fddbdata/export:
    get:
      tags:
        - FDDB Data Export
      summary: Export data for recent days
      description: |
        Export FDDB data for a specified number of days back from today.
        If includeToday is true, the current day will be exported as well.
      operationId: exportForDaysBack
      parameters:
        - name: days
          in: query
          description: Number of days to export
          required: true
          schema:
            type: integer
            minimum: 1
            example: 7
        - name: includeToday
          in: query
          description: Whether to include today in the export
          required: false
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Export completed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExportResultDTO'

  /api/v2/fddbdata/{date}:
    get:
      tags:
        - FDDB Data Query
      summary: Get FDDB data for a specific date
      description: Retrieves FDDB data entries for the specified date. Requires MongoDB to be available.
      operationId: findByDate
      parameters:
        - name: date
          in: path
          description: Date in YYYY-MM-DD format
          required: true
          schema:
            type: string
            pattern: '^\d{4}-\d{2}-\d{2}$'
            example: "2024-12-22"
      responses:
        '200':
          description: Data found for the specified date
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FddbDataDTO'
        '400':
          description: Invalid date format, or MongoDB is disabled
          content:
            application/json:
              schema:
                type: string
                example: "Date must be in the format YYYY-MM-DD"
        '404':
          description: No data found for the specified date

  /api/v2/fddbdata/range:
    get:
      tags:
        - FDDB Data Query
      summary: Get FDDB data for a date range
      description: |
        Retrieves all entries between two dates (both inclusive), oldest first. Product lists are omitted unless
        explicitly requested, since a long range with products is a very large response. The range is limited to
        366 days. Requires MongoDB to be available.
      operationId: findByDateRange
      parameters:
        - name: fromDate
          in: query
          description: Start date (inclusive), format YYYY-MM-DD
          required: true
          schema:
            type: string
            format: date
            example: "2024-12-01"
        - name: toDate
          in: query
          description: End date (inclusive), format YYYY-MM-DD
          required: true
          schema:
            type: string
            format: date
            example: "2024-12-31"
        - name: includeProducts
          in: query
          description: Whether to include the product list of each day
          required: false
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Entries for the specified range
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FddbDataDTO'
        '400':
          description: Invalid or too large date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/fddbdata/products:
    get:
      tags:
        - FDDB Data Query
      summary: Search products by name
      description: |
        Search for FDDB products by name across all dates, optionally filtered by specific days of the week, a date
        range and a maximum number of results. Requires MongoDB to be available.
      operationId: findByProduct
      parameters:
        - name: name
          in: query
          description: Product name to search for
          required: true
          schema:
            type: string
            example: "Banana"
        - name: days
          in: query
          description: Optional days of week to filter results (e.g., MONDAY, WEDNESDAY, FRIDAY). Can specify multiple days.
          required: false
          schema:
            type: array
            items:
              type: string
              enum:
                - MONDAY
                - TUESDAY
                - WEDNESDAY
                - THURSDAY
                - FRIDAY
                - SATURDAY
                - SUNDAY
          style: form
          explode: false
          example: "MONDAY,FRIDAY"
        - name: fromDate
          in: query
          description: Optional start date (inclusive), format YYYY-MM-DD
          required: false
          schema:
            type: string
            format: date
            example: "2024-01-01"
        - name: toDate
          in: query
          description: Optional end date (inclusive), format YYYY-MM-DD
          required: false
          schema:
            type: string
            format: date
            example: "2024-12-31"
        - name: limit
          in: query
          description: Optional maximum number of results
          required: false
          schema:
            type: integer
            example: 100
      responses:
        '200':
          description: Search results
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProductWithDateDTO'
        '400':
          description: Invalid date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/fddbdata/products/distinct:
    get:
      tags:
        - FDDB Data Query
      summary: List distinct product names
      description: |
        Lists the distinct product names in the database, so a fuzzy term ("oats") can be resolved to the exact,
        brand-prefixed name FDDB stores ("Haferflocken kernig"). Requires MongoDB to be available.
      operationId: findDistinctProductNames
      parameters:
        - name: search
          in: query
          description: Optional case-insensitive substring the name has to contain
          required: false
          schema:
            type: string
            example: "hafer"
        - name: limit
          in: query
          description: Maximum number of names to return
          required: false
          schema:
            type: integer
            default: 100
            minimum: 1
            maximum: 1000
            example: 100
      responses:
        '200':
          description: Distinct product names
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
        '400':
          description: MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/fddbdata/products/summary:
    get:
      tags:
        - FDDB Data Query
      summary: Summarize a product
      description: |
        Aggregates every occurrence of the products matching a search term: how often they were logged, first and
        last date, the totals they contributed and the weekday distribution. Requires MongoDB to be available.
      operationId: getProductSummary
      parameters:
        - name: name
          in: query
          description: Product name to search for
          required: true
          schema:
            type: string
            example: "Haferflocken"
        - name: fromDate
          in: query
          description: Optional start date (inclusive), format YYYY-MM-DD
          required: false
          schema:
            type: string
            format: date
            example: "2024-01-01"
        - name: toDate
          in: query
          description: Optional end date (inclusive), format YYYY-MM-DD
          required: false
          schema:
            type: string
            format: date
            example: "2024-12-31"
      responses:
        '200':
          description: Product summary
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductSummaryDTO'
        '400':
          description: Invalid date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/fddbdata/products/top:
    get:
      tags:
        - FDDB Data Query
      summary: List top products
      description: |
        Ranks products by how often they were logged (FREQUENCY) or by the nutrient totals they contributed -
        "what do I actually eat the most, and where do my calories come from?" Requires MongoDB to be available.
      operationId: getTopProducts
      parameters:
        - name: by
          in: query
          description: Ranking criterion
          required: false
          schema:
            type: string
            enum:
              - FREQUENCY
              - CALORIES
              - FAT
              - CARBS
              - PROTEIN
            default: FREQUENCY
            example: FREQUENCY
        - name: fromDate
          in: query
          description: Optional start date (inclusive), format YYYY-MM-DD
          required: false
          schema:
            type: string
            format: date
            example: "2024-01-01"
        - name: toDate
          in: query
          description: Optional end date (inclusive), format YYYY-MM-DD
          required: false
          schema:
            type: string
            format: date
            example: "2024-12-31"
        - name: limit
          in: query
          description: Maximum number of products to return
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 500
            example: 20
      responses:
        '200':
          description: Ranked products
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TopProductDTO'
        '400':
          description: Invalid date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/fddbdata/download:
    get:
      tags:
        - FDDB Data Download
      summary: Download FDDB data
      description: |
        Download FDDB data as CSV or JSON. Optionally filter by date range and choose whether to include product details or just daily totals.
        
        When includeProducts is false (default), only daily totals are returned with columns: Date, Calories, Fat, Carbs, Sugar, Protein, Fibre.
        
        When includeProducts is true, the data is flattened with one row per product, including both product details and daily totals.
      operationId: downloadData
      parameters:
        - name: fromDate
          in: query
          description: Start date for filtering (inclusive), format YYYY-MM-DD. If not provided, downloads from the beginning.
          required: false
          schema:
            type: string
            format: date
            example: "2024-01-01"
        - name: toDate
          in: query
          description: End date for filtering (inclusive), format YYYY-MM-DD. If not provided, downloads until the most recent entry.
          required: false
          schema:
            type: string
            format: date
            example: "2024-12-31"
        - name: format
          in: query
          description: Download format (CSV or JSON)
          required: true
          schema:
            type: string
            enum:
              - CSV
              - JSON
            example: "CSV"
        - name: includeProducts
          in: query
          description: Whether to include product details (true) or just daily totals (false)
          required: false
          schema:
            type: boolean
            default: false
            example: false
        - name: decimalSeparator
          in: query
          description: Decimal separator for CSV format (. or ,). Only applies when format is CSV.
          required: false
          schema:
            type: string
            enum:
              - "comma"
              - "dot"
            default: "comma"
            example: "comma"
      responses:
        '200':
          description: Data downloaded successfully
          content:
            text/csv:
              schema:
                type: string
                format: binary
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FddbDataDTO'
                description: |
                  Returns an array of FddbDataDTO objects.
                  When includeProducts=false, the 'id' and 'products' fields will be null.
                  When includeProducts=true, all fields are populated.
        '400':
          description: Invalid parameters (e.g., fromDate is after toDate), or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/stats:
    get:
      tags:
        - FDDB Data Statistics
      summary: Get overall statistics
      description: Retrieves overall statistics for FDDB data. Requires MongoDB to be available.
      operationId: getStats
      responses:
        '200':
          description: Statistics retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StatsDTO'
        '400':
          description: MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/stats/averages:
    get:
      tags:
        - FDDB Data Statistics
      summary: Get rolling averages
      description: Calculate rolling averages for a specified date range. Requires MongoDB to be available.
      operationId: getRollingAverages
      parameters:
        - name: fromDate
          in: query
          description: Start date in YYYY-MM-DD format
          required: true
          schema:
            type: string
            pattern: '^\d{4}-\d{2}-\d{2}$'
            example: "2024-01-01"
        - name: toDate
          in: query
          description: End date in YYYY-MM-DD format
          required: true
          schema:
            type: string
            pattern: '^\d{4}-\d{2}-\d{2}$'
            example: "2024-01-31"
      responses:
        '200':
          description: Rolling averages calculated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RollingAveragesDTO'
        '400':
          description: Invalid date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                type: string
                example: "Invalid date range"

  /api/v2/stats/trend:
    get:
      tags:
        - FDDB Data Statistics
      summary: Get a trend time series
      description: |
        Builds a time series of one metric over a date range, bucketed by day, ISO week or month. Buckets without a
        single entry are omitted, so unlogged days never drag an average down. Requires MongoDB to be available.
      operationId: getTrend
      parameters:
        - name: metric
          in: query
          description: Metric to trend
          required: false
          schema:
            type: string
            enum:
              - CALORIES
              - FAT
              - CARBS
              - SUGAR
              - PROTEIN
              - FIBRE
            default: CALORIES
            example: CALORIES
        - name: fromDate
          in: query
          description: Start date (inclusive), format YYYY-MM-DD
          required: true
          schema:
            type: string
            format: date
            example: "2024-01-01"
        - name: toDate
          in: query
          description: End date (inclusive), format YYYY-MM-DD
          required: true
          schema:
            type: string
            format: date
            example: "2024-12-31"
        - name: granularity
          in: query
          description: Bucket size
          required: false
          schema:
            type: string
            enum:
              - DAY
              - WEEK
              - MONTH
            default: DAY
            example: WEEK
      responses:
        '200':
          description: Trend time series
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TrendPointDTO'
        '400':
          description: Invalid date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/stats/weekdays:
    get:
      tags:
        - FDDB Data Statistics
      summary: Get a weekday breakdown
      description: |
        Averages the daily totals grouped by day of the week - "do my weekends wreck the average?". Days of the week
        without a single entry are omitted. Requires MongoDB to be available.
      operationId: getWeekdayBreakdown
      parameters:
        - name: fromDate
          in: query
          description: Optional start date (inclusive), format YYYY-MM-DD
          required: false
          schema:
            type: string
            format: date
            example: "2024-01-01"
        - name: toDate
          in: query
          description: Optional end date (inclusive), format YYYY-MM-DD
          required: false
          schema:
            type: string
            format: date
            example: "2024-12-31"
      responses:
        '200':
          description: Averages per day of the week
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WeekdayStatsDTO'
        '400':
          description: Invalid date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/stats/macro-split:
    get:
      tags:
        - FDDB Data Statistics
      summary: Get the macro split
      description: |
        Share of energy from fat, carbs and protein over a date range. The split is kcal-weighted (fat 9 kcal/g,
        carbs and protein 4 kcal/g), not gram-weighted. Requires MongoDB to be available.
      operationId: getMacroSplit
      parameters:
        - name: fromDate
          in: query
          description: Start date (inclusive), format YYYY-MM-DD
          required: true
          schema:
            type: string
            format: date
            example: "2024-01-01"
        - name: toDate
          in: query
          description: End date (inclusive), format YYYY-MM-DD
          required: true
          schema:
            type: string
            format: date
            example: "2024-12-31"
      responses:
        '200':
          description: Macro split
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MacroSplitDTO'
        '400':
          description: Invalid date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/stats/missing-days:
    get:
      tags:
        - FDDB Data Statistics
      summary: List missing days
      description: |
        Lists every day in the range that has no entry at all or an entry without a single calorie - "when did I
        forget to log?" Requires MongoDB to be available.
      operationId: getMissingDays
      parameters:
        - name: fromDate
          in: query
          description: Start date (inclusive), format YYYY-MM-DD
          required: true
          schema:
            type: string
            format: date
            example: "2024-01-01"
        - name: toDate
          in: query
          description: End date (inclusive), format YYYY-MM-DD
          required: true
          schema:
            type: string
            format: date
            example: "2024-12-31"
      responses:
        '200':
          description: Missing days
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                  format: date
        '400':
          description: Invalid date range, or MongoDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/migration/toInfluxDb:
    post:
      tags:
        - FDDB Data Migration
      summary: Migrate data to InfluxDB
      description: Migrate all MongoDB entries to InfluxDB. Requires both MongoDB and InfluxDB to be available.
      operationId: migrateMongoDbEntriesToInfluxDb
      responses:
        '200':
          description: Migration completed successfully
          content:
            application/json:
              schema:
                type: string
                example: "Migrated 365 entries to InfluxDB"
        '400':
          description: MongoDB or InfluxDB is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /api/v2/correlation:
    post:
      tags:
        - Correlation Analysis
      summary: Create correlation analysis
      description: |
        Calculate correlation between two data series based on product consumption patterns.
        
        The analysis identifies correlations between:
        - Products matching inclusion keywords
        - Dates when specific events occurred
        
        Products matching exclusion keywords are filtered out from the analysis.
      operationId: createCorrelation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CorrelationInputDto'
            examples:
              correlation:
                summary: Analyze correlation between dairy products and specific dates
                value:
                  inclusionKeywords:
                    - "milk"
                    - "cheese"
                  exclusionKeywords:
                    - "lactose-free"
                  occurrenceDates:
                    - "2024-01-05"
                    - "2024-01-12"
                    - "2024-01-19"
                  startDate: "2024-01-01"
      responses:
        '200':
          description: Correlation calculated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CorrelationOutputDto'

components:
  schemas:
    DateRangeDTO:
      type: object
      description: Date range with from and to dates
      required:
        - fromDate
        - toDate
      properties:
        fromDate:
          type: string
          pattern: '^\d{4}-\d{2}-\d{2}$'
          description: Start date in YYYY-MM-DD format
          example: "2024-01-01"
        toDate:
          type: string
          pattern: '^\d{4}-\d{2}-\d{2}$'
          description: End date in YYYY-MM-DD format
          example: "2024-01-31"

    ExportResultDTO:
      type: object
      description: Result of an export operation
      properties:
        successfulDays:
          type: array
          description: Dates that were successfully exported
          items:
            type: string
          example: [ "2024-12-20", "2024-12-21" ]
        unsuccessfulDays:
          type: array
          description: Dates that failed to export
          items:
            type: string
          example: [ "2024-12-22" ]

    FddbDataDTO:
      type: object
      description: FDDB nutrition data for a specific day
      properties:
        id:
          type: string
          nullable: true
          description: Unique identifier (null when used for daily totals downloads)
          example: "507f1f77bcf86cd799439011"
        date:
          type: string
          format: date
          description: Date of the entry
          example: "2024-12-22"
        products:
          type: array
          nullable: true
          description: List of products consumed on this day (null when used for daily totals downloads)
          items:
            $ref: '#/components/schemas/ProductDTO'
        totalCalories:
          type: number
          format: double
          description: Total calories for the day
          example: 2000.5
        totalFat:
          type: number
          format: double
          description: Total fat in grams
          example: 65.3
        totalCarbs:
          type: number
          format: double
          description: Total carbs in grams
          example: 250.2
        totalSugar:
          type: number
          format: double
          description: Total sugar in grams
          example: 50.1
        totalProtein:
          type: number
          format: double
          description: Total protein in grams
          example: 80.4
        totalFibre:
          type: number
          format: double
          description: Total fibre in grams
          example: 25.6

    ProductDTO:
      type: object
      description: A consumed product with nutritional information
      properties:
        name:
          type: string
          description: Product name
          example: "Banana"
        amount:
          type: string
          description: Amount consumed
          example: "100 g"
        calories:
          type: number
          format: double
          description: Calories
          example: 89.0
        fat:
          type: number
          format: double
          description: Fat in grams
          example: 0.3
        carbs:
          type: number
          format: double
          description: Carbs in grams
          example: 23.0
        protein:
          type: number
          format: double
          description: Protein in grams
          example: 1.1
        link:
          type: string
          description: Link to product page on FDDB
          example: "https://fddb.info/db/de/lebensmittel/..."

    ProductWithDateDTO:
      type: object
      description: A product with its consumption date
      properties:
        date:
          type: string
          format: date
          description: Date when the product was consumed
          example: "2024-12-22"
        product:
          $ref: '#/components/schemas/ProductDTO'

    StatsDTO:
      type: object
      description: Statistics about FDDB data entries
      properties:
        amountEntries:
          type: integer
          format: int64
          description: Total number of entries in the database
          example: 365
        firstEntryDate:
          type: string
          format: date
          description: Date of the first entry
          example: "2024-01-01"
        lastEntryDate:
          type: string
          format: date
          description: Date of the most recent entry
          example: "2024-12-22"
        entryPercentage:
          type: number
          format: double
          description: Percentage of days with entries
          example: 95.5
        uniqueProducts:
          type: integer
          format: int64
          description: Number of unique products consumed
          example: 150
        totalProducts:
          type: integer
          format: int64
          description: Total number of products across all days
          example: 2450
        averageTotals:
          $ref: '#/components/schemas/Averages'
        highestCaloriesDay:
          $ref: '#/components/schemas/DayStats'
        highestFatDay:
          $ref: '#/components/schemas/DayStats'
        highestCarbsDay:
          $ref: '#/components/schemas/DayStats'
        highestProteinDay:
          $ref: '#/components/schemas/DayStats'
        highestFibreDay:
          $ref: '#/components/schemas/DayStats'
        highestSugarDay:
          $ref: '#/components/schemas/DayStats'
        mostRecentMissingDay:
          description: Most recent day with no entry (excluding today). Returns date or 'only available with MongoDB' when MongoDB is not configured
          oneOf:
            - type: string
              format: date
            - type: string
          example: "2024-12-20"
        missingDaysCount:
          type: integer
          format: int64
          nullable: true
          description: Number of days between the first entry and yesterday that have no entry. Null when MongoDB is not configured
          example: 18
        currentStreak:
          type: integer
          nullable: true
          description: Days logged in a row up to now. Today is only counted once it has an entry, so a day still in progress does not break the streak. Null when MongoDB is not configured
          example: 12
        longestStreak:
          type: integer
          nullable: true
          description: Longest run of consecutive logged days since the first entry. Null when MongoDB is not configured
          example: 94

    Averages:
      type: object
      description: Average nutritional values
      properties:
        avgTotalCalories:
          type: number
          format: double
          description: Average calories per day
          example: 2000.5
        avgTotalFat:
          type: number
          format: double
          description: Average fat per day in grams
          example: 65.3
        avgTotalCarbs:
          type: number
          format: double
          description: Average carbs per day in grams
          example: 250.2
        avgTotalSugar:
          type: number
          format: double
          description: Average sugar per day in grams
          example: 50.1
        avgTotalProtein:
          type: number
          format: double
          description: Average protein per day in grams
          example: 80.4
        avgTotalFibre:
          type: number
          format: double
          description: Average fibre per day in grams
          example: 25.6

    DayStats:
      type: object
      description: Statistics for a specific day
      properties:
        date:
          type: string
          format: date
          description: Date of the entry
          example: "2024-12-22"
        total:
          type: number
          format: double
          description: Total value for that day
          example: 2500.5

    RollingAveragesDTO:
      type: object
      description: Rolling averages for a date range
      properties:
        fromDate:
          type: string
          description: Start date of the range
          example: "2024-01-01"
        toDate:
          type: string
          description: End date of the range
          example: "2024-12-31"
        averages:
          $ref: '#/components/schemas/Averages'

    TopProductDTO:
      type: object
      description: A product with its aggregated contribution across all logged occurrences
      properties:
        name:
          type: string
          description: Product name as logged in FDDB
          example: "Haferflocken kernig"
        timesEaten:
          type: integer
          format: int64
          description: How often the product was logged
          example: 42
        totalCalories:
          type: number
          format: double
          description: Sum of calories contributed by this product
          example: 12600.5
        totalFat:
          type: number
          format: double
          description: Sum of fat in grams contributed by this product
          example: 310.2
        totalCarbs:
          type: number
          format: double
          description: Sum of carbs in grams contributed by this product
          example: 1850.7
        totalProtein:
          type: number
          format: double
          description: Sum of protein in grams contributed by this product
          example: 540.3
        averageCalories:
          type: number
          format: double
          description: Average calories per logged occurrence
          example: 300.0

    ProductSummaryDTO:
      type: object
      description: Aggregated summary for all products matching a search term
      properties:
        searchTerm:
          type: string
          description: The search term this summary was built for
          example: "haferflocken"
        matchedProductNames:
          type: array
          description: Distinct product names that matched the search term
          items:
            type: string
        timesEaten:
          type: integer
          format: int64
          description: How often a matching product was logged
          example: 42
        firstDate:
          type: string
          format: date
          description: First date a matching product was logged
          example: "2024-01-03"
        lastDate:
          type: string
          format: date
          description: Most recent date a matching product was logged
          example: "2024-12-19"
        totalCalories:
          type: number
          format: double
          description: Sum of calories contributed by matching products
          example: 12600.5
        totalFat:
          type: number
          format: double
          description: Sum of fat in grams contributed by matching products
          example: 310.2
        totalCarbs:
          type: number
          format: double
          description: Sum of carbs in grams contributed by matching products
          example: 1850.7
        totalProtein:
          type: number
          format: double
          description: Sum of protein in grams contributed by matching products
          example: 540.3
        averageCalories:
          type: number
          format: double
          description: Average calories per logged occurrence
          example: 300.0
        weekdayDistribution:
          type: object
          description: How the occurrences distribute over the days of the week
          additionalProperties:
            type: integer
            format: int64
          example:
            MONDAY: 8
            TUESDAY: 5
            WEDNESDAY: 6
            THURSDAY: 7
            FRIDAY: 6
            SATURDAY: 5
            SUNDAY: 5

    TrendPointDTO:
      type: object
      description: One bucket of a nutritional trend time series
      properties:
        bucket:
          type: string
          description: Label of the bucket - the date for DAY, ISO week for WEEK, year-month for MONTH
          example: "2024-W03"
        fromDate:
          type: string
          format: date
          description: First day of the bucket that lies within the queried range
          example: "2024-01-15"
        toDate:
          type: string
          format: date
          description: Last day of the bucket that lies within the queried range
          example: "2024-01-21"
        dayCount:
          type: integer
          format: int64
          description: Number of days with an entry inside this bucket
          example: 7
        average:
          type: number
          format: double
          description: Average value of the metric across the days with an entry
          example: 2143.7
        total:
          type: number
          format: double
          description: Summed value of the metric across the days with an entry
          example: 15005.9

    WeekdayStatsDTO:
      type: object
      description: Average nutritional values grouped by day of the week
      properties:
        dayOfWeek:
          type: string
          enum:
            - MONDAY
            - TUESDAY
            - WEDNESDAY
            - THURSDAY
            - FRIDAY
            - SATURDAY
            - SUNDAY
          description: Day of the week
          example: SATURDAY
        dayCount:
          type: integer
          format: int64
          description: Number of entries that fell on this day of the week
          example: 52
        averages:
          $ref: '#/components/schemas/Averages'

    MacroSplitDTO:
      type: object
      description: kcal-weighted share of energy from fat, carbs and protein
      properties:
        fromDate:
          type: string
          description: Start date of the range
          example: "2024-01-01"
        toDate:
          type: string
          description: End date of the range
          example: "2024-01-31"
        fatPercentage:
          type: number
          format: double
          description: Percentage of energy from fat
          example: 34.5
        carbsPercentage:
          type: number
          format: double
          description: Percentage of energy from carbs
          example: 45.2
        proteinPercentage:
          type: number
          format: double
          description: Percentage of energy from protein
          example: 20.3
        fatCalories:
          type: number
          format: double
          description: Average daily kcal from fat
          example: 690.3
        carbsCalories:
          type: number
          format: double
          description: Average daily kcal from carbs
          example: 904.8
        proteinCalories:
          type: number
          format: double
          description: Average daily kcal from protein
          example: 406.4
        macroCalories:
          type: number
          format: double
          description: Average daily kcal derived from the macros (fat*9 + carbs*4 + protein*4)
          example: 2001.5
        averageCalories:
          type: number
          format: double
          description: Average daily kcal as reported by FDDB
          example: 2000.5

    CorrelationInputDto:
      type: object
      description: Input data for correlation analysis
      properties:
        inclusionKeywords:
          type: array
          description: Keywords to match products for inclusion in the analysis
          items:
            type: string
          example: [ "milk", "cheese" ]
        exclusionKeywords:
          type: array
          description: Keywords to match products for exclusion from the analysis
          items:
            type: string
          example: [ "lactose-free" ]
        occurrenceDates:
          type: array
          description: Dates when specific events occurred
          items:
            type: string
          example: [ "2024-01-05", "2024-01-12", "2024-01-19" ]
        startDate:
          type: string
          description: Start date for the analysis
          example: "2024-01-01"

    CorrelationOutputDto:
      type: object
      description: Result of correlation analysis
      properties:
        correlations:
          $ref: '#/components/schemas/Correlations'
        matchedProducts:
          type: array
          description: List of products that matched the criteria
          items:
            type: string
        matchedDates:
          type: array
          description: List of dates that matched the criteria
          items:
            type: string
            format: date
        amountMatchedProducts:
          type: integer
          description: Number of products that matched
          example: 15
        amountMatchedDates:
          type: integer
          description: Number of dates that matched
          example: 12

    Correlations:
      type: object
      description: Correlation details for different time windows
      properties:
        across3Days:
          $ref: '#/components/schemas/CorrelationDetail'
        across2Days:
          $ref: '#/components/schemas/CorrelationDetail'
        sameDay:
          $ref: '#/components/schemas/CorrelationDetail'
        oneDayBefore:
          $ref: '#/components/schemas/CorrelationDetail'
        twoDaysBefore:
          $ref: '#/components/schemas/CorrelationDetail'

    CorrelationDetail:
      type: object
      description: Detailed correlation information for a specific time window
      properties:
        percentage:
          type: number
          format: double
          description: Correlation percentage
          example: 75.5
        matchedDates:
          type: array
          description: Dates that matched in this time window
          items:
            type: string
        matchedDays:
          type: integer
          description: Number of days that matched
          example: 9

    ErrorResponse:
      type: object
      description: Error response
      properties:
        message:
          type: string
          description: Error message
          example: "MongoDB not available"
        timestamp:
          type: string
          format: date-time
          description: Timestamp of the error
        path:
          type: string
          description: Request path that caused the error

