{
  "openapi": "3.0.3",
  "info": {
    "title": "真机矩阵中控 API",
    "version": "1.0.0",
    "description": "跨机房真机矩阵群控与自动化运营系统核心 API。除 /api/login 外均需 Bearer JWT。"
  },
  "servers": [{"url": "/"}],
  "components": {
    "securitySchemes": {"bearer": {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"}}
  },
  "security": [{"bearer": []}],
  "paths": {
    "/api/login": {
      "post": {
        "summary": "登录获取 JWT", "security": [],
        "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"username": {"type": "string"}, "password": {"type": "string"}}}}}},
        "responses": {"200": {"description": "含 token/role/room/username"}, "401": {"description": "凭证错误"}, "429": {"description": "失败过多被锁定"}}
      }
    },
    "/api/state": {"get": {"summary": "设备墙 + 任务实时态", "responses": {"200": {"description": "devices/tasks/ts"}}}},
    "/api/dispatch": {"post": {"summary": "下发单动作到目标", "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"action": {"type": "string"}, "target": {"type": "string"}, "sample": {"type": "number"}}}}}}, "responses": {"200": {"description": "task_id/total"}}}},
    "/api/dispatch/preview": {"post": {"summary": "下发预检(dry-run)", "responses": {"200": {"description": "命中/可执行性分类/抽样预估"}}}},
    "/api/flows": {"get": {"summary": "Flow 列表", "responses": {"200": {"description": "id/name/platform/steps"}}}},
    "/api/flow": {"get": {"summary": "取单个 Flow 定义", "parameters": [{"name": "id", "in": "query", "schema": {"type": "string"}}], "responses": {"200": {"description": "Flow"}}}},
    "/api/flow/save": {"post": {"summary": "保存 Flow", "responses": {"200": {"description": "ok/id"}}}},
    "/api/flow/lint": {"post": {"summary": "Flow 静态校验", "responses": {"200": {"description": "errors/warnings"}}}},
    "/api/flow/run": {"post": {"summary": "运行 Flow(edge:true 委派边缘自治)", "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"flow_id": {"type": "string"}, "target": {"type": "string"}, "sample": {"type": "number"}, "edge": {"type": "boolean"}}}}}}, "responses": {"200": {"description": "task_id/total"}}}},
    "/api/schedule": {"post": {"summary": "创建排期(edge_run:true 下沉边缘)", "responses": {"200": {"description": "Schedule"}}}},
    "/api/schedule/preview": {"get": {"summary": "排期日历预览", "parameters": [{"name": "days", "in": "query", "schema": {"type": "integer"}}], "responses": {"200": {"description": "days/schedules"}}}},
    "/api/dashboard": {"get": {"summary": "数据看板聚合 + SLO", "responses": {"200": {"description": "devices/actions/slo/history"}}}},
    "/api/dashboard/breakdown": {"get": {"summary": "成功率归因(平台/机房/阶段)", "responses": {"200": {"description": "platform/room/stage"}}}},
    "/api/accounts": {"get": {"summary": "账号列表", "responses": {"200": {"description": "Account[]"}}}},
    "/api/health/scores": {"get": {"summary": "设备健康度评分", "responses": {"200": {"description": "summary/devices"}}}},
    "/api/proxy/check": {"get": {"summary": "代理出口一致性体检", "responses": {"200": {"description": "summary/collapse/devices"}}}},
    "/api/audit/anomalies": {"get": {"summary": "审计异常检测", "responses": {"200": {"description": "summary/anomalies"}}}},
    "/api/backup": {"get": {"summary": "导出备份(管理员)", "responses": {"200": {"description": "Backup JSON"}, "403": {"description": "需管理员"}}}},
    "/api/restore": {"post": {"summary": "恢复备份(管理员)", "responses": {"200": {"description": "flows/schedules/kv 计数"}, "403": {"description": "需管理员"}}}},
    "/api/fleet/overview": {"get": {"summary": "机群总览 KPI(在线/就绪/异常/成本聚合)", "responses": {"200": {"description": "devices/accounts/ops"}}}},
    "/api/fleet/versions": {"get": {"summary": "版本看板(灰度观测)", "responses": {"200": {"description": "groups/outdated"}}}},
    "/api/fleet/economics": {"get": {"summary": "成本与产能(代理成本/利用率/养成周期)", "responses": {"200": {"description": "proxy/utilization/cycle"}}}},
    "/api/fleet/trends": {"get": {"summary": "机群时序留存(养成曲线)", "responses": {"200": {"description": "points"}}}},
    "/api/devices/ota": {"post": {"summary": "远程推送升级(sample 灰度)", "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"target": {"type": "string"}, "sample": {"type": "number"}}}}}}, "responses": {"200": {"description": "pushed"}}}},
    "/api/accounts/anomalies": {"get": {"summary": "封号/异常账号红榜", "responses": {"200": {"description": "anomalies/count"}}}},
    "/api/accounts/recommendations": {"get": {"summary": "AI 策略推荐", "responses": {"200": {"description": "recommendations"}}}},
    "/api/playbooks": {"get": {"summary": "养号剧本市场目录", "responses": {"200": {"description": "Playbook[]"}}}},
    "/api/playbook/apply": {"post": {"summary": "一键套用剧本(建 Flow+节律排期)", "responses": {"200": {"description": "schedule"}}}},
    "/api/experiments": {"get": {"summary": "A/B 实验(变体养成对比)", "responses": {"200": {"description": "experiments"}}}},
    "/api/experiment/bandit": {"get": {"summary": "多臂老虎机分配建议", "parameters": [{"name": "id", "in": "query", "schema": {"type": "string"}}], "responses": {"200": {"description": "best/allocation"}}}},
    "/api/billing": {"get": {"summary": "成本账单(按机房)", "responses": {"200": {"description": "lines/total_monthly"}}}},
    "/api/cabinets": {"get": {"summary": "机柜物理监控(温控/电源/湿度)", "responses": {"200": {"description": "Cabinet[]"}}}},
    "/api/cabinet/telemetry": {"post": {"summary": "机柜传感器上报遥测", "responses": {"200": {"description": "ok"}}}},
    "/api/apikey": {"post": {"summary": "创建 API Key(管理员)", "responses": {"200": {"description": "key(仅一次)"}, "403": {"description": "需管理员"}}}},
    "/api/material/aigen": {"post": {"summary": "AI 文案生成(接 Claude API,过质量/查重守门入库)", "description": "按平台风格用 claude-opus-4-8 生成 count 条文案,逐条经质量/查重过滤后作为 text 素材入库;auto_approve 免审。需中心配置 -aikey / ANTHROPIC_API_KEY,未配置返回 503。", "requestBody": {"content": {"application/json": {"schema": {"type": "object", "properties": {"platform": {"type": "string"}, "topic": {"type": "string"}, "count": {"type": "integer"}, "auto_approve": {"type": "boolean"}}}}}}, "responses": {"200": {"description": "ok/count/generated/items[]/errors[]"}, "400": {"description": "缺 topic"}, "502": {"description": "Claude API 错误"}, "503": {"description": "AI 未配置"}}}},
    "/api/material/ingest": {"post": {"summary": "第三方内容生成对接:批量注入素材(url/text/base64)", "description": "外部 AI 生成服务把成品推入素材库。items 每条用 url(中心拉取)/text(文案)/data(base64)之一;source 记生成来源溯源;auto_approve=true 信任源免审(默认待审)。API Key 鉴权。", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"source": {"type": "string"}, "auto_approve": {"type": "boolean"}, "items": {"type": "array", "items": {"type": "object", "properties": {"name": {"type": "string"}, "kind": {"type": "string", "enum": ["image", "video", "text"]}, "platform": {"type": "string"}, "category": {"type": "string"}, "tags": {"type": "array", "items": {"type": "string"}}, "url": {"type": "string"}, "text": {"type": "string"}, "data": {"type": "string"}}}}}}}}}, "responses": {"200": {"description": "ok/count/assets[]/errors[]"}, "400": {"description": "items 为空/过大/格式错误"}}}},
    "/healthz": {"get": {"summary": "存活探针(免鉴权)", "security": [], "responses": {"200": {"description": "status/uptime/store"}}}},
    "/readyz": {"get": {"summary": "就绪探针(免鉴权,存储不可达返 503)", "security": [], "responses": {"200": {"description": "ready"}, "503": {"description": "unavailable"}}}},
    "/metrics": {"get": {"summary": "Prometheus 指标(免鉴权)", "security": [], "responses": {"200": {"description": "text/plain exposition"}}}}
  }
}