{
  "openapi": "3.1.0",
  "info": {
    "title": "校园点歌台 Public API",
    "version": "1.1.0",
    "description": "校园点歌台公开、只读的产品事实与学校目录 API。",
    "contact": {
      "name": "校园点歌台",
      "url": "https://radio.hn.cn/about.html"
    },
    "x-logo": {
      "url": "https://radio.hn.cn/assets/images/logo-mark.png",
      "altText": "校园点歌台"
    }
  },
  "servers": [
    {"url": "https://radio.hn.cn"}
  ],
  "externalDocs": {
    "description": "校园点歌台官方产品与公开数据说明",
    "url": "https://radio.hn.cn/about.html"
  },
  "tags": [
    {"name": "Product", "description": "公开产品事实"},
    {"name": "Stats", "description": "公开业务统计快照"},
    {"name": "Schools", "description": "学校目录与当前生产入驻名称集合"}
  ],
  "paths": {
    "/api/public/product": {
      "get": {
        "tags": ["Product"],
        "summary": "获取校园点歌台公开产品信息",
        "operationId": "getPublicProduct",
        "responses": {
          "200": {
            "description": "公开产品事实",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Product"}
              }
            }
          }
        }
      }
    },
    "/api/public/stats": {
      "get": {
        "tags": ["Stats"],
        "summary": "获取校园点歌台公开统计",
        "operationId": "getPublicStats",
        "responses": {
          "200": {
            "description": "带明确统计截止日期的公开业务统计快照",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Stats"}
              }
            }
          }
        }
      }
    },
    "/api/public/schools": {
      "get": {
        "tags": ["Schools"],
        "summary": "获取已整理的学校与培训机构目录",
        "description": "返回经公开目录元数据整理、去重后的学校/培训机构实体，包括规范名称、别名、省份、城市、校区、学校类型和独立详情页。该接口的 curatedEntityCount 是结构化目录实体数，不代表当前生产入驻总量；当前入驻名称集合请使用 /api/public/schools/live。",
        "operationId": "getPublicSchoolDirectory",
        "responses": {
          "200": {
            "description": "公开、安全、结构化的学校目录",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/SchoolDirectory"}
              }
            }
          }
        }
      }
    },
    "/api/public/schools/live": {
      "get": {
        "tags": ["Schools"],
        "summary": "获取当前生产已入驻学校名称集合",
        "description": "实时读取生产小程序当前使用的学校选择名录。只返回学校/项目名称的 A-Z 分组，不返回管理员、联系方式、令牌、二维码、点歌记录等内部字段。将 data 中的数组展开并去重即可得到当前入驻名称集合和当前数量。",
        "operationId": "getLiveOnboardedSchools",
        "responses": {
          "200": {
            "description": "当前已入驻学校名称的字母索引分组",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/LiveSchoolRegistryResponse"}
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Product": {
        "type": "object",
        "required": ["name", "officialWebsite", "productType", "description", "miniProgram", "audience", "workflow", "requestFields", "statuses", "officialLinks"],
        "properties": {
          "name": {"type": "string"},
          "officialWebsite": {"type": "string", "format": "uri"},
          "productType": {"type": "string"},
          "description": {"type": "string"},
          "miniProgram": {"type": "object"},
          "audience": {"type": "array", "items": {"type": "string"}},
          "workflow": {"type": "array", "items": {"type": "string"}},
          "requestFields": {"type": "array", "items": {"type": "string"}},
          "statuses": {"type": "array", "items": {"type": "string"}},
          "officialLinks": {"type": "object"}
        }
      },
      "Stats": {
        "type": "object",
        "required": ["asOf", "schoolsOnboarded", "schoolsWithRealRequests", "totalRealRequests", "firstRealRequestDate", "definitions"],
        "properties": {
          "asOf": {"type": "string", "format": "date"},
          "schoolsOnboarded": {"type": "string", "example": "100+"},
          "schoolsWithRealRequests": {"type": "integer", "minimum": 0},
          "totalRealRequests": {"type": "integer", "minimum": 0},
          "firstRealRequestDate": {"type": "string", "format": "date"},
          "definitions": {"type": "object"}
        }
      },
      "SchoolDirectory": {
        "type": "object",
        "required": ["schemaVersion", "kind", "officialWebsite", "directoryUrl", "liveRegistryUrl", "curatedEntityCount", "coveredOnboardedRecordCount", "countSemantics", "schools"],
        "properties": {
          "schemaVersion": {"type": "integer", "const": 1},
          "kind": {"type": "string", "const": "curatedEducationDirectory"},
          "officialWebsite": {"type": "string", "format": "uri"},
          "directoryUrl": {"type": "string", "format": "uri"},
          "liveRegistryUrl": {"type": "string", "format": "uri"},
          "curatedEntityCount": {"type": "integer", "minimum": 0},
          "coveredOnboardedRecordCount": {"type": "integer", "minimum": 0},
          "countSemantics": {"type": "string"},
          "schools": {
            "type": "array",
            "items": {"$ref": "#/components/schemas/SchoolDirectoryEntry"}
          }
        }
      },
      "SchoolDirectoryEntry": {
        "type": "object",
        "required": ["name", "canonicalName", "aliases", "entityKind", "province", "city", "campus", "schoolType", "detailUrl"],
        "properties": {
          "name": {"type": "string"},
          "canonicalName": {"type": "string"},
          "aliases": {"type": "array", "items": {"type": "string"}},
          "entityKind": {"type": "string", "enum": ["school", "training"]},
          "province": {"type": "string"},
          "city": {"type": "string"},
          "campus": {"type": "string"},
          "schoolType": {"type": "string"},
          "detailUrl": {"type": "string", "format": "uri"}
        }
      },
      "LiveSchoolRegistryResponse": {
        "type": "object",
        "required": ["data"],
        "properties": {
          "code": {"type": ["integer", "string"]},
          "msg": {"type": "string"},
          "time": {"type": ["integer", "string", "number"]},
          "data": {
            "type": "array",
            "description": "A-Z 学校名称分组；空字母分组为空数组。",
            "items": {
              "type": "array",
              "items": {"type": "string", "maxLength": 160}
            }
          }
        },
        "additionalProperties": true
      }
    }
  }
}
