openapi: 3.1.0
info:
  title: Popcast Attention API
  version: 0.1.0
  description: |
    Attention layer of The Conscience Stack. Forward-looking per-FIPS
    event schedule (concerts, sports, conferences, festivals, community
    events, school sessions, civic/holiday). Uses `horizon_days` for the
    single-FIPS endpoint and `window_days` (lookback) for history.

    Sources: Ticketmaster Discovery API (free tier), Eventbrite (stub),
    US federal holidays (static 2026-2030), school calendars (static
    top-25 DMAs).
  contact: { name: Motionworks AI, url: https://docs.mworks.com }

servers:
  - url: https://api.mworks.com

tags:
  - name: attention
    description: Block group attention signal endpoints

paths:
  /v2/popcast/attention/{fips}:
    get:
      operationId: getAttentionSignal
      summary: Forward-looking event signal
      description: Returns events within `horizon_days` of today.
      tags: [attention]
      x-motionworks-status: roadmap
      x-motionworks-data-maturity: synthetic-only
      x-credit-cost: 1
      parameters:
        - $ref: '#/components/parameters/FipsParam'
        - name: horizon
          in: query
          schema: { type: integer, enum: [7, 14, 30], default: 14 }
      responses:
        '200':
          description: Attention signal
          content:
            application/json:
              schema: { $ref: '#/components/schemas/AttentionSignalResponse' }
        '404': { $ref: '#/components/responses/NotFound' }
        '400': { $ref: '#/components/responses/ValidationError' }

  /v2/popcast/attention/{fips}/history:
    get:
      operationId: getAttentionHistory
      summary: Past attention rollup
      tags: [attention]
      x-motionworks-status: roadmap
      x-motionworks-data-maturity: synthetic-only
      x-credit-cost: 3
      parameters:
        - $ref: '#/components/parameters/FipsParam'
        - name: window
          in: query
          schema: { type: integer, enum: [30, 90], default: 30 }
        - { name: cursor, in: query, schema: { type: string } }
        - { name: limit, in: query, schema: { type: integer, maximum: 24 } }
      responses:
        '200':
          description: Attention history
          content:
            application/json:
              schema: { $ref: '#/components/schemas/AttentionHistoryResponse' }

  /v2/popcast/attention/batch:
    post:
      operationId: batchAttentionSignals
      summary: Batch attention lookup
      tags: [attention]
      x-motionworks-status: roadmap
      x-motionworks-data-maturity: synthetic-only
      x-credit-cost: 100
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/AttentionBatchRequest' }
      responses:
        '200':
          description: Batch results
          content:
            application/json:
              schema: { $ref: '#/components/schemas/AttentionBatchResponse' }

components:
  parameters:
    FipsParam:
      name: fips
      in: path
      required: true
      schema: { type: string, pattern: '^\d{12}$' }

  schemas:
    EventItem:
      type: object
      required: [id, name, category, start_time, source]
      properties:
        id: { type: string }
        name: { type: string }
        category: { type: string, enum: [concert, sports, conference, festival, community, school, civic, holiday] }
        start_time: { type: string, format: date-time }
        end_time: { type: string, format: date-time }
        venue_name: { type: string }
        venue_address: { type: string }
        latitude: { type: number }
        longitude: { type: number }
        expected_attendance: { type: integer }
        url: { type: string, format: uri }
        source: { type: string }

    AttentionPayload:
      type: object
      properties:
        events:
          type: array
          items: { $ref: '#/components/schemas/EventItem' }
        total_expected_attendance: { type: integer }
        categories: { type: object, additionalProperties: { type: integer } }
        peak_day: { type: string, nullable: true }

    AttentionSignal:
      type: object
      required: [fips, signal_layer, horizon_days, period_end, refreshed_at, payload]
      properties:
        fips: { type: string }
        signal_layer: { type: string, enum: [attention] }
        period_end: { type: string }
        horizon_days: { type: integer, enum: [7, 14, 30] }
        refreshed_at: { type: string, format: date-time }
        data_quality: { type: string, enum: [high, medium, low] }
        source_breakdown: { type: object, additionalProperties: { type: integer } }
        payload: { $ref: '#/components/schemas/AttentionPayload' }

    Meta:
      type: object
      properties:
        request_id: { type: string }
        credits_used: { type: integer }
        product: { type: string }
        version: { type: string }
        provenance: { type: object, additionalProperties: true }

    AttentionSignalResponse:
      type: object
      properties:
        data: { $ref: '#/components/schemas/AttentionSignal' }
        meta: { $ref: '#/components/schemas/Meta' }

    AttentionHistorySnapshot:
      type: object
      properties:
        fips: { type: string }
        period_start: { type: string }
        period_end: { type: string }
        window_days: { type: integer }
        event_count: { type: integer }
        total_attendance: { type: integer }
        categories: { type: object, additionalProperties: { type: integer } }
        data_quality: { type: string }

    AttentionHistoryResponse:
      type: object
      properties:
        data:
          type: array
          items: { $ref: '#/components/schemas/AttentionHistorySnapshot' }
        pagination:
          type: object
          properties:
            cursor: { type: string, nullable: true }
            has_more: { type: boolean }
            total: { type: integer }
        meta: { $ref: '#/components/schemas/Meta' }

    AttentionBatchRequest:
      type: object
      required: [fips_codes]
      properties:
        fips_codes:
          type: array
          maxItems: 100
          items: { type: string, pattern: '^\d{12}$' }
        horizon: { type: integer, enum: [7, 14, 30] }

    AttentionBatchResponse:
      type: object
      properties:
        data:
          type: array
          items: { $ref: '#/components/schemas/AttentionSignal' }
        meta: { $ref: '#/components/schemas/Meta' }

    ApiError:
      type: object
      properties:
        error:
          type: object
          properties:
            code: { type: string }
            message: { type: string }
            status: { type: integer }
            request_id: { type: string }

  responses:
    NotFound:
      description: Not found
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ApiError' }
    ValidationError:
      description: Validation error
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ApiError' }
