{
  "openapi": "3.1.0",
  "info": {
    "title": "ElecJump 应用分发 API",
    "version": "1.0.0",
    "description": "发布工具与AI/CI使用的公开目录、私有上传、不可变版本、发布/撤回及单应用凭证API。JSON请求最多16KiB；二进制单次上传最多90MiB。登录使用既有邮箱验证码接口，管理权限由后端校验。"
  },
  "servers": [
    {
      "url": "https://platform.elecjump.com"
    }
  ],
  "paths": {
    "/v1/admin/distribution/apps": {
      "get": {
        "summary": "listDistributionApps",
        "description": "仅平台管理员。返回全部分发应用。",
        "operationId": "get_listDistributionApps",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Application"
                      }
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": []
      }
    },
    "/v1/admin/distribution/apps/{appKey}": {
      "put": {
        "summary": "registerOrUpdateDistributionApp",
        "description": "仅平台管理员；分发注册独立于 OAuth 注册。幂等更新。",
        "operationId": "put_registerOrUpdateDistributionApp",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object"
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": [
          {
            "name": "appKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplicationInput"
              }
            }
          }
        }
      }
    },
    "/v1/admin/distribution/apps/{appKey}/releases": {
      "get": {
        "summary": "listApplicationReleases",
        "description": "管理员或所属应用发布凭证；包含草稿、已发布和撤回版本。",
        "operationId": "get_listApplicationReleases",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Release"
                      }
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": [
          {
            "name": "appKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "summary": "createReleaseDraft",
        "description": "不可变草稿；优先提交 artifact_id，服务端推导下载URL、SHA256与大小。外部文件提交 download_url+sha256+size_bytes，商店无需哈希/大小。相同 app/platform/arch/channel/build 返回409，不覆盖。允许域名见管理方案文档。",
        "operationId": "post_createReleaseDraft",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object"
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          },
          "409": {
            "description": "相同构建号已存在，读取比对后复用或增加构建号"
          }
        },
        "parameters": [
          {
            "name": "appKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReleaseInput"
              }
            }
          }
        }
      }
    },
    "/v1/admin/distribution/apps/{appKey}/artifacts": {
      "post": {
        "summary": "uploadApplicationArtifact",
        "description": "管理员或所属应用发布凭证。直接二进制流，1字节到90MiB；服务端重新计算SHA-256并严格检查大小。未发布对象私有。",
        "operationId": "post_uploadApplicationArtifact",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "filename": {
                          "type": "string"
                        },
                        "sha256": {
                          "type": "string"
                        },
                        "size_bytes": {
                          "type": "integer"
                        }
                      },
                      "required": []
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": [
          {
            "name": "Content-Length",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 94371840
            }
          },
          {
            "name": "X-File-Name",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,150}\\.(dmg|pkg|msix|exe|msi|apk)$"
            }
          },
          {
            "name": "X-Content-SHA256",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-fA-F0-9]{64}$"
            }
          },
          {
            "name": "appKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        }
      }
    },
    "/v1/admin/distribution/releases/{id}/status": {
      "patch": {
        "summary": "publishOrWithdrawRelease",
        "description": "管理员或此版本所属应用凭证。状态变更可重试；撤回停止平台入口和私有R2对象公开下载，外部链接由外部服务控制。",
        "operationId": "patch_publishOrWithdrawRelease",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object"
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "enum": [
                      "published",
                      "withdrawn"
                    ]
                  }
                },
                "required": [
                  "status"
                ]
              }
            }
          }
        }
      }
    },
    "/v1/admin/distribution-tokens": {
      "get": {
        "summary": "listPublishTokens",
        "description": "仅平台管理员。明文令牌只在创建响应的 data.token 出现，列表只含元数据。凭证仅支持指定应用版本及上传，最长90天。",
        "operationId": "get_listPublishTokens",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "app_key": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "expires_at": {
                            "type": "integer"
                          },
                          "revoked_at": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "created_at": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": []
      },
      "post": {
        "summary": "createScopedPublishToken",
        "description": "仅平台管理员。明文令牌只在创建响应的 data.token 出现，列表只含元数据。凭证仅支持指定应用版本及上传，最长90天。",
        "operationId": "post_createScopedPublishToken",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "token": {
                          "type": "string"
                        },
                        "app_key": {
                          "type": "string"
                        },
                        "expires_at": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "token",
                        "app_key",
                        "expires_at"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenInput"
              }
            }
          }
        }
      }
    },
    "/v1/admin/distribution-tokens/{id}": {
      "delete": {
        "summary": "revokePublishToken",
        "description": "仅平台管理员；幂等撤销。后续使用该令牌返回401。",
        "operationId": "delete_revokePublishToken",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object"
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/distribution/catalog": {
      "get": {
        "summary": "getCompatibleCatalog",
        "description": "公开；每个可见应用只返回匹配系统/CPU/通道的最大构建版本，没有版本时release为null。不授予OAuth权限或Workspace权益。",
        "operationId": "get_getCompatibleCatalog",
        "security": [],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "platform": {
                          "type": "string"
                        },
                        "arch": {
                          "type": "string"
                        },
                        "channel": {
                          "type": "string"
                        },
                        "apps": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "app_key": {
                                "type": "string"
                              },
                              "display_name": {
                                "type": "string"
                              },
                              "summary": {
                                "type": "string"
                              },
                              "category": {
                                "type": "string"
                              },
                              "homepage_url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "release": {
                                "anyOf": [
                                  {
                                    "$ref": "#/components/schemas/Release"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": []
                          }
                        }
                      },
                      "required": []
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "输入或校验失败",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "凭证缺失/过期"
          },
          "403": {
            "description": "权限不足"
          },
          "404": {
            "description": "目标不存在"
          }
        },
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "macos",
                "windows",
                "ios",
                "android"
              ]
            }
          },
          {
            "name": "arch",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "arm64",
                "x64",
                "universal"
              ]
            }
          },
          {
            "name": "os_version",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d+(\\.\\d+){0,3}$"
            }
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "enum": [
                "stable",
                "beta"
              ],
              "default": "stable"
            }
          }
        ]
      }
    },
    "/v1/distribution/releases/{id}/download": {
      "get": {
        "summary": "resolvePublishedDownload",
        "description": "公开；每次重查发布及可见状态，无缓存。已撤回/未发布返回410。",
        "operationId": "get_resolvePublishedDownload",
        "security": [],
        "responses": {
          "410": {
            "description": "版本已撤回或未公开",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "文件不存在"
          },
          "302": {
            "description": "已发布安装包/官方商店URL",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/distribution/artifacts/{id}": {
      "get": {
        "summary": "downloadPublishedArtifact",
        "description": "公开；每次重查发布及可见状态，无缓存。已撤回/未发布返回410。",
        "operationId": "get_downloadPublishedArtifact",
        "security": [],
        "responses": {
          "410": {
            "description": "版本已撤回或未公开",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "文件不存在"
          },
          "200": {
            "description": "安装包字节流",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "平台管理员 access_token 或 ejpub_ 前缀的单应用发布凭证"
      }
    },
    "schemas": {
      "ApplicationInput": {
        "type": "object",
        "properties": {
          "display_name": {
            "type": "string",
            "maxLength": 100
          },
          "summary": {
            "type": "string",
            "maxLength": 500
          },
          "category": {
            "type": "string",
            "maxLength": 40
          },
          "homepage_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "visible": {
            "type": "boolean"
          },
          "sort_order": {
            "type": "integer"
          }
        },
        "required": [
          "display_name",
          "summary",
          "category",
          "visible",
          "sort_order"
        ]
      },
      "Application": {
        "type": "object",
        "properties": {
          "app_key": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]{1,63}$"
          },
          "display_name": {
            "type": "string",
            "maxLength": 100
          },
          "summary": {
            "type": "string",
            "maxLength": 500
          },
          "category": {
            "type": "string",
            "maxLength": 40
          },
          "homepage_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "visible": {
            "type": "integer",
            "enum": [
              0,
              1
            ]
          },
          "sort_order": {
            "type": "integer"
          }
        },
        "required": []
      },
      "Release": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "app_key": {
            "type": "string"
          },
          "platform": {
            "enum": [
              "macos",
              "windows",
              "ios",
              "android"
            ]
          },
          "arch": {
            "enum": [
              "arm64",
              "x64",
              "universal"
            ]
          },
          "channel": {
            "enum": [
              "stable",
              "beta"
            ]
          },
          "version": {
            "type": "string",
            "pattern": "^\\d+\\.\\d+\\.\\d+(?:-[a-zA-Z0-9.-]+)?$"
          },
          "build": {
            "type": "integer",
            "minimum": 1
          },
          "min_os": {
            "type": "string",
            "pattern": "^\\d+(\\.\\d+){0,3}$"
          },
          "package_type": {
            "enum": [
              "dmg",
              "pkg",
              "msix",
              "exe",
              "msi",
              "store",
              "apk"
            ]
          },
          "download_url": {
            "type": "string",
            "format": "uri"
          },
          "sha256": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-f0-9]{64}$"
          },
          "size_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 8589934592
          },
          "install_id": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9._{}-]{3,200}$"
          },
          "release_notes": {
            "type": "string",
            "maxLength": 8000
          },
          "status": {
            "enum": [
              "draft",
              "published",
              "withdrawn"
            ]
          },
          "created_at": {
            "type": "integer"
          },
          "published_at": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": []
      },
      "ReleaseInput": {
        "type": "object",
        "properties": {
          "platform": {
            "enum": [
              "macos",
              "windows",
              "ios",
              "android"
            ]
          },
          "arch": {
            "enum": [
              "arm64",
              "x64",
              "universal"
            ]
          },
          "channel": {
            "enum": [
              "stable",
              "beta"
            ]
          },
          "version": {
            "type": "string",
            "pattern": "^\\d+\\.\\d+\\.\\d+(?:-[a-zA-Z0-9.-]+)?$"
          },
          "build": {
            "type": "integer",
            "minimum": 1
          },
          "min_os": {
            "type": "string",
            "pattern": "^\\d+(\\.\\d+){0,3}$"
          },
          "package_type": {
            "enum": [
              "dmg",
              "pkg",
              "msix",
              "exe",
              "msi",
              "store",
              "apk"
            ]
          },
          "download_url": {
            "type": "string",
            "format": "uri"
          },
          "sha256": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-f0-9]{64}$"
          },
          "size_bytes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 8589934592
          },
          "install_id": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9._{}-]{3,200}$"
          },
          "release_notes": {
            "type": "string",
            "maxLength": 8000
          },
          "artifact_id": {
            "type": "string"
          }
        },
        "required": [
          "platform",
          "arch",
          "channel",
          "version",
          "build",
          "min_os",
          "package_type",
          "install_id",
          "release_notes"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "package_type": {
                  "const": "store"
                }
              }
            },
            "then": {
              "required": [
                "download_url"
              ]
            },
            "else": {
              "anyOf": [
                {
                  "required": [
                    "artifact_id"
                  ]
                },
                {
                  "required": [
                    "download_url",
                    "sha256",
                    "size_bytes"
                  ]
                }
              ]
            }
          }
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "TokenInput": {
        "type": "object",
        "properties": {
          "app_key": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "maxLength": 100
          },
          "expires_in_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 90
          }
        },
        "required": [
          "app_key",
          "label",
          "expires_in_days"
        ]
      }
    }
  }
}
