{
  "openapi": "3.1.0",
  "info": {
    "title": "Dot API Gateway",
    "version": "1.1.0",
    "description": "Bearer 認証付きの API 入口。ダミー API は独立した HTTP バックエンドを呼び出します。"
  },
  "servers": [{ "url": "https://dot.sugar-knight.com" }],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/v1/backends": {
      "get": {
        "operationId": "listBackends",
        "summary": "登録済みバックエンドの一覧を取得する",
        "description": "名前・説明・公開APIパス・HTTPメソッドを返します。内部アドレスや認証情報は含みません。稼働状態の確認は行いません。",
        "responses": {
          "200": {
            "description": "登録済みバックエンドの公開情報",
            "content": { "application/json": {
              "schema": { "type": "object", "required": ["backends"], "additionalProperties": false, "properties": { "backends": { "type": "array", "items": { "$ref": "#/components/schemas/Backend" } } } },
              "example": { "backends": [{ "id": "dummy", "name": "Dummy API", "description": "独立した HTTP バックエンドを呼び出すダミー API。", "path": "/v1/dummy", "method": "GET" }] }
            } }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "description": "リクエスト数の制限を超過" }
        }
      }
    },
    "/v1/dummy": {
      "get": {
        "operationId": "callDummy",
        "summary": "認証後にダミー API を呼び出す",
        "parameters": [{ "name": "message", "in": "query", "required": false, "schema": { "type": "string", "maxLength": 200, "default": "Hello" } }],
        "responses": {
          "200": {
            "description": "バックエンドからの JSON 応答",
            "content": { "application/json": { "schema": { "type": "object", "required": ["ok", "data"], "properties": { "ok": { "type": "boolean", "const": true }, "data": {} } }, "example": { "ok": true, "data": { "service": "dot-dummy-upstream", "message": "Hello", "timestamp": "2026-10-16T03:00:00.000Z" } } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "description": "リクエスト数の制限を超過" },
          "502": { "$ref": "#/components/responses/BadGateway" },
          "504": { "$ref": "#/components/responses/GatewayTimeout" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "description": "発行された API キーを Authorization: Bearer <key> で指定します。" } },
    "schemas": {
      "Backend": {
        "type": "object", "additionalProperties": false,
        "required": ["id", "name", "description", "path", "method"],
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string" },
          "path": { "type": "string", "description": "このゲートウェイ上の公開APIパス" },
          "method": { "type": "string", "enum": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"] }
        }
      },
      "Error": { "type": "object", "required": ["error"], "properties": { "error": { "type": "string" } } }
    },
    "responses": {
      "BadRequest": { "description": "不正なパラメーター（message は最大200文字）", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "認証キーがない、または不正", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "BadGateway": { "description": "バックエンドへの接続失敗、応答不正、または1 MiB超過", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "GatewayTimeout": { "description": "バックエンドが制限時間内に応答しない（既定5秒）", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
