openapi: 3.1.0
info:
  title: Alert-JP API
  description: |
    日本の緊急速報リアルタイム配信API

    ## 特徴
    - ⚡ 低レイテンシ配信（Cloudflare Workers）
    - 🌐 世界310拠点のエッジネットワーク
    - 📡 REST API、WebSocket、SSE対応
    - 🔒 セキュアな認証（API Key）
    - 📊 99.9%以上の稼働率

    ## データソース
    | ソース | 種別 | 更新間隔 | 説明 |
    |--------|------|----------|------|
    | JMA (気象庁) | 地震・津波・気象・火山 | 10秒 | 日本国内の公式速報 |
    | USGS | 地震 | 1分 | 日本周辺の海外地震 |
    | P2P地震情報 | 地震 | 30秒 | コミュニティベースの地震情報 |
    | IHR (Internet Health Report) | ネットワーク障害 | 5分 | BGP/ネットワーク異常検知 |

    ## 速報種別
    - 地震速報（気象庁/USGS/P2P）
    - 津波警報（気象庁）
    - 気象警報（気象庁）
    - 火山情報（気象庁）
    - ネットワーク障害（IHR）

    ## Getting Started
    1. [アカウント登録](https://www.alert-jp.org/signup)
    2. API Keyを取得
    3. エンドポイントを呼び出し

    ## サポート
    - ドキュメント: https://docs.alert-jp.org
    - ステータス: https://status.alert-jp.org
    - お問い合わせ: https://www.alert-jp.org/contact
  version: 1.1.0
  contact:
    name: Alert-JP
    url: https://www.alert-jp.org
  license:
    name: 利用規約
    url: https://www.alert-jp.org/terms
servers:
  - url: https://api.alert-jp.org
    description: 本番環境
  - url: http://localhost:3083
    description: ローカル開発環境
tags:
  - name: Standard
    description: 標準エンドポイント（ヘルスチェック等）- Marduk仕様準拠
  - name: Alerts
    description: アラート情報取得
  - name: Realtime
    description: リアルタイム配信（SSE/WebSocket）
  - name: Admin
    description: 管理機能（内部用）
  - name: External Pollers
    description: 外部ポーラー管理（USGS/P2P/IHR）
  - name: Feeds
    description: RSSフィード
  - name: Statistics
    description: 統計情報
  - name: Education
    description: 教育・防災啓発
  - name: Business
    description: Business API（メディア・企業向け）- X-Business-API-Key 認証必須
paths:
  /health:
    get:
      tags:
        - Standard
      summary: Health check
      description: APIの稼働状況を確認
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: healthy
                  service:
                    type: string
                    example: alert-jp-api
                  timestamp:
                    type: string
                    format: date-time
      operationId: getHealth
      security: []
  /version:
    get:
      tags:
        - Standard
      summary: Get the API version and build info.
      description: APIのバージョン情報とMarduk仕様バージョン
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionResponse'
      operationId: getVersion
  /ready:
    get:
      tags:
        - Standard
      summary: Readiness probe — returns 200 when ready to serve traffic.
      description: Kubernetes/orchestrator用のReadinessプローブ
      responses:
        '200':
          description: 準備完了
          content:
            application/json:
              schema:
                type: object
                properties:
                  ready:
                    type: boolean
                    example: true
                  timestamp:
                    type: string
                    format: date-time
      operationId: getReady
  /metrics:
    get:
      tags:
        - Standard
      summary: API metrics in JSON or Prometheus format.
      description: Prometheus形式のメトリクス情報
      responses:
        '200':
          description: メトリクス
          content:
            text/plain:
              schema:
                type: string
                example: |
                  # HELP http_requests_total Total HTTP requests
                  # TYPE http_requests_total counter
                  http_requests_total{method="GET",status="200"} 1234
      operationId: getMetrics
  /stats:
    get:
      tags:
        - Statistics
      summary: Aggregated alert statistics across all regions and alert types.
      description: アラート統計と配信パフォーマンス
      responses:
        '200':
          description: 統計情報
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StatsResponse'
      operationId: getStats
  /api/v1/alerts:
    get:
      tags:
        - Alerts
      summary: List recent Japanese emergency alerts (earthquake, weather, etc.).
      description: 最新のアラート情報を取得
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
          description: Maximum number of results to return
          example: 20
        - name: type
          in: query
          description: アラート種別でフィルタ
          schema:
            $ref: '#/components/schemas/AlertType'
          example: standard
        - name: source
          in: query
          description: データソースでフィルタ
          schema:
            $ref: '#/components/schemas/AlertSource'
          example: jma
        - name: severity
          in: query
          schema:
            type: string
            enum:
              - minor
              - moderate
              - severe
              - extreme
          description: Severity
          example: severe
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Alert'
      operationId: getAlerts
  /api/v1/alerts/{id}:
    get:
      tags:
        - Alerts
      summary: Get the full record for one Japanese emergency alert by ID.
      description: |
        Returns the full record for one alert — original source feed payload, parsed structured fields, affected regions, severity escalation history.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Unique resource identifier
          example: abc-123
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Alert'
        '404':
          description: アラートが見つかりません
      operationId: getAlertsId
  /api/v1/stream/alerts:
    get:
      tags:
        - Realtime
      summary: Server-Sent Events stream of live emergency alerts as they arrive.
      description: |
        Server-Sent Eventsでリアルタイムアラート配信

        ## 使用例
        ```javascript
        const es = new EventSource('https://api.alert-jp.org/api/v1/stream/alerts', {
          headers: {
            'X-API-Key': 'YOUR_API_KEY'
          }
        });

        es.addEventListener('alert', (event) => {
          const alert = JSON.parse(event.data);
          console.log('新しいアラート:', alert);
        });

        es.addEventListener('connected', (event) => {
          const data = JSON.parse(event.data);
          console.log('接続ID:', data.sessionId);
        });
        ```

        ## イベント種別
        - `connected`: 接続確立時
        - `alert`: 新しいアラート受信時
        - `heartbeat`: 接続維持用（30秒ごと）
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: SSE接続確立
          content:
            text/event-stream:
              schema:
                type: string
              example: |
                event: connected
                data: {"sessionId":"abc123","timestamp":"2025-01-15T12:00:00Z"}

                event: alert
                data: {"id":"earthquake-001","type":"earthquake","title":"震度5強","severity":"high"}
        '401':
          description: 認証エラー
      operationId: getSseAlerts
  /api/v1/ws/alerts:
    get:
      tags:
        - Realtime
      summary: WebSocket stream of live emergency alerts (alternative to SSE).
      description: |
        WebSocketでリアルタイムアラート配信

        ## 使用例
        ```javascript
        const ws = new WebSocket('wss://api.alert-jp.org/api/v1/ws/alerts?apiKey=YOUR_API_KEY');

        ws.onopen = () => {
          console.log('WebSocket接続確立');
        };

        ws.onmessage = (event) => {
          const data = JSON.parse(event.data);
          if (data.event === 'alert') {
            console.log('新しいアラート:', data.data);
          }
        };

        ws.onerror = (error) => {
          console.error('WebSocketエラー:', error);
        };
        ```

        ## メッセージ形式
        - `{"event":"connected","data":{...}}`: 接続確立
        - `{"event":"alert","data":{...}}`: 新しいアラート
        - `{"event":"heartbeat","data":{...}}`: 接続維持
      parameters:
        - name: apiKey
          in: query
          required: true
          schema:
            type: string
          description: API Key（クエリパラメータで指定）
          example: pk_live_...
      responses:
        '101':
          description: WebSocket接続確立
        '401':
          description: 認証エラー
      operationId: getWsAlerts
  /api/v1/admin/polling/status:
    get:
      tags:
        - Admin
      summary: Get JMA-polling status (admin) — last fetch time, errors.
      description: |
        Returns current status of the JMA-polling worker — last successful fetch time, error count, items ingested.
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  summary:
                    type: object
                    properties:
                      totalPollers:
                        type: integer
                      activePollers:
                        type: integer
                      effectiveInterval:
                        type: string
                      mostRecentPoll:
                        type: string
                        format: date-time
      operationId: getAdminPollingStatus
  /api/v1/admin/polling/start:
    post:
      tags:
        - Admin
      summary: Start JMA polling (admin). Resumes alert ingest from JMA feeds.
      description: |
        Starts the JMA-polling worker if stopped. Idempotent — no-op if already running.
      responses:
        '200':
          description: 開始成功
      operationId: createAdminPollingStart
  /api/v1/admin/external-pollers/status:
    get:
      tags:
        - External Pollers
      summary: Get status of all external alert-source pollers (admin).
      description: USGS、P2P、IHRの全ポーラー状態を一括取得
      responses:
        '200':
          description: ポーラー状態一覧
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalPollersStatus'
      operationId: getAdminExternalPollersStatus
  /api/v1/admin/external-pollers/start:
    post:
      tags:
        - External Pollers
      summary: Start all external alert-source pollers (admin).
      description: USGS、P2P、IHRの全ポーラーを一括開始
      responses:
        '200':
          description: 開始成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  results:
                    type: object
      operationId: createAdminExternalPollersStart
  /api/v1/admin/external-pollers/stop:
    post:
      tags:
        - External Pollers
      summary: Stop all external alert-source pollers (admin).
      description: |
        Stops every external alert-source poller. Used during incidents to halt ingest.
      responses:
        '200':
          description: 停止成功
      operationId: createAdminExternalPollersStop
  /api/v1/admin/external-pollers/{name}/status:
    get:
      tags:
        - External Pollers
      summary: Get status of one named external alert-source poller (admin).
      description: |
        Returns status for one named external alert-source poller.
      parameters:
        - name: name
          in: path
          required: true
          schema:
            type: string
            enum:
              - usgs
              - p2p
              - ihr
          description: ポーラー名
          example: usgs
      responses:
        '200':
          description: ポーラー状態
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PollerStatus'
      operationId: getAdminExternalPollersNameStatus
  /api/v1/admin/external-pollers/{name}/start:
    post:
      tags:
        - External Pollers
      summary: Start one named external alert-source poller (admin).
      description: |
        Starts one named external alert-source poller. Idempotent.
      parameters:
        - name: name
          in: path
          required: true
          schema:
            type: string
            enum:
              - usgs
              - p2p
              - ihr
          description: Name
          example: usgs
      responses:
        '200':
          description: 開始成功
      operationId: createAdminExternalPollersNameStart
  /api/v1/admin/external-pollers/{name}/test:
    get:
      tags:
        - External Pollers
      summary: Test connectivity to one external alert source (admin).
      description: 外部APIへの接続テストを実行
      parameters:
        - name: name
          in: path
          required: true
          schema:
            type: string
            enum:
              - usgs
              - p2p
              - ihr
          description: Name
          example: usgs
      responses:
        '200':
          description: テスト成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
      operationId: getAdminExternalPollersNameTest
  /api/v1/feed/rss:
    get:
      tags:
        - Feeds
      summary: RSS 2.0 feed of recent emergency alerts (for feed readers).
      description: |
        Returns recent alerts as an RSS 2.0 feed for compatibility with feed readers.
      responses:
        '200':
          description: RSSフィード
          content:
            application/rss+xml:
              schema:
                type: string
      operationId: getFeedRss
  /api/v1/feed/atom:
    get:
      tags:
        - Feeds
      summary: Atom 1.0 feed of recent emergency alerts (for feed readers).
      description: |
        Returns recent alerts as an Atom 1.0 feed for compatibility with feed readers.
      responses:
        '200':
          description: Atomフィード
          content:
            application/atom+xml:
              schema:
                type: string
      operationId: getFeedAtom
  /api/v1/education/tips:
    get:
      tags:
        - Education
      summary: List disaster-preparedness tips (educational content).
      description: 防災豆知識の一覧を取得します。カテゴリでフィルタできます。
      parameters:
        - name: category
          in: query
          description: カテゴリでフィルタ
          schema:
            type: string
            enum:
              - earthquake
              - tsunami
              - typhoon
              - flood
              - general
          example: general
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/PreventionTip'
                  meta:
                    type: object
                    properties:
                      timestamp:
                        type: string
                        format: date-time
                      total:
                        type: integer
                      categories:
                        type: array
                        items:
                          type: string
      operationId: getEducationTips
  /api/v1/education/tips/{id}:
    get:
      tags:
        - Education
      summary: Get one disaster-preparedness tip (educational) by ID.
      description: 指定IDの防災豆知識を取得します。
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: 豆知識ID
          example: abc-123
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/PreventionTip'
                  meta:
                    type: object
                    properties:
                      timestamp:
                        type: string
                        format: date-time
        '404':
          description: 豆知識が見つかりません
      operationId: getEducationTipsId
  /api/v1/education/quiz:
    get:
      tags:
        - Education
      summary: Get a random disaster-preparedness quiz question.
      description: 防災に関するランダムなクイズを出題します。カテゴリでフィルタできます。
      parameters:
        - name: category
          in: query
          description: カテゴリでフィルタ
          schema:
            type: string
            enum:
              - earthquake
              - tsunami
              - typhoon
              - flood
              - general
          example: general
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/Quiz'
                  meta:
                    type: object
                    properties:
                      timestamp:
                        type: string
                        format: date-time
                      total_quizzes:
                        type: integer
        '404':
          description: 該当カテゴリのクイズが見つかりません
      operationId: getEducationQuiz
  /api/v1/education/prevention-tip:
    get:
      tags:
        - Education
      summary: Get a random disaster-preparedness tip (educational).
      description: ランダムな防災豆知識（地震、津波、台風など）を返します。教育目的や日常の備えとして利用できます。
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/PreventionTip'
                  meta:
                    type: object
                    properties:
                      timestamp:
                        type: string
                        format: date-time
                      total_tips:
                        type: integer
      operationId: getEducationPreventionTip
  /api/v1/alerts/easy:
    get:
      tags:
        - Education
      summary: Get alerts rewritten in simplified "easy" Japanese (やさしい日本語).
      description: 最新の防災アラートを、外国人や子供にも分かりやすい「やさしい日本語」に変換して返します。AI (Claude 3.5 Sonnet) を使用します。
      responses:
        '200':
          description: 正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/EasyAlert'
                  meta:
                    type: object
                    properties:
                      tokens_used:
                        type: integer
                      model:
                        type: string
                      cached:
                        type: boolean
        '503':
          description: AIサービス未設定または利用不可
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: CONFIG_ERROR
                      message:
                        type: string
      operationId: getAlertsEasy
  /api/business/v1/alerts:
    get:
      tags:
        - Business
      summary: List alerts via the Business-tier alerts endpoint (auth required).
      description: |
        高優先度アラート配信（5秒以内保証）。
        フィルタリング、XML形式出力に対応。
      security:
        - BusinessApiKeyAuth: []
      parameters:
        - name: types
          in: query
          description: アラート種別でフィルタ（カンマ区切り）
          schema:
            type: string
            example: earthquake,tsunami
        - name: areas
          in: query
          description: 地域でフィルタ（カンマ区切り）
          schema:
            type: string
          example: 'tokyo,osaka,kanagawa'
        - name: severity
          in: query
          description: 深刻度でフィルタ（カンマ区切り）
          schema:
            type: string
            example: extreme,severe
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
            maximum: 100
          description: Maximum number of results to return
          example: 20
        - name: format
          in: query
          description: レスポンス形式
          schema:
            type: string
            enum:
              - json
              - xml
            default: json
          example: json
      responses:
        '200':
          description: アラート一覧
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/BusinessAlert'
                  meta:
                    $ref: '#/components/schemas/BusinessMeta'
        '401':
          description: 認証エラー
      operationId: getBusinessV1Alerts
  /api/business/v1/alerts/{id}:
    get:
      tags:
        - Business
      summary: Get one alert via the Business-tier endpoint (auth required).
      description: |
        Returns one alert via the Business-tier endpoint with full extended fields.
      security:
        - BusinessApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Unique resource identifier
          example: abc-123
      responses:
        '200':
          description: アラート詳細
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessAlert'
        '401':
          description: 認証エラー
        '404':
          description: アラートが見つかりません
      operationId: getBusinessV1AlertsId
  /api/business/v1/alerts/stream:
    get:
      tags:
        - Business
      summary: Business-tier SSE stream of live alerts (auth required).
      description: Server-Sent Eventsでリアルタイムアラート配信（Business専用・優先配信）
      security:
        - BusinessApiKeyAuth: []
      responses:
        '200':
          description: SSE接続確立
          content:
            text/event-stream:
              schema:
                type: string
        '401':
          description: 認証エラー
      operationId: getBusinessV1AlertsStream
  /api/business/v1/usage:
    get:
      tags:
        - Business
      summary: Get the caller's API usage and remaining quota.
      description: 当月のAPI使用状況をD1データベースから取得
      security:
        - BusinessApiKeyAuth: []
      responses:
        '200':
          description: 使用状況
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessUsage'
        '401':
          description: 認証エラー
      operationId: getBusinessV1Usage
  /v1/metadata/enums:
    get:
      summary: List every enum used by the alert-jp API.
      description: |
        Returns the directory of enums (alert types, severity levels, region
        codes, source feeds) with localised labels. Use when building UIs
        that mirror the API's vocabulary.
      operationId: listEnums
      tags:
        - Metadata
      security: []
      responses:
        '200':
          description: Enum metadata
  /v1/metadata/enums/{name}:
    get:
      summary: Get one alert-jp enum (alert_type, severity, region_code) by name.
      description: |
        Returns localised values for one enum. See `listEnums` for the directory of available enum names.
      operationId: getEnum
      tags:
        - Metadata
      security: []
      parameters:
        - name: name
          in: path
          required: true
          example: alert_type
          schema: { type: string }
      responses:
        '200':
          description: Enum values

components:
  schemas:
    AlertType:
      type: string
      enum:
        - earthquake
        - tsunami
        - weather
        - volcanic
        - network
        - other
      description: |
        アラート種別:
        - `earthquake`: 地震速報
        - `tsunami`: 津波警報
        - `weather`: 気象警報
        - `volcanic`: 火山情報
        - `network`: ネットワーク障害
        - `other`: その他
    AlertSource:
      type: string
      enum:
        - jma
        - usgs
        - p2p
        - ihr
        - manual
      description: |
        データソース:
        - `jma`: 気象庁（Japan Meteorological Agency）
        - `usgs`: 米国地質調査所（US Geological Survey）
        - `p2p`: P2P地震情報
        - `ihr`: Internet Health Report
        - `manual`: 手動登録
    Alert:
      type: object
      required:
        - id
        - type
        - title
        - severity
        - issuedAt
      properties:
        id:
          type: string
          example: usgs-earthquake-us7000n3gb
          description: アラートの一意識別子
        type:
          $ref: '#/components/schemas/AlertType'
        source:
          $ref: '#/components/schemas/AlertSource'
        title:
          type: string
          example: M6.2 - 150km ENE of Katsuura, Japan
        description:
          type: string
          description: アラートの詳細説明
        severity:
          type: string
          enum:
            - minor
            - moderate
            - severe
            - extreme
          description: 深刻度レベル
        areas:
          type: array
          items:
            type: string
          description: 影響を受ける地域
        location:
          type: object
          properties:
            latitude:
              type: number
              example: 35.6895
            longitude:
              type: number
              example: 139.6917
            depth:
              type: number
              description: 震源の深さ（km）
          description: 位置情報（地震の場合）
        magnitude:
          type: number
          example: 6.2
          description: マグニチュード（地震の場合）
        issuedAt:
          type: string
          format: date-time
          description: アラート発行時刻
        validUntil:
          type: string
          format: date-time
          description: アラート有効期限
        metadata:
          type: object
          additionalProperties: true
          description: ソース固有の追加データ
        rawData:
          type: object
          description: 元データ（デバッグ用）
    VersionResponse:
      type: object
      properties:
        service:
          type: string
          example: alert-jp-api
        version:
          type: string
          example: 1.1.0
        marduk_version:
          type: string
          example: 2.1.0
        api_version:
          type: string
          example: v1
        commit:
          type: string
          description: Gitコミットハッシュ
        build_time:
          type: string
          format: date-time
    StatsResponse:
      type: object
      properties:
        totalAlerts:
          type: integer
          description: 総アラート数
        alertsByType:
          type: object
          additionalProperties:
            type: integer
        alertsBySource:
          type: object
          additionalProperties:
            type: integer
        recentAlerts:
          type: integer
          description: 過去24時間のアラート数
        averageDeliveryTime:
          type: number
          description: 平均配信時間（ミリ秒）
    PollerStatus:
      type: object
      properties:
        name:
          type: string
          example: usgs-poller
        isActive:
          type: boolean
        lastPollTime:
          type: string
          format: date-time
        nextPollTime:
          type: string
          format: date-time
        pollInterval:
          type: integer
          description: ポーリング間隔（ミリ秒）
        successRate:
          type: number
          description: 成功率（0-1）
        recentPolls:
          type: array
          items:
            type: object
            properties:
              timestamp:
                type: string
                format: date-time
              duration:
                type: integer
              alertsFound:
                type: integer
              status:
                type: string
                enum:
                  - success
                  - error
    ExternalPollersStatus:
      type: object
      properties:
        usgs:
          $ref: '#/components/schemas/PollerStatus'
        p2p:
          $ref: '#/components/schemas/PollerStatus'
        ihr:
          $ref: '#/components/schemas/PollerStatus'
        summary:
          type: object
          properties:
            totalPollers:
              type: integer
              example: 3
            activePollers:
              type: integer
            totalAlertsToday:
              type: integer
              example: 123
    PreventionTip:
      type: object
      properties:
        id:
          type: string
          example: eq-01
        category:
          type: string
          enum:
            - earthquake
            - tsunami
            - typhoon
            - flood
            - general
          example: earthquake
        title:
          type: string
          example: Drop, Cover, and Hold On
        content:
          type: string
          example: When an earthquake strikes, drop to your hands and knees...
    EasyAlert:
      type: object
      properties:
        id:
          type: string
          example: alert-001
        type:
          type: string
          example: earthquake
        original:
          type: string
          description: 元のアラート文
          example: 緊急地震速報。強い揺れに警戒してください。
        easy_japanese:
          type: string
          description: やさしい日本語に変換されたアラート文
          example: おおきな じしんが きます。 つよい ゆれに きをつけて ください。
        timestamp:
          type: string
          format: date-time
    Quiz:
      type: object
      properties:
        id:
          type: string
          example: quiz-01
        category:
          type: string
          enum:
            - earthquake
            - tsunami
            - typhoon
            - flood
            - general
          example: earthquake
        question:
          type: string
          example: What should you do first when an earthquake strikes?
        choices:
          type: array
          items:
            type: string
          example:
            - Run outside immediately
            - Drop to your hands and knees
            - Stand in a doorway
            - Call emergency services
        correct_index:
          type: integer
          example: 1
        explanation:
          type: string
          example: The recommended action is to Drop, Cover, and Hold On.
    BusinessAlert:
      allOf:
        - $ref: '#/components/schemas/Alert'
        - type: object
          properties:
            _business:
              type: object
              properties:
                tier:
                  type: string
                  enum:
                    - standard
                    - premium
                    - enterprise
                priority:
                  type: string
                  enum:
                    - normal
                    - high
                    - critical
                deliveryTime:
                  type: string
                  format: date-time
                apiVersion:
                  type: string
                  example: business/v1
    BusinessMeta:
      type: object
      properties:
        count:
          type: integer
        tier:
          type: string
          enum:
            - standard
            - premium
            - enterprise
        timestamp:
          type: string
          format: date-time
        sla:
          type: object
          properties:
            targetLatency:
              type: string
              example: 5s
            guaranteedUptime:
              type: string
              example: 99.9%
    BusinessUsage:
      type: object
      properties:
        customerId:
          type: string
        tier:
          type: string
          enum:
            - standard
            - premium
            - enterprise
        period:
          type: object
          properties:
            start:
              type: string
              format: date-time
            end:
              type: string
              format: date-time
        usage:
          type: object
          properties:
            apiCalls:
              type: integer
            websocketConnections:
              type: integer
        quota:
          type: object
          properties:
            calls:
              oneOf:
                - type: integer
                - type: string
                  enum:
                    - unlimited
            remaining:
              oneOf:
                - type: integer
                - type: string
                  enum:
                    - unlimited
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: APIキー認証
    BusinessApiKeyAuth:
      type: apiKey
      in: header
      name: X-Business-API-Key
      description: Business APIキー認証（メディア・企業向け）
security:
  - ApiKeyAuth: []