{
  "openapi": "3.1.0",
  "info": {
    "title": "租户文件选择与NAS归档候选接口",
    "version": "0.2.0",
    "description": "未部署。双入口共用接口；所有身份从认证绑定获取，不接受请求指定owner、源URL或NAS系统路径。只支持复制保留，不授予删除权限。"
  },
  "servers": [],
  "x-deployment-status": "candidate_not_published",
  "x-api-base-path": "/v1/storage",
  "x-runtime-authorization-granted": false,
  "paths": {
    "/files": {
      "get": {
        "operationId": "listOwnFiles",
        "tags": [
          "FileArchive"
        ],
        "x-required-scope": "files:list",
        "security": [
          {
            "ArchiveKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Files"
                }
              }
            }
          },
          "401": {
            "description": "认证失败"
          },
          "404": {
            "description": "不存在或无权访问"
          },
          "409": {
            "description": "版本、配额或同请求绑定冲突"
          },
          "503": {
            "description": "目的地、源或配额证据未就绪"
          }
        },
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
            }
          },
          {
            "name": "directory_id",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
            }
          }
        ]
      }
    },
    "/destinations": {
      "get": {
        "operationId": "listOwnArchiveDestinations",
        "tags": [
          "FileArchive"
        ],
        "x-required-scope": "archive:read",
        "security": [
          {
            "ArchiveKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Destinations"
                }
              }
            }
          },
          "401": {
            "description": "认证失败"
          },
          "404": {
            "description": "不存在或无权访问"
          },
          "409": {
            "description": "版本、配额或同请求绑定冲突"
          },
          "503": {
            "description": "目的地、源或配额证据未就绪"
          }
        }
      }
    },
    "/quota": {
      "get": {
        "operationId": "readOwnStorageQuota",
        "tags": [
          "FileArchive"
        ],
        "x-required-scope": "quota:read",
        "security": [
          {
            "ArchiveKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quota"
                }
              }
            }
          },
          "401": {
            "description": "认证失败"
          },
          "404": {
            "description": "不存在或无权访问"
          },
          "409": {
            "description": "版本、配额或同请求绑定冲突"
          },
          "503": {
            "description": "目的地、源或配额证据未就绪"
          }
        }
      }
    },
    "/archive-jobs": {
      "post": {
        "operationId": "createArchiveJob",
        "tags": [
          "FileArchive"
        ],
        "x-required-scope": "archive:submit",
        "security": [
          {
            "ArchiveKey": []
          }
        ],
        "responses": {
          "202": {
            "description": "已接收；尚未归档完成",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArchiveJob"
                }
              }
            }
          },
          "401": {
            "description": "认证失败"
          },
          "404": {
            "description": "不存在或无权访问"
          },
          "409": {
            "description": "版本、配额或同请求绑定冲突"
          },
          "503": {
            "description": "目的地、源或配额证据未就绪"
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArchiveRequest"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listOwnArchiveJobs",
        "tags": [
          "FileArchive"
        ],
        "security": [
          {
            "ArchiveKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "最近50项本账户任务",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArchiveJobs"
                }
              }
            }
          },
          "401": {
            "description": "密钥无效或已撤销"
          },
          "404": {
            "description": "不存在或不属于本账户"
          },
          "409": {
            "description": "版本、配额或请求绑定冲突"
          },
          "503": {
            "description": "接单关闭、源、扫描或磁盘未就绪"
          }
        }
      }
    },
    "/archive-jobs/{job_id}": {
      "get": {
        "operationId": "readOwnArchiveJob",
        "tags": [
          "FileArchive"
        ],
        "x-required-scope": "archive:read",
        "security": [
          {
            "ArchiveKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArchiveJob"
                }
              }
            }
          },
          "401": {
            "description": "认证失败"
          },
          "404": {
            "description": "不存在或无权访问"
          },
          "409": {
            "description": "版本、配额或同请求绑定冲突"
          },
          "503": {
            "description": "目的地、源或配额证据未就绪"
          }
        },
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
            }
          }
        ]
      }
    },
    "/archive-requests/{request_id}": {
      "get": {
        "operationId": "findOwnArchiveRequest",
        "tags": [
          "FileArchive"
        ],
        "x-required-scope": "archive:read",
        "security": [
          {
            "ArchiveKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArchiveJob"
                }
              }
            }
          },
          "401": {
            "description": "认证失败"
          },
          "404": {
            "description": "不存在或无权访问"
          },
          "409": {
            "description": "版本、配额或同请求绑定冲突"
          },
          "503": {
            "description": "目的地、源或配额证据未就绪"
          }
        },
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/objects/{object_id}": {
      "get": {
        "operationId": "downloadOwnVerifiedArchive",
        "tags": [
          "FileArchive"
        ],
        "security": [
          {
            "ArchiveKey": []
          }
        ],
        "parameters": [
          {
            "name": "object_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "schema": {
              "type": "string",
              "pattern": "^bytes=[0-9]+-[0-9]*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "完整文件；重新读回摘要后使用",
            "headers": {
              "X-Content-SHA256": {
                "schema": {
                  "type": "string"
                }
              },
              "Accept-Ranges": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Length": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Range": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "断点续传；总长及摘要必须与原文件一致",
            "headers": {
              "X-Content-SHA256": {
                "schema": {
                  "type": "string"
                }
              },
              "Accept-Ranges": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Length": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Range": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "密钥无效或已撤销"
          },
          "404": {
            "description": "不存在或不属于本账户"
          },
          "409": {
            "description": "版本、配额或请求绑定冲突"
          },
          "503": {
            "description": "接单关闭、源、扫描或磁盘未就绪"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ArchiveKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "独立文件归档业务凭据；不接受ASR密钥或NAS管理身份。"
      }
    },
    "schemas": {
      "SelectedFile": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "version": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          }
        },
        "required": [
          "file_id",
          "version"
        ]
      },
      "File": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "version": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "enum": [
              "file",
              "directory"
            ]
          },
          "bytes": {
            "type": "integer",
            "minimum": 0
          },
          "upload_complete": {
            "type": "boolean"
          },
          "archivable": {
            "type": "boolean"
          }
        },
        "required": [
          "file_id",
          "version",
          "name",
          "kind",
          "bytes",
          "archivable"
        ]
      },
      "Files": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/File"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "directory_id": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "files",
          "next_cursor",
          "directory_id"
        ]
      },
      "Quota": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "hard_bytes": {
            "type": "integer",
            "minimum": 0
          },
          "hard_files": {
            "type": "integer",
            "minimum": 0
          },
          "used_bytes": {
            "type": "integer",
            "minimum": 0
          },
          "used_files": {
            "type": "integer",
            "minimum": 0
          },
          "reserved_bytes": {
            "type": "integer",
            "minimum": 0
          },
          "reserved_files": {
            "type": "integer",
            "minimum": 0
          },
          "available_bytes": {
            "type": "integer",
            "minimum": 0
          },
          "available_files": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "hard_bytes",
          "hard_files",
          "used_bytes",
          "used_files",
          "reserved_bytes",
          "reserved_files",
          "available_bytes",
          "available_files"
        ]
      },
      "Destination": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "destination_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "name": {
            "type": "string"
          },
          "mode": {
            "const": "copy"
          }
        },
        "required": [
          "destination_id",
          "name",
          "mode"
        ]
      },
      "Destinations": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "destinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Destination"
            }
          }
        },
        "required": [
          "destinations"
        ]
      },
      "ArchiveRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "destination_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "mode": {
            "const": "copy",
            "type": "string"
          },
          "files": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/SelectedFile"
            }
          }
        },
        "required": [
          "destination_id",
          "mode",
          "files"
        ]
      },
      "ArchiveItem": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "file_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "version": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "name": {
            "type": "string"
          },
          "bytes": {
            "type": "integer",
            "minimum": 0
          },
          "state": {
            "enum": [
              "queued",
              "copying",
              "verifying",
              "scanning",
              "publishing",
              "archived",
              "scan_pending",
              "rejected",
              "failed",
              "needs_review"
            ]
          },
          "copied_bytes": {
            "type": "integer",
            "minimum": 0
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "file_id",
          "version",
          "name",
          "bytes",
          "state",
          "copied_bytes",
          "error"
        ]
      },
      "ArchiveJob": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "job_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "destination_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$"
          },
          "mode": {
            "const": "copy"
          },
          "state": {
            "enum": [
              "processing",
              "archived",
              "needs_review",
              "scan_pending",
              "failed"
            ]
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArchiveItem"
            }
          }
        },
        "required": [
          "job_id",
          "request_id",
          "destination_id",
          "mode",
          "state",
          "files"
        ]
      },
      "Error": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string"
          },
          "request_id": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "error",
          "request_id"
        ]
      },
      "ArchiveJobs": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jobs": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/ArchiveJob"
            }
          }
        },
        "required": [
          "jobs"
        ]
      }
    }
  }
}
