Files
photo-live/packages/contracts/src/generated/openapi.d.ts
T
浅念 b0a3515bf2 feat(api): 用户前缀查找并入 displayName——成员添加可按姓名搜人(方案 A)
线上根因:V1.1 账号=手机号,运营按姓名搜索恒空(accountPrefix 仅匹配
account)。扩展为 account OR displayName 前缀(括号分组保资格过滤不被
短路),大小写敏感/激活过滤/account 升序语义不变;与管理列表 query 模式
对齐。契约描述同步。附 members-categories e2e 冷启动超时对齐 120s。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-29 15:20:09 +08:00

6010 lines
230 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* This file was auto-generated by openapi-typescript.
* Do not make direct changes to the file.
*/
export interface paths {
"/auth/password": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 密码登录
* @description 校验账号密码,签发会话令牌。
*/
post: operations["loginWithPassword"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/auth/refresh": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 会话滑动续期
* @description 携带有效 Bearer 令牌滑动续期,返回新的过期时间。
*/
post: operations["refreshSession"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/auth/logout": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 退出登录
* @description 使当前 Bearer 令牌失效。
*/
post: operations["logout"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/auth/password-change": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 修改密码
* @description 已认证用户修改自身密码:校验旧密码,成功后更新密码哈希并撤销该用户
* 除当前会话外的全部其他会话(当前会话保持有效,无需重新登录)。
* P3 Task 3 契约增补(需求 4.1「支持修改密码」,P1 契约缺口补齐)。
*/
post: operations["changePassword"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 相册列表
* @description 当前用户可见(参与)的相册列表;管理员可见全部。按创建时间倒序。
*/
get: operations["listAlbums"];
put?: never;
/**
* 创建相册
* @description 创建相册并写入多语言内容;创建者自动成为 owner 成员。
* 初始默认值:uploadEnabled/publicEnabled/downloadEnabled=true、
* originalDownloadEnabled=false、status=active、watermarkVersion=0。
*/
post: operations["createAlbum"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums/{albumId}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
/**
* 相册详情
* @description 相册完整配置、多语言内容与分类列表。
*/
get: operations["getAlbum"];
put?: never;
post?: never;
/**
* 软删除相册
* @description 标记 status=deleted(软删除):管理端列表与公开端即刻不可见,成员/上传/ 资产等全部子资源随之 404;数据保留(物理删除走独立运维流程),不提供 恢复端点。权限同「配置相册」(公司管理员或相册创建者)。事件走 album.updated(priority=high)同步 ov 副本下线。
*/
delete: operations["deleteAlbum"];
options?: never;
head?: never;
/**
* 更新相册配置
* @description 部分更新:仅提交的字段被修改,各开关互相独立。
* translations 为全量替换(须包含 defaultLocale 对应条目)。
*/
patch: operations["updateAlbum"];
trace?: never;
};
"/albums/{albumId}/watermark-jobs": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
/**
* 水印配置版本与重生成任务状态
* @description 当前生效配置(current,从未配置为 null)与历史任务列表(创建时间倒序)。
* 任务进度(progress/total/failed)供前端轮询;state=failed 的任务可经
* POST 重新发起(按照片粒度幂等续跑)。
*/
get: operations["getWatermarkJobs"];
put?: never;
/**
* 保存水印配置并发起历史重生成
* @description 保存新的水印配置版本(configVersion 递增)并创建历史照片重生成任务
* (A18/A20)。仅创建者或管理员可操作。语义约定:
* 新照片发布默认套用最新版本;历史照片重生成须显式经本端点发起;
* 任务为原子切换——全部照片处理完成前旧浏览图保持可用(失败照片保留
* 旧图,任务可重试);原图(original)永不覆盖。
*/
post: operations["createWatermarkJob"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums/{albumId}/assets": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
/**
* 各类资产当前生效项(管理端现状展示)
* @description 返回每个 (kind, locale) 组合的最新 effective 资产行 + 现签短期 URL (同「替换语义」——同组再上传即整体替换)。未设置的组合不出现; 签名过期重取本端点刷新。权限同相册详情(可见即可读)。
*/
get: operations["listAlbumAssetStatus"];
put?: never;
/**
* 初始化资产上传
* @description 为相册宣传图/封面/Logo 创建上传会话,返回 staging 对象的临时直传凭证
* (凭证结构与照片直传同形)。无 clientTaskId 幂等键:assetId 即一次性会话,
* 失败重试重新初始化即可。替换语义:同一 (kind, locale) 再次上传→新行生效,
* 旧行保留作历史(P1b 无删除端点);公开相册响应始终取该 kind 最新生效行
* (P1a 公开服务已按 latest 实现)。
*/
post: operations["initAlbumAssetUpload"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums/{albumId}/assets/{assetId}/complete": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
/** @description 相册资产 ID。 */
assetId: components["parameters"]["AssetId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 完成资产上传核验
* @description 核验 staging 对象(存在性、字节数与可用完整性信息)后将资产挂到相册生效,
* 并返回短期签名访问 URL。幂等:已核验通过的资产重复调用返回 200
* (URL 重新现签,本端点即签名刷新入口)。
*/
post: operations["completeAlbumAssetUpload"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums/{albumId}/members": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
/**
* 相册成员列表
* @description 相册全部成员(含 owner)。
*/
get: operations["listAlbumMembers"];
put?: never;
/**
* 添加相册成员
* @description 将已开通的同事添加为协作者;仅创建者或管理员可操作。
*/
post: operations["addAlbumMember"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums/{albumId}/members/{userId}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/**
* 移除相册成员
* @description 移除协作者;仅创建者或管理员可操作。不能移除创建者(403)。
* 目标成员不存在时幂等返回 204。
*/
delete: operations["removeAlbumMember"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums/{albumId}/categories": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 创建分类
* @description 在相册下创建分类;仅创建者或管理员可操作。
*/
post: operations["createCategory"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/categories/{categoryId}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 分类 ID。 */
categoryId: components["parameters"]["CategoryId"];
};
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/**
* 删除分类
* @description 删除分类(分类下仍有照片时是否允许删除由服务端策略决定,400 拒绝)。
*/
delete: operations["deleteCategory"];
options?: never;
head?: never;
/**
* 更新分类
* @description 部分更新;translations 为全量替换。
*/
patch: operations["updateCategory"];
trace?: never;
};
"/uploads": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 上传会话记录
* @description 当前用户的上传会话历史(新在前),用于任务队列恢复与状态展示。
*/
get: operations["listUploads"];
put?: never;
/**
* 初始化上传任务
* @description 幂等初始化:预创建上传会话与照片 ID,返回 staging 对象的临时直传凭证。
* 相同 clientTaskId 且参数一致时返回原会话,不重复创建照片;
* 参数不一致时返回 409(UPLOAD_SESSION_CONFLICT)。
*/
post: operations["initUpload"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/uploads/duplicates/check": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 上传查重预检(批量,只读)
* @description 批量查重预检:对每个请求条目判定「同相册 + 同上传者(当前用户)+ 同字节数」
* 的非 deleted 照片是否已存在——判定谓词与 initUpload 的 PHOTO_DUPLICATE
* 查重逐字一致(含 uploaderId 隔离;filename 刻意不参与)。命中条目按请求
* 下标逐项返回(两个请求条目共享同一命中 bytes 时各返回一条)。
* 不校验 uploadEnabled:预检是只读预览,相册关闭上传时仍可查询历史重复
* (init 在真正入队时仍按开关 409 兜底)。
*/
post: operations["checkUploadDuplicates"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/uploads/{uploadId}/renew": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 上传会话 ID。 */
uploadId: components["parameters"]["UploadId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 续签上传凭证
* @description 为仍处于 pending 状态的会话重新签发直传凭证(结构同初始化响应)。
*/
post: operations["renewUploadCredential"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/uploads/{uploadId}/complete": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 上传会话 ID。 */
uploadId: components["parameters"]["UploadId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 完成核验
* @description 核验 staging 对象(存在性、字节数与可用完整性信息)后进入处理流水线。
* 幂等:核验通过的会话重复调用返回相同结果。
*/
post: operations["completeUpload"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums/{albumId}/photos": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
/**
* 管理端照片列表
* @description 相册照片管理列表(区别于公开列表):全部状态可见(unpublished/published/
* hidden/deleted),条目含 uploader 脱敏信息。按 uploadedAt 与 ID 稳定倒序
* 游标分页。
*
* scope(UI-01 可选扩展,缺省 all=既有行为不变):协作者显式查询自己
* 上传的照片——服务端过滤 uploaderId=当前用户,成员资格逐请求校验;
* 仅 owner/admin 可用 all(协作者 all → 403)。条目 preview 按请求者
* 权限逐张裁决(见 PhotoPreview)。
*/
get: operations["listAlbumPhotos"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/albums/{albumId}/photos/hide-batch": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 批量隐藏照片
* @description 批量将 published 照片置为 hidden(A16)。逐项返回结果:不存在、已删除
* 或状态不可切换单项 ok=false 并携带 code,不影响其余项(部分成功语义)。
* 单批上限 200(minItems/maxItems)。权限与 403/404 语义同管理照片列表
* (仅创建者或管理员;ALBUM_NOT_FOUND 防枚举)。
*/
post: operations["hidePhotosBatch"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/photos/{photoId}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/**
* 软删除照片
* @description 标记 deleted(软删除),公开端点即刻不可见;物理删除走独立运维流程。
*/
delete: operations["deletePhoto"];
options?: never;
head?: never;
/**
* 调整照片可见性
* @description 在 hidden 与 published 间切换(隐藏/恢复发布);按相册角色与上传人共同判定权限。
*/
patch: operations["updatePhoto"];
trace?: never;
};
"/admin/albums/{albumId}/transfer": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 相册负责人交接
* @description 将相册 owner 移交给目标用户(A17)。仅 admin 可操作(负责人交接为
* 组织级治理动作,区别于相册级配置修改)。keepAsCollaborator=true 时
* 原 owner 转为 collaborator 成员,否则原 owner 移出成员表。历史上传人
* 不变(photos.uploaderId 不动);审计 album.transfer。
*/
post: operations["transferAlbum"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/users": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 用户查询与管理列表
* @description 双模式统一端点(P4a 决策:与 P1b 账号前缀查询合一,响应统一
* AdminUserList——条目为 AdminUser 字段超集,管理端 UI 按场景裁剪展示):
* · 前缀模式(提供 accountPrefix):邀请协作者前置查询,沿用 P1b 语义
* ——大小写敏感前缀匹配(服务端按二进制校对执行 LIKE prefix%,匹配
* account **或 displayName** 前缀——2026-09-29 扩展:V1.1 账号=手机号,
* 运营按姓名搜人是自然预期)、仅「激活资格」用户(credentialStatus=
* active 且 sourceStatus≠disabled 且 !localLocked,与成员添加的目标
* 校验一致)、account 升序;
* 访问策略沿用 P1b 决策:任何已认证工作人员可用(邀请发起方不限于
* 创建者/管理员,泄露面为已认证内部人员,风险可接受)。
* · 管理列表模式(未提供 accountPrefix):全量用户治理列表(游标分页,
* 按 createdAt 与 ID 稳定倒序),可选 query/status 过滤(不做全文
* 搜索);仅 admin 可用(非 admin 403)。
* 两模式响应形状一致(AdminUserList);前缀模式小上限即取即用,
* hasMore/nextCursor 同样按游标语义填充。
*/
get: operations["listAdminUsers"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/users/{userId}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
get?: never;
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
/**
* 更新用户治理属性
* @description 部分更新 role/localLocked/displayName;仅 admin。sourceStatus 只读
* (上游状态仅由同步任务维护,本地不越权改写——技术方案 3.1A 红线,
* 需求侧只读展示)。localLocked 置 true 等价停用(撤销该用户全部会话);
* 置 false 仅解除本地锁定,不改变上游停用状态。审计全程。
*/
patch: operations["updateAdminUser"];
trace?: never;
};
"/admin/users/{userId}/reset-password": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 管理员重置用户密码
* @description 仅 admin。body 可选 newPassword(8-128):缺省由服务端生成随机密码
* (e2e 两种路径均覆盖)。重置成功后撤销该目标用户全部既有会话(须
* 重新登录);新密码仅在响应中返回一次(不入库明文、不留日志),管理
* 端一次性展示转交。审计全程。
*/
post: operations["resetAdminUserPassword"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/users/{userId}/activate": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 激活待激活用户
* @description 仅 admin。credentialStatus pending→active(闭环用户同步创建的待激活
* 账号,§10 语义)。激活本身不出凭据:初始密码经 reset-password 出具
* (推荐流程 activate → reset-password 生成一次性初始密码 → 用户登录)。
* 幂等:对已是 active 的用户重复激活返回当前条目。
*/
post: operations["activateAdminUser"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/users/{userId}/deactivate": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 停用用户
* @description 仅 admin。localLocked=true 并撤销该用户全部会话(既有令牌即刻 401)。
* 上游状态不动(sourceStatus 保持;上游恢复 active 不解除本地锁定——
* 本地锁定独立,技术方案 3.1A)。重新启用经 PATCH localLocked=false。
* 审计全程。
*/
post: operations["deactivateAdminUser"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/user-sync/status": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 用户同步状态
* @description 仅 admin。同步引擎当前状态、最近批次计数与源水位(A29)。当前为 mock
* 源(G4:真实接口到位后仅替换 provider,契约不变)。
*/
get: operations["getUserSyncStatus"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/user-sync/runs": {
parameters: {
query?: {
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数。 */
limit?: number;
};
header?: never;
path?: never;
cookie?: never;
};
/**
* 同步运行历史
* @description 仅 admin。历史批次列表(startedAt 与 ID 稳定倒序游标分页)。
*/
get: operations["listUserSyncRuns"];
put?: never;
/**
* 手动触发同步补拉
* @description 仅 admin。手动发起一次同步(与定时调度共用互斥锁;已有批次运行中时
* 不重复执行,返回进行中批次的 runId)。202 表示已受理,异步执行,
* 结果经 status/runs 端点查询。
*/
post: operations["triggerUserSyncRun"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/user-sync/errors": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 同步失败明细
* @description 仅 admin。单批次失败行明细(state=partial/failed 批次的坏行记录,
* 其余行照常应用的证据链);runId 必填。
*/
get: operations["listUserSyncErrors"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/usage/summary": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 用量汇总与阈值告警
* @description 仅 admin。按相册聚合存储用量(原图 + 变体,实时 SUM——P1 规模够用;
* P5 接 OSS 用量 API/物化视图,登记偏差)、当前阈值与告警列表
* (A23 后台侧;告警接收人通知渠道 P5)。
*/
get: operations["getUsageSummary"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/usage/thresholds": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
/**
* 更新用量阈值
* @description 仅 admin。部分更新:缺省字段保持不变,显式 null 清除该阈值(清除后
* 对应告警维度停用)。修改后即刻重新评估(超阈产生新告警、阈值上调将
* 已回落旧告警标记 resolvedAt)。
*/
put: operations["updateUsageThresholds"];
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/embed-slots": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 展示位列表
* @description 展示位(悬浮轮播组件挂载点)治理列表,游标分页(按 createdAt 与 ID
* 稳定倒序);仅公司 admin 可用(P4b 权限简化:成员授权面 P5 按需补)。
*/
get: operations["listEmbedSlots"];
put?: never;
/**
* 创建展示位
* @description 创建展示位(仅 admin):服务端生成不可枚举 publicToken(嵌入代码
* data-slot 引用);初始 enabled=true、albumId=null(未绑定,公开端
* 404)、configVersion=1。settings 整体缺省时按各字段缺省值落库。
*/
post: operations["createEmbedSlot"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/embed-slots/{id}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 展示位 ID。 */
id: components["parameters"]["EmbedSlotId"];
};
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/**
* 软删除展示位
* @description 标记 deletedAt(软删除):管理列表隐藏、公开拉取经 enabled=false 快照 同步 ov 后 404(已接入网站停止展示)。数据保留,无恢复端点。 admin 专属;幂等(重复删除 204)。
*/
delete: operations["deleteEmbedSlot"];
options?: never;
head?: never;
/**
* 更新展示位
* @description 展示位部分更新(仅 admin):name/enabled/settings/albumId 任一管理面
* 变更均递增 configVersion 并触发 slot-state 同步事件(嵌入端配置版本
* 变化即整体重置渲染)。albumId 语义:非 null 为绑定/换绑目标相册
* (相册须存在,不存在 404 ALBUM_NOT_FOUND),null 为解绑(公开端随即
* 404);albumId 值本身变化(含换绑与解绑)即视为配置变更。settings
* 为整体替换(提供时字段齐全)。无删除端点:enabled=false 即下线。
*/
patch: operations["updateEmbedSlot"];
trace?: never;
};
"/admin/ads": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* 广告位列表
* @description 广告位治理列表(仅 admin):按 sortOrder 升序、并列 createdAt 升序
* 全量返回(运营量级 <20,不分页);imageUrl 为现签 GET,过期后重拉
* 本列表刷新。albumIds=null 为全局投放。
*/
get: operations["listAdminAds"];
put?: never;
/**
* 创建广告位
* @description 创建广告位(仅 admin):服务端核验 staging 对象(存在 + bytes +
* contentType 与申明一致,banner complete 同口径)后 copyIfAbsent
* 转存版本化终键,落库并写 outbox ad.updated(entityVersion=1)。
* albumIds 未提供或空数组归一为 null(全局投放);元素须为存在的相册
* ID(相册删除不级联清理,容失效见设计 §2.1)。
*/
post: operations["createAd"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/ads/uploads": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 初始化广告图直传
* @description 广告图两步直传第一步(仅 admin):签发 staging 对象的临时直传凭证,
* 键 photo-live/{env}/ads/staging/{cuid}.{ext}。字节上限收紧为 2MB
* (AD_UPLOAD_MAX_BYTES:广告不走变体流水线、原图直出且轮播多张同屏,
* 独立于照片域 UPLOAD_MAX_BYTES 的 50MB,设计 §3);类型白名单
* image/jpeg|png|heic。无会话概念(重复转存由创建端 copyIfAbsent
* 禁止覆盖语义承担)。
*/
post: operations["initAdUpload"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/admin/ads/{adId}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 广告位 ID。 */
adId: components["parameters"]["AdId"];
};
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/**
* 硬删除广告位
* @description 硬删行并写 ad.deleted 墓碑(high 优先级;ov 删 ads_ov 投影行且不被 旧事件复活)。cn 侧数据不保留、无恢复端点;重复删除 404。
*/
delete: operations["deleteAd"];
options?: never;
head?: never;
/**
* 更新广告位
* @description 广告位部分更新(仅 admin):title/linkUrl/enabled/sortOrder/albumIds
* 任一变更递增 entityVersion 并重发整行快照(ad.updated;停用 true→false
* 走 high 优先级)。albumIds:未提供=不动,null=转全局,数组=整体替换;
* 换图时 imageStagingKey/imageBytes/imageContentType 三者必须同时提供
* (核验后转存新版本键,旧对象不回收,OSS 生命周期兜底)。
*/
patch: operations["updateAd"];
trace?: never;
};
"/public/albums/{token}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
};
cookie?: never;
};
/**
* 公开相册信息
* @description 观众页入口:按「请求 locale → defaultLocale」回退解析为单语言对象。
* publicToken 不可枚举,但持有链接者均可访问。
*/
get: operations["getPublicAlbum"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/public/albums/{token}/photos": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
};
cookie?: never;
};
/**
* 公开照片列表
* @description 仅返回公开相册中 published 的照片,按 publishedAt 与 ID 稳定倒序游标分页。
* 签名 URL 为短期凭证,过期后凭同一入口刷新。
*/
get: operations["listPublicPhotos"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/public/albums/{token}/photos/{photoId}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
/**
* 公开单图
* @description 深度链接定位单图,同时作为签名 URL 过期后的刷新入口。
* 服务端校验相册与照片归属;隐藏/删除后的旧链接返回 404。
*/
get: operations["getPublicPhoto"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/public/albums/{token}/ads": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
};
cookie?: never;
};
/**
* 公开广告列表
* @description 观众页相册头部轮播数据(ov 域部署):返回「全局投放(albumIds=null)
* ∨ 绑定本相册」的启用广告,按 sortOrder 升序、并列 createdAt 升序;
* imageUrl 为现签 GET(TTL=SIGNED_URL_TTL_SECONDS)。无广告返回空
* items(非 404)。量级假设广告 ≤ 百条:ads_ov 全表捞 + 应用层过滤,
* 不加独立限速档(与公开相册读同量级,设计 §5.2)。
*/
get: operations["listPublicAds"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/public/embed-slots/{slotToken}": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 展示位公开令牌(不可枚举,持有即可访问;格式见 EmbedSlot.publicToken)。 */
slotToken: components["parameters"]["EmbedSlotToken"];
};
cookie?: never;
};
/**
* 展示位公开数据(嵌入组件数据源)
* @description 悬浮轮播组件的数据源(ov 域部署,匿名只读;嵌入 iframe 轮询调用):
* 返回展示位绑定相册的近期已发布照片(≤20,按 publishedAt 与 ID 稳定
* 倒序,小尺寸缩略图省流量)与相册摘要。lang 语义:auto(缺省)或取值
* 不支持时按相册 defaultLocale 回退(不报 400,与公开相册一致)。
* settings(UI-01)返回后台配置的归一化全集(嵌入端应用后台配置,
* data-* 覆盖优先)。
*
* - 防探测:slotToken 不存在、展示位停用(enabled=false)或未绑定相册
* 一律 404 NOT_FOUND(同码同文案,不区分原因,避免枚举探测)。
* - 条件请求(A23 省流量):200/304 响应携带强 ETag,取值为四元组
* `"{configVersion}-{photoCount}-{maxPublishedAtMs}-{maxPhotoId}"`
* (含照片条数与最新发布时间——新照片发布必变,避免仅比对实体版本
* 时新照片小版本导致 304 陈旧);请求携带 If-None-Match 且匹配时
* 返回 304(无响应体,仍携带 ETag)。
*/
get: operations["getPublicEmbedSlot"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/public/albums/{token}/photos/{photoId}/likes": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 点赞批次上报
* @description 匿名点赞批次(ov 域部署;路径前缀与 cn 相同,按部署域名区分)。
* 客户端将短时间内的多次点击合并为批次提交,delta 为本批新增点赞数。
*
* - 幂等:同一 (photoId, sessionId, batchId) 重复提交返回已确认结果
* (batchAccepted=true、total 为权威累计值),不重复加计;失败重试
* 必须复用同一 batchId。
* - 窗口外过期批次(LIKE_BATCH_WINDOW_HOURS,默认 24h,清理任务保留窗口)
* 拒绝重放:不加计,返回当前权威 total(batchAccepted=false),
* 客户端据此校准本地乐观计数。
* - 基础限速:sessionId+来源 IP 滑窗,超限 429(RATE_LIMITED)。
* - 相册非公开/紧急停用 404(ALBUM_NOT_PUBLIC);照片不存在、未发布、
* 不属于该相册或相册非公开 404(PHOTO_NOT_PUBLIC)。
*/
post: operations["likePhotoBatch"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/public/albums/{token}/visits": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
};
cookie?: never;
};
get?: never;
put?: never;
/**
* 浏览上报
* @description 匿名浏览上报(ov 域部署)。仅由客户端显式调用:页面可见且相册信息
* 加载成功后上报一次(列表/图片/WS 等接口调用一律不触发计数)。
*
* - requestId 为上报幂等键(建议 UUID),counted 确认前跨刷新/重试持久复用;
* 重复 requestId 幂等重放:counted 回显该 requestId 首次处理的结局
* (确认响应丢失后重试仍见 true),viewCount 恒为当前权威值,不重复计数。
* - 去重窗口(VISIT_WINDOW_MINUTES,默认 30 分钟,D07)内同一 visitorId
* 不重复计数;窗口过后再上报按新访次计数。
* - 过期 requestId(VISIT_REQUEST_TTL_MINUTES,默认 35 分钟)拒绝重放
* (counted=false,无论原结局),不得重新加计。
* - 基础限速:visitorId+来源 IP 固定窗(VISIT_WINDOW_REQUESTS,默认
* 60/窗),超限 429(RATE_LIMITED);去重本身为主缓解。
* - 相册非公开/紧急停用 404(ALBUM_NOT_PUBLIC)。
*/
post: operations["reportAlbumVisit"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/public/albums/{token}/photos/{photoId}/download": {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
/**
* 公开照片下载
* @description 匿名下载(ov 域部署,观众动作端点故归 interactions)。按相册两级下载
* 开关校验(A18):variant=browse 需 downloadEnabled;variant=original
* 需 originalDownloadEnabled(在 downloadEnabled 基础上的更高级开关,
* 两者均开才可下载原图)。对应级别开关关闭 → 403 DOWNLOAD_DISABLED;
* 相册/照片不可见 404(ALBUM_NOT_PUBLIC/PHOTO_NOT_PUBLIC,不区分枚举)。
* URL 为短期签名凭证,禁止持久保存/写入分享链接,过期经本端点刷新;
* 服务端日志不记完整签名 URL。
*/
get: operations["downloadPublicPhoto"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/internal/sync/content-batches": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 内容事件批量推送
* @description cn→ov 方向:cn outbox 未投递事件批量推送(默认每 2s 一批、单批
* SYNC_BATCH_SIZE 条;priority=high 的下线/隐藏/删除类事件即时单发)。
* ov 侧语义:eventId 幂等(重复推送忽略)、entityVersion 单调
* (旧版本忽略)、tombstone 墓碑优先(副本删除且不被旧事件复活)、
* 依赖缺失暂存待补。acceptedEventIds 为本批受理(含幂等重复)的事件 ID,
* applied 为实际应用(新版本生效)条数。鉴权见 [internal] tag 描述。
*/
post: operations["syncContentBatches"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/internal/sync/stat-snapshots": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 统计快照回传
* @description ov→cn 方向:ov 侧聚合的统计快照(likes/views 权威累计值,默认每 60s
* 增量回传)。cn 按 statVersion 单调替换副本列(仅更高版本替换、
* 绝不相加),重复回传幂等。kind=likes 时 photoId 必填(照片点赞数);
* kind=views 为相册级浏览数(无 photoId)。鉴权见 [internal] tag 描述。
*/
post: operations["syncStatSnapshots"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/internal/sync/reconcile": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 缺失事件对账
* @description ov 侧按 sync_state 水位向 cn 请求指定实体类型在 sinceVersion 之后
* 的事件清单(albumId 可选过滤;中断恢复=水位重放)。cn 返回按版本
* 升序的事件数组,ov 重放补漏;全量快照(bootstrap)的事件本体也经
* 本通道分批拉取。鉴权见 [internal] tag 描述。
*/
post: operations["syncReconcile"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/internal/sync/bootstrap": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 全量快照引导
* @description ov 冷启动或新建副本时请求 cn 生成当前全量快照事件序列
* (album → categories → assets → photos,含各实体当前 entityVersion)。
* 本端点仅返回事件计数 eventCount 与快照水位 watermark;事件本体经
* 对账通道(/internal/sync/reconcile)以 watermark 为起点分批拉取。
* albumId 缺省表示全部相册。鉴权见 [internal] tag 描述。
*/
post: operations["syncBootstrap"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/internal/sync/digest": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 每相册实体计数摘要
* @description cn 侧权威计数(P2 Task 4):每相册 {categoryCount, publishedPhotoCount,
* photoCount, assetCount}。ov 对账调度定期拉取并与副本计数比对——不一致
* 的相册触发该相册 bootstrap(当前状态快照重发,含分类全量清单整体替换),
* 收敛错过的墓碑与漏掉的事件。albumId 缺省表示全部相册。鉴权见 [internal]
* tag 描述。
*/
post: operations["syncDigest"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/internal/emergency/disable": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 海外紧急停用相册(ov 域)
* @description ov 侧独立于同步链路的紧急停用入口:直接置 albums_ov.emergency_disabled
* =true(ov 本地写,不经同步版本链——后续任何同步事件不得解除,恢复仅经
* /internal/emergency/enable 显式操作)。停用相册在 ov 公开 API/WS 侧按
* 404 ALBUM_NOT_PUBLIC 语义处理;cn 侧不感知(同步照常)。albumToken 与
* albumId 二选一(都缺省 400)。审计:ov 侧结构化日志以 audit=emergency
* 字段标记(P2 决策:不做独立文件通道,P5 运维按字段路由聚合)。
* 鉴权见 [internal] tag 描述。
*/
post: operations["emergencyDisable"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/internal/emergency/enable": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* 解除海外紧急停用(ov 域,显式唯一恢复通道)
* @description 唯一能清除 albums_ov.emergency_disabled 的入口(显式操作,任何同步
* 事件都不会代为解除)。albumToken 与 albumId 二选一(都缺省 400)。
* 审计同 disable(audit=emergency 字段)。鉴权见 [internal] tag 描述。
*/
post: operations["emergencyEnable"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
}
export type webhooks = Record<string, never>;
export interface components {
schemas: {
/**
* @description 稳定错误码(服务器生成,与 src/errors.ts 的 ErrorCodes 一一对应,
* 1:1 类型守护见 __tests__/events.test.ts);P4a 起供批量逐项结果等
* 内嵌失败原因复用。
* @enum {string}
*/
ErrorCode: "AUTH_INVALID_CREDENTIALS" | "AUTH_TOKEN_EXPIRED" | "AUTH_RATE_LIMITED" | "RATE_LIMITED" | "AUTH_FORBIDDEN" | "NOT_FOUND" | "ALBUM_NOT_FOUND" | "ALBUM_NOT_PUBLIC" | "ALBUM_UPLOAD_DISABLED" | "MEMBER_CONFLICT" | "UPLOAD_SESSION_CONFLICT" | "UPLOAD_VERIFY_FAILED" | "PHOTO_NOT_FOUND" | "PHOTO_NOT_PUBLIC" | "DOWNLOAD_DISABLED" | "VALIDATION_FAILED" | "SYNC_AUTH_FAILED" | "INTERNAL_ERROR";
Error: {
code: components["schemas"]["ErrorCode"];
/** @description 服务器生成的可读消息(诊断用,不作为客户端展示文案依据)。 */
readonly message: string;
/** @description 请求追踪 ID。 */
readonly requestId: string;
};
/** @description 游标分页元信息;各列表响应以 allOf 内嵌本结构(条目 schema 在业务端点中定义)。不变式:hasMore=true 当且仅当 nextCursor≠null,两者必须成对填充。 */
CursorPageMeta: {
/** @description 下一页游标;null 表示没有更多数据。 */
readonly nextCursor: string | null;
/** @description 是否还有下一页。 */
readonly hasMore: boolean;
};
/**
* @description P1a 支持的语言。
* @enum {string}
*/
Locale: "zh-CN" | "en";
LoginRequest: {
/** @description 账号(用户名或邮箱)。 */
account: string;
/** @description 密码。 */
password: string;
};
LoginResponse: {
/** @description 会话令牌(Bearer)。 */
readonly sessionToken: string;
/**
* Format: date-time
* @description 会话过期时间。
*/
readonly expiresAt: string;
};
RefreshResponse: {
/**
* Format: date-time
* @description 续期后的过期时间。
*/
readonly expiresAt: string;
};
/** @description 修改密码请求(P3 Task 3 契约增补)。 */
PasswordChangeRequest: {
/** @description 当前密码。 */
oldPassword: string;
/** @description 新密码(至少 8 位)。 */
newPassword: string;
};
/** @description 相册多语言条目(创建/更新与响应共用;未填的可选字段存储为 null)。 */
AlbumTranslation: {
locale: components["schemas"]["Locale"];
/** @description 相册标题。 */
title: string;
/** @description 相册描述。 */
description?: string | null;
/** @description 场地名称。 */
venue?: string | null;
/** @description 场地地址。 */
address?: string | null;
};
AlbumCreateRequest: {
/** @description 多语言内容;必须包含 defaultLocale 对应条目。 */
translations: components["schemas"]["AlbumTranslation"][];
defaultLocale: components["schemas"]["Locale"];
/**
* Format: date-time
* @description 活动开始时间(UTC 存储,展示按 timezone)。
*/
startAt: string;
/**
* Format: date-time
* @description 活动结束时间;null 或缺省表示未定。
*/
endAt?: string | null;
/**
* @description 活动 IANA 时区。
* @default Asia/Shanghai
* @example Asia/Shanghai
*/
timezone: string;
/**
* @description 允许下载浏览版本。
* @default true
*/
downloadEnabled: boolean;
/**
* @description 允许下载原图。
* @default false
*/
originalDownloadEnabled: boolean;
};
/** @description 部分更新:仅提交的字段被修改,各开关互相独立;endAt 传 null 清除。 */
AlbumUpdateRequest: {
/** @description 全量替换多语言内容;须包含 defaultLocale 对应条目。 */
translations?: components["schemas"]["AlbumTranslation"][];
defaultLocale?: components["schemas"]["Locale"];
/**
* Format: date-time
* @description 活动开始时间。
*/
startAt?: string;
/**
* Format: date-time
* @description 活动结束时间;null 清除。
*/
endAt?: string | null;
/** @description 活动 IANA 时区。 */
timezone?: string;
/** @description 是否允许新上传任务。 */
uploadEnabled?: boolean;
/** @description 是否公开可见。 */
publicEnabled?: boolean;
/** @description 允许下载浏览版本。 */
downloadEnabled?: boolean;
/** @description 允许下载原图。 */
originalDownloadEnabled?: boolean;
};
/** @description 相册列表条目(完整开关与多语言标题,管理列表无需二次请求详情)。 */
AlbumSummary: {
/** @description 相册 ID。 */
readonly id: string;
/** @description 公开访问令牌(不可枚举)。 */
readonly publicToken: string;
/** @description 创建者用户 ID。 */
readonly ownerId: string;
/**
* @description 相册状态;offline 表示下线(停止公开访问与新授权签发)。
* @default active
* @enum {string}
*/
readonly status: "active" | "offline" | "deleted";
defaultLocale: components["schemas"]["Locale"];
/** @description 活动 IANA 时区。 */
timezone: string;
/**
* Format: date-time
* @description 活动开始时间。
*/
startAt: string;
/**
* Format: date-time
* @description 活动结束时间;null 表示未定。
*/
endAt: string | null;
/** @description 是否允许新上传任务。 */
uploadEnabled: boolean;
/** @description 是否公开可见。 */
publicEnabled: boolean;
/** @description 允许下载浏览版本。 */
downloadEnabled: boolean;
/** @description 允许下载原图。 */
originalDownloadEnabled: boolean;
/**
* @description 当前水印配置版本。
* @default 0
*/
readonly watermarkVersion: number;
/** @description 各语言内容。 */
translations: components["schemas"]["AlbumTranslation"][];
/**
* Format: date-time
* @description 创建时间。
*/
readonly createdAt: string;
/**
* Format: date-time
* @description 最近更新时间。
*/
readonly updatedAt: string;
/**
* Format: date-time
* @description 统计副本最近同步时间(P2 A27:ov→cn 统计快照在本相册的应用时刻);
* null 表示尚无回传应用(viewCountReplica 副本位仍为初始 0)。照片级
* 点赞副本(PhotoRecord.likeCount)的同步时间不经相册行表达。
*/
readonly statsSyncedAt: string | null;
/**
* @description 相册封面摘要(UI-01,readOnly 可选扩展):当前生效封面资产
* (album_assets kind=cover、state=effective 的最新一行)的短期
* 签名 URL;未配置封面为 null。宣传图/封面共用(2026-09-23 决策):
* 未配置封面时回退最新生效宣传图(传一张即可两用)。列表端点按页
* 批量组装(非逐相册查询);旧客户端忽略本字段不受影响。
*/
readonly cover?: components["schemas"]["SignedUrl"] | null;
};
AlbumList: components["schemas"]["CursorPageMeta"] & {
items: components["schemas"]["AlbumSummary"][];
};
Album: components["schemas"]["AlbumSummary"] & {
/** @description 相册分类(按 sortOrder 升序)。 */
categories: components["schemas"]["Category"][];
};
/**
* @description 水印配置(P4a A18,创建请求与当前配置响应共用)。enabled=false 表示
* 关闭水印(新照片不加水印),其余字段此时被忽略;可选字段缺省用服务端
* 默认值。
*/
WatermarkConfig: {
/** @description 是否开启浏览图水印。 */
enabled: boolean;
/**
* @description 水印位置;缺省服务端默认。
* @enum {string}
*/
position?: "topLeft" | "topRight" | "bottomLeft" | "bottomRight" | "center";
/** @description 不透明度百分比。 */
opacity?: number;
/** @description 水印尺寸相对浏览图宽度的百分比。 */
scalePercent?: number;
/** @description 文字水印参数;缺省不绘制文字。 */
text?: components["schemas"]["WatermarkTextConfig"];
};
/** @description 文字水印参数(SVG 渲染实现,Task 3 登记)。 */
WatermarkTextConfig: {
/** @description 文字内容。 */
content?: string;
/** @description 字号(像素)。 */
fontSize?: number;
};
/** @description 重生成任务受理结果;configVersion 为本次保存的配置版本。 */
WatermarkJobCreated: {
/** @description 重生成任务 ID。 */
readonly jobId: string;
/** @description 本次保存的水印配置版本(新照片即刻套用)。 */
readonly configVersion: number;
};
/**
* @description 重生成任务状态;failed 可重新发起(按照片粒度幂等续跑)。
* @enum {string}
*/
WatermarkJobState: "pending" | "running" | "done" | "failed";
/** @description 历史重生成任务条目(进度供前端轮询)。 */
WatermarkJob: {
/** @description 任务 ID。 */
readonly jobId: string;
/** @description 目标配置版本。 */
readonly configVersion: number;
state: components["schemas"]["WatermarkJobState"];
/** @description 已处理张数(含失败)。 */
readonly progress: number;
/** @description 待处理总张数。 */
readonly total: number;
/** @description 失败张数。 */
readonly failed: number;
/** @description 任务失败原因(state=failed 时必有)。 */
errorCode?: components["schemas"]["ErrorCode"];
/**
* Format: date-time
* @description 任务创建时间。
*/
readonly createdAt: string;
};
/** @description 当前生效的水印配置。 */
WatermarkCurrent: {
/** @description 当前配置版本(同 AlbumSummary.watermarkVersion)。 */
readonly configVersion: number;
config: components["schemas"]["WatermarkConfig"];
};
/** @description 水印配置与任务状态;current 从未配置为 null(watermarkVersion=0)。 */
WatermarkJobsStatus: {
/** @description 当前生效配置;从未配置为 null。 */
current: components["schemas"]["WatermarkCurrent"] | null;
/** @description 历史任务(创建时间倒序)。 */
jobs: components["schemas"]["WatermarkJob"][];
};
/**
* @description 相册资产类型(技术实施方案 §4 album_assets.kind)。banner 为观众页宣传图
* (PublicAlbum.banner,P1b 消费方);cover/logo 建表与上传链路就绪,展示
* 消费随后续阶段。
* @enum {string}
*/
AssetKind: "banner" | "cover" | "logo";
/**
* @description 资产上传初始化请求;大小与类型白名单与照片直传一致(UPLOAD_MAX_BYTES
* 环境策略,逐请求惰性读取)。locale 为可选语言维度:同一 (kind, locale)
* 的再次上传即替换(新行生效);语言无关的资产(如 logo)可不传。
*/
AssetInitRequest: {
kind: components["schemas"]["AssetKind"];
locale?: components["schemas"]["Locale"];
/** @description 原始文件名(仅元数据,不作对象唯一标识)。 */
filename: string;
/**
* Format: int64
* @description 申明文件字节数;完成核验时逐一比对。
*/
bytes: number;
/**
* @description MIME 类型白名单;image/heic 为暂定项,解码能力待 G2 真机验证后确认。
* @enum {string}
*/
contentType: "image/jpeg" | "image/png" | "image/heic";
};
AssetInitResponse: {
/** @description 资产 ID(完成核验的寻址凭据,一次性会话)。 */
readonly assetId: string;
/** @description staging 对象键(photo-live/{env}/albums/{albumId}/assets/{assetId}.{ext})。 */
readonly objectKey: string;
credential: components["schemas"]["UploadCredential"];
};
AssetCompleteResponse: components["schemas"]["SignedUrl"] & {
/** @description 资产 ID。 */
readonly assetId: string;
};
/** @description 单个生效资产(管理端现状展示用)。 */
AssetStatusItem: {
/** @enum {string} */
kind: "banner" | "cover" | "logo";
/** @description 语言标签(banner 可带;null=全局)。 */
locale: string | null;
/** @description 现签短期 GET URL。 */
url: string;
/** Format: date-time */
expiresAt: string;
contentType: string;
/** Format: date-time */
createdAt: string;
};
/** @description 各 (kind, locale) 组合最新生效资产列表。 */
AssetStatusResponse: {
items: components["schemas"]["AssetStatusItem"][];
};
MemberAddRequest: {
/** @description 被添加用户的 ID(须为已开通账号)。 */
userId: string;
/**
* @description 成员角色;P1a 仅协作者(owner 由创建流程产生)。
* @default collaborator
* @enum {string}
*/
role: "collaborator";
};
Member: {
/** @description 用户 ID。 */
readonly userId: string;
/** @description 登录账号。 */
readonly account: string;
/** @description 展示姓名(来自用户资料同步)。 */
readonly displayName: string;
/**
* @description 相册角色。
* @enum {string}
*/
readonly role: "owner" | "collaborator";
/**
* @description 成员状态;P1a 仅 active,预留扩展。
* @enum {string}
*/
readonly status: "active";
};
MemberList: components["schemas"]["CursorPageMeta"] & {
items: components["schemas"]["Member"][];
};
CategoryTranslation: {
locale: components["schemas"]["Locale"];
/** @description 分类名称。 */
name: string;
};
CategoryCreateRequest: {
/**
* @description 排序序号(升序)。
* @default 0
*/
sortOrder: number;
/** @description 分类多语言名称。 */
translations: components["schemas"]["CategoryTranslation"][];
};
/** @description 部分更新;translations 为全量替换。 */
CategoryUpdateRequest: {
/** @description 排序序号(升序)。 */
sortOrder?: number;
/** @description 全量替换多语言名称。 */
translations?: components["schemas"]["CategoryTranslation"][];
};
Category: {
/** @description 分类 ID。 */
readonly id: string;
/** @description 所属相册 ID。 */
readonly albumId: string;
/** @description 排序序号(升序)。 */
sortOrder: number;
/** @description 各语言名称。 */
translations: components["schemas"]["CategoryTranslation"][];
};
/**
* @description 上传会话状态(服务端视角;本地任务状态见技术实施方案 §5.5)。
* 会话没有 failed 状态:完成核验失败属于单次请求错误(UPLOAD_VERIFY_FAILED),
* 会话保持 pending 可重试;cancelled 为用户主动取消;
* expired 为超过 expiresAt 未完成(核验时推导或由补偿扫描落定)。
* @enum {string}
*/
UploadSessionState: "pending" | "confirmed" | "cancelled" | "expired";
/**
* @description 照片服务端处理状态(技术实施方案 §5.5「服务端处理」链路)。
* @enum {string}
*/
PhotoProcessingState: "pending_upload" | "uploaded" | "processing" | "ready" | "processing_failed";
/**
* @description 照片对外可见性(技术实施方案 §5.5「对外可见性」;deleted 为软删除)。
* @enum {string}
*/
PhotoVisibility: "unpublished" | "published" | "hidden" | "deleted";
UploadInitRequest: {
/** @description 目标相册 ID。 */
albumId: string;
/** @description 目标分类 ID;缺省为相册默认分类。 */
categoryId?: string;
/** @description 客户端任务幂等键;同一任务的重试必须复用(会话与照片 ID 均复用)。 */
clientTaskId: string;
/** @description 原始文件名(仅元数据,不作对象唯一标识)。 */
filename: string;
/**
* Format: int64
* @description 申明文件字节数;完成核验时逐一比对。
*/
bytes: number;
/**
* @description MIME 类型白名单;image/heic 为暂定项,解码能力待 G2 真机验证后确认。
* @enum {string}
*/
contentType: "image/jpeg" | "image/png" | "image/heic";
/**
* @description 客户端首次生成并持久化的设备标识;服务端历史返回用于区分上传来源
* (A19)。可选;同一 clientTaskId 幂等重放时保留首次落库的值。
*/
sourceDeviceId?: string;
/**
* @description 跳过服务端查重(P0-1 层 2)。仅相册 owner/admin 可用;协作者
* 传 true 无效。false(缺省)时:同 albumId+uploaderId+bytes
* 已有非 deleted 照片 → 409 PHOTO_DUPLICATE。
* @default false
*/
force: boolean;
};
/** @description staging 对象的临时直传凭证;仅可写入指定 objectKey,不可访问 originals/variants。 */
UploadCredential: {
/**
* @description 凭证模式;P1a 仅预签名 URL,预留 STS 扩展。
* @default presigned
* @enum {string}
*/
readonly mode: "presigned";
/** @description 预签名上传 URL。 */
readonly url: string;
/**
* @description 上传 HTTP 方法。
* @enum {string}
*/
readonly method: "PUT";
/** @description 上传时必须携带的请求头(如 Content-Type)。 */
readonly headers: {
[key: string]: string;
};
/**
* Format: date-time
* @description 凭证过期时间;过期后续签(renew)再重试。
*/
readonly expiresAt: string;
};
UploadInitResponse: {
/** @description 上传会话 ID。 */
readonly uploadId: string;
/** @description 预创建的照片 ID(重试复用,不重复建照片)。 */
readonly photoId: string;
/** @description staging 对象键(photo-live/{env}/staging/{uploadId}/{photoId}.{ext})。 */
readonly objectKey: string;
credential: components["schemas"]["UploadCredential"];
};
UploadCompleteResponse: {
/** @description 照片 ID。 */
readonly photoId: string;
processingState: components["schemas"]["PhotoProcessingState"];
};
/** @description 会话关联照片的当前状态(会话记录内嵌,客户端据此展示服务端进度)。 */
UploadSessionPhoto: {
/** @description 照片 ID。 */
readonly photoId: string;
processingState: components["schemas"]["PhotoProcessingState"];
visibility: components["schemas"]["PhotoVisibility"];
preview?: components["schemas"]["PhotoPreview"];
};
UploadSessionRecord: {
/** @description 上传会话 ID。 */
readonly uploadId: string;
/** @description 目标相册 ID。 */
readonly albumId: string;
/** @description 客户端任务幂等键。 */
readonly clientTaskId: string;
state: components["schemas"]["UploadSessionState"];
/**
* Format: int64
* @description 申明文件字节数。
*/
readonly expectedBytes: number;
/** @description 申明 MIME 类型。 */
readonly contentType: string;
/**
* Format: date-time
* @description 会话创建时间。
*/
readonly createdAt: string;
/**
* @description 发起该上传的设备标识(客户端首次生成并持久化;init 时未携带为 null)。
* P3 Task 3 契约增补(A19 设备来源语义)。
*/
readonly sourceDeviceId?: string | null;
photo: components["schemas"]["UploadSessionPhoto"];
};
UploadSessionList: components["schemas"]["CursorPageMeta"] & {
items: components["schemas"]["UploadSessionRecord"][];
};
/** @description 查重预检请求条目(与 initUpload 入参同形;filename 仅元数据)。 */
UploadDuplicateCheckItem: {
/** @description 原始文件名(仅元数据;查重谓词不使用,与 init 查重一致)。 */
filename: string;
/**
* Format: int64
* @description 申明文件字节数(查重键)。
*/
bytes: number;
};
/** @description 批量查重预检请求;单批上限 500 项,客户端按 500 分块顺序调用。 */
UploadDuplicateCheckRequest: {
/** @description 目标相册 ID。 */
albumId: string;
/** @description 待查重条目(1..500 项)。 */
items: components["schemas"]["UploadDuplicateCheckItem"][];
};
/** @description 单条命中结果;每个命中的「请求条目」一条(index 指向请求数组)。 */
UploadDuplicateCheckDuplicate: {
/** @description 命中条目在请求 items 数组中的下标(0 起)。 */
index: number;
/**
* Format: int64
* @description 命中字节数(与对应请求条目一致)。
*/
bytes: number;
/**
* Format: date-time
* @description 服务端既有照片的上传时间(同 bytes 多条命中取最早)。
*/
uploadedAt: string;
};
/** @description 查重预检结果(命中子集,按请求下标升序)。 */
UploadDuplicateCheckResponse: {
/** @description 命中子集;无命中为空数组。 */
duplicates: components["schemas"]["UploadDuplicateCheckDuplicate"][];
};
PhotoVisibilityUpdateRequest: {
/**
* @description 目标可见性;仅允许 hidden 与 published 间切换。
* @enum {string}
*/
visibility: "hidden" | "published";
};
/** @description 批量隐藏请求(P4a A16);逐项处理,部分成功。 */
PhotoHideBatchRequest: {
/** @description 目标照片 ID 列表(单批上限 200,执行注意约定)。 */
photoIds: string[];
};
/** @description 单项隐藏结果;ok=false 时 code 说明原因(如 PHOTO_NOT_PUBLIC/PHOTO_NOT_FOUND)。 */
BatchHideItem: {
/** @description 照片 ID。 */
readonly photoId: string;
/** @description 本项是否隐藏成功。 */
readonly ok: boolean;
/** @description 失败原因错误码(ok=false 时必有)。 */
code?: components["schemas"]["ErrorCode"];
};
/** @description 批量隐藏结果;results 与请求 photoIds 同序逐项对应。 */
BatchHideResult: {
/** @description 逐项结果(与请求同序)。 */
results: components["schemas"]["BatchHideItem"][];
};
/** @description 管理端照片记录(技术实施方案 §4 photos 表字段)。 */
PhotoRecord: {
/** @description 照片 ID。 */
readonly photoId: string;
/** @description 所属相册 ID。 */
readonly albumId: string;
/** @description 分类 ID;null 表示未分类。 */
readonly categoryId: string | null;
/** @description 上传人用户 ID。 */
readonly uploaderId: string;
visibility: components["schemas"]["PhotoVisibility"];
processingState: components["schemas"]["PhotoProcessingState"];
/**
* Format: int64
* @description 原图字节数。
*/
readonly bytes: number;
/** @description 原图宽度(像素);处理前为 null。 */
readonly width: number | null;
/** @description 原图高度(像素);处理前为 null。 */
readonly height: number | null;
/**
* Format: date-time
* @description 拍摄时间(EXIF);无有效值时为 null。
*/
readonly shotAt: string | null;
/**
* Format: date-time
* @description 上传完成时间。
*/
readonly uploadedAt: string;
/**
* Format: date-time
* @description 发布时间;未发布为 null。
*/
readonly publishedAt: string | null;
/** @description 累计点赞数。 */
readonly likeCount: number;
};
/** @description 管理列表条目内嵌的上传人脱敏信息(不含邮箱、手机等凭据字段)。 */
AdminPhotoUploader: {
/** @description 上传人用户 ID(与 PhotoRecord.uploaderId 一致)。 */
readonly userId: string;
/** @description 登录账号。 */
readonly account: string;
/** @description 展示姓名(来自用户资料)。 */
readonly displayName: string;
};
/**
* @description 管理端照片预览(UI-01,readOnly):thumb/browse 短期签名 URL 与过期
* 时间。签发条件(服务端逐张裁决):请求者有该照片管理权(admin 全部 /
* 相册 owner 本相册全部 / 协作者仅自己上传)且照片有有效变体、未删除;
* 隐藏照片仅 admin/owner 签发。不满足条件时 AdminPhoto.preview 为 null
* (PhotoRecord 本身仍如实返回)。URL 过期后经列表重取刷新。
* 亦用于上传会话历史(UploadSessionPhoto.preview,uploader 本人视角):
* 变体齐备且未隐藏/未删除时签发,否则字段缺省。
*/
PhotoPreview: {
thumb: components["schemas"]["SignedUrl"];
browse: components["schemas"]["SignedUrl"];
};
AdminPhoto: components["schemas"]["PhotoRecord"] & {
uploader: components["schemas"]["AdminPhotoUploader"];
/**
* @description 受权限管理的照片预览(UI-01,readOnly 可选扩展;无变体/已删除/
* 无权签发时为 null)。旧客户端忽略本字段不受影响。
*/
readonly preview?: components["schemas"]["PhotoPreview"] | null;
};
AdminPhotoList: components["schemas"]["CursorPageMeta"] & {
items: components["schemas"]["AdminPhoto"][];
};
/** @description 相册负责人交接请求(A17)。 */
AlbumTransferRequest: {
/** @description 新 owner 用户 ID(须为可被指定为 owner 的账号,见端点 400 说明)。 */
targetUserId: string;
/** @description 原 owner 是否保留为 collaborator;false 时移出成员表。 */
keepAsCollaborator: boolean;
};
/**
* @description 用户治理条目(P4a;不含邮箱/手机/密码等凭据字段)。sourceStatus 只读
* 展示(上游状态仅同步任务维护)。id 用于邀请协作者
* (POST /albums/{albumId}/members 的 userId)。
*/
AdminUser: {
/** @description 用户 ID。 */
readonly id: string;
/** @description 登录账号。 */
readonly account: string;
/** @description 展示姓名。 */
readonly displayName: string;
/**
* @description 公司角色(staff/admin;相册角色另表)。
* @enum {string}
*/
readonly role: "staff" | "admin";
/**
* @description 来源状态:local=本地创建;active/disabled=同步源状态(P4a 同步)。
* @enum {string}
*/
readonly sourceStatus: "local" | "active" | "disabled";
/** @description 本地锁定(停用/deactivate 置 true;与上游状态独立)。 */
readonly localLocked: boolean;
/**
* @description 凭据状态:active=可登录;pending=同步创建待激活(不可登录,待管理员激活并出初始凭据)。
* @enum {string}
*/
readonly credentialStatus: "active" | "pending";
/** @description 界面语言偏好;未设置为 null。 */
readonly locale?: string | null;
/**
* Format: date-time
* @description 创建时间。
*/
readonly createdAt: string;
/**
* @description 同步源档案快照(G4:工号/邮箱/公司/头像,来自用户同步、落
* external_user_mappings.profile 列);本地创建/未同步用户为 null。
* 纯展示维度,不参与任何治理判定。
*/
readonly synced?: {
/** @description 工号。 */
sn?: string;
/** @description 企业邮箱。 */
email?: string;
/** @description 公司全称。 */
companyName?: string;
/** @description 公司简称。 */
companyAbbr?: string;
/** @description 头像 URL。 */
avatar?: string;
} | null;
};
AdminUserList: components["schemas"]["CursorPageMeta"] & {
/** @description 用户条目(前缀模式按 account 升序且仅激活资格用户;管理列表模式按 createdAt 与 ID 稳定倒序)。 */
items: components["schemas"]["AdminUser"][];
/** @description 过滤命中总数——仅管理列表 page 模式返回;游标/前缀模式为 null。 */
total?: number | null;
};
/**
* @description 管理列表治理状态过滤(单值归类):pending=待激活;disabled=上游停用;
* locked=本地锁定;active=其余可正常登录。同时命中多状态时按
* pending > disabled > locked > active 优先级归类后匹配。
* @enum {string}
*/
AdminUserStatusFilter: "active" | "pending" | "disabled" | "locked";
/** @description 用户治理属性部分更新(仅提交的字段被修改;sourceStatus 不在可更新集)。 */
AdminUserUpdateRequest: {
/**
* @description 公司角色。
* @enum {string}
*/
role?: "staff" | "admin";
/** @description 本地锁定;置 true 撤销该用户全部会话。 */
localLocked?: boolean;
/** @description 展示姓名。 */
displayName?: string;
};
/** @description 管理员重置密码请求;newPassword 缺省由服务端生成随机密码。 */
AdminPasswordResetRequest: {
/** @description 指定新密码(至少 8 位);缺省服务端生成。 */
newPassword?: string;
};
/** @description 重置结果;newPassword 仅此一次返回(请求指定或服务端生成)。 */
AdminPasswordResetResponse: {
/** @description 重置后的密码(一次性展示,转交用户后不再可见)。 */
readonly newPassword: string;
};
/**
* @description 同步引擎状态:idle=空闲/从未运行;其余为最近批次结局。
* @enum {string}
*/
UserSyncState: "idle" | "running" | "success" | "partial" | "failed";
/**
* @description 批次状态(partial=部分行失败,其余行照常应用)。
* @enum {string}
*/
UserSyncRunState: "running" | "success" | "partial" | "failed";
/** @description 批次计数。 */
UserSyncCounts: {
/** @description 新增用户数(建为待激活)。 */
added: number;
/** @description 幂等更新数(改名等)。 */
updated: number;
/** @description 上游停用数(撤会话)。 */
disabled: number;
/** @description 失败行数(明细见 /admin/user-sync/errors)。 */
failed: number;
};
/** @description 用户同步引擎状态(A29;mock 源先行,G4 后仅替换 provider)。 */
UserSyncStatus: {
/**
* Format: date-time
* @description 最近批次开始时间;从未运行为 null。
*/
readonly lastRunAt?: string | null;
/**
* Format: date-time
* @description 最近完全成功批次开始时间;从未成功为 null。
*/
readonly lastSuccessAt?: string | null;
state: components["schemas"]["UserSyncState"];
/**
* Format: int64
* @description 已提交的源水位(版本游标);从未同步为 null。
*/
readonly sourceVersion?: number | null;
/** @description 最近批次计数;从未运行为 null。 */
counts?: components["schemas"]["UserSyncCounts"] | null;
};
/** @description 同步批次条目。 */
UserSyncRun: {
/** @description 批次 ID。 */
readonly id: string;
/**
* @description 触发方式(定时/手动补拉)。
* @enum {string}
*/
readonly trigger: "cron" | "manual";
state: components["schemas"]["UserSyncRunState"];
/**
* Format: int64
* @description 本批次已提交的源水位(同步游标,非分页游标);未提交为 null。
*/
readonly cursor?: number | null;
counts: components["schemas"]["UserSyncCounts"];
/**
* Format: date-time
* @description 批次开始时间。
*/
readonly startedAt: string;
/**
* Format: date-time
* @description 批次结束时间;运行中为 null。
*/
readonly finishedAt?: string | null;
/** @description 批次级失败摘要;无为 null。 */
readonly error?: string | null;
};
UserSyncRunList: components["schemas"]["CursorPageMeta"] & {
/** @description 批次列表(startedAt 与 ID 稳定倒序)。 */
items: components["schemas"]["UserSyncRun"][];
};
/** @description 手动触发受理结果。 */
UserSyncRunCreated: {
/** @description 批次 ID(已有批次运行中时为该进行中批次)。 */
readonly runId: string;
};
/** @description 同步失败行明细(坏行记录,其余行照常应用的证据链)。 */
UserSyncError: {
/** @description 归属批次 ID。 */
readonly runId: string;
/** @description 上游用户标识。 */
readonly externalUserId: string;
/** @description 失败分类码(provider 级约定,如 upstream_timeout/invalid_record)。 */
readonly code: string;
/** @description 失败详情(诊断用)。 */
readonly detail: string;
/**
* Format: date-time
* @description 记录时间。
*/
readonly createdAt: string;
};
/** @description 失败明细列表(createdAt 倒序;无游标即取即用)。 */
UserSyncErrorList: {
items: components["schemas"]["UserSyncError"][];
};
/** @description 单相册用量聚合(实时 SUM;P5 换物化/OSS 用量,登记偏差)。 */
UsageAlbum: {
/** @description 相册 ID。 */
readonly albumId: string;
/** @description 相册标题(defaultLocale 解析)。 */
readonly title: string;
/** @description 照片总数(全部状态)。 */
readonly photoCount: number;
/**
* Format: int64
* @description 原图存储字节数。
*/
readonly originalBytes: number;
/**
* Format: int64
* @description 变体(缩略/浏览/水印等)存储字节数。
*/
readonly variantBytes: number;
/**
* Format: int64
* @description 合计字节数(originalBytes + variantBytes)。
*/
readonly totalBytes: number;
};
/** @description 全库用量合计。 */
UsageTotals: {
/** @description 照片总数。 */
readonly photoCount: number;
/**
* Format: int64
* @description 存储总字节数。
*/
readonly totalBytes: number;
};
/** @description 用量阈值;null 表示该维度未设置(告警停用)。 */
UsageThresholds: {
/**
* Format: int64
* @description 全库存储阈值。
*/
readonly storageBytes: number | null;
/**
* Format: int64
* @description 单相册存储阈值。
*/
readonly perAlbumBytes: number | null;
};
/** @description 阈值更新请求;字段缺省=保持不变,显式 null=清除该阈值。 */
UsageThresholdsUpdate: {
/**
* Format: int64
* @description 全库存储阈值;null 清除。
*/
storageBytes?: number | null;
/**
* Format: int64
* @description 单相册存储阈值;null 清除。
*/
perAlbumBytes?: number | null;
};
/**
* @description 阈值告警(A23 后台侧;接收人通知渠道 P5)。超阈写入一次直到回落
* (同 kind+albumId 活跃告警唯一——重复告警去重);resolvedAt 非空为
* 已解除。
*/
UsageAlert: {
/** @description 告警 ID。 */
readonly id: string;
/**
* @description 告警维度。
* @enum {string}
*/
readonly kind: "storage" | "perAlbum";
/** @description 相册 ID;kind=perAlbum 必有,storage 为 null。 */
readonly albumId?: string | null;
/** @description 告警描述。 */
readonly message: string;
/**
* Format: date-time
* @description 产生时间。
*/
readonly createdAt: string;
/**
* Format: date-time
* @description 解除时间(阈值上调/用量回落时标记);活跃告警为 null。
*/
readonly resolvedAt?: string | null;
};
/** @description 用量汇总(A23 后台侧)。 */
UsageSummary: {
/** @description 相册用量(按 totalBytes 降序)。 */
albums: components["schemas"]["UsageAlbum"][];
totals: components["schemas"]["UsageTotals"];
thresholds: components["schemas"]["UsageThresholds"];
/** @description 告警列表(createdAt 倒序,含已解除)。 */
alerts: components["schemas"]["UsageAlert"][];
};
/**
* @description 展示位内容语言(设置与公开查询共用):auto=按相册 defaultLocale,
* 其余为指定语言(取值不支持时服务端静默回退相册 defaultLocale)。
* @enum {string}
*/
EmbedSlotLang: "auto" | "zh-CN" | "en";
/**
* @description 展示位展示设置。整体提交语义:创建时 settings 可整体缺省(各字段按
* 下列缺省值落库),提供时字段齐全;更新为整体替换(未单独提交
* settings 则保持不变)。响应中字段恒齐全。UI-01 新增字段
* (imageFit/offsetX/offsetBottom/zIndex)为可选扩展:提交时可缺省
* (按默认值归一化落库),旧 JSON/旧客户端零影响;响应恒为归一化全集。
*/
EmbedSlotSettings: {
/**
* @description 悬浮位置(宿主页面左/右侧)。
* @default right
* @enum {string}
*/
position: "left" | "right";
/**
* @description 组件尺寸(sm=窄屏降级档,宿主 viewport<480px 时自动降为 sm)。
* @default md
* @enum {string}
*/
size: "sm" | "md";
/**
* @description 轮播切换间隔毫秒。
* @default 5000
*/
intervalMs: number;
lang: components["schemas"]["EmbedSlotLang"];
/**
* @description 初始是否收起(收起后仅展示小把手,点击展开)。
* @default false
*/
collapsedDefault: boolean;
/**
* @description 轮播图片适配方式(UI-01):contain=完整展示于 4:3 舞台(中性底);
* cover=裁切填满舞台。可缺省(默认 contain)。
* @default contain
* @enum {string}
*/
imageFit: "contain" | "cover";
/**
* @description 组件距宿主页面边缘的水平偏移(像素,UI-01)。可缺省。
* @default 16
*/
offsetX: number;
/**
* @description 组件距宿主页面底部的垂直偏移(像素,UI-01)。可缺省。
* @default 24
*/
offsetBottom: number;
/**
* @description 组件在宿主页面的层级(UI-01)。可缺省。
* @default 1000
*/
zIndex: number;
/**
* @description 展示模式(UI-04):carousel=旧版轮播(v1 loader,footer/舞台结构);
* vertical-stream=新版垂直照片流(v2 loader,固定 195×280 连续上滚照片窗,
* 忽略 size/intervalMs/imageFit 的布局作用)。可缺省(默认 carousel——
* UI-04 前旧记录读取归一为旧模式;新建走 v2 由管理端显式提交)。
* @default carousel
* @enum {string}
*/
displayMode: "carousel" | "vertical-stream";
/**
* @description vertical-stream 自动上滚速度(CSS px/秒,UI-04)。可缺省(默认 16);
* 仅 v2 生效,carousel 模式忽略。
* @default 16
*/
scrollSpeed: number;
/**
* @description vertical-stream 点赞心形气泡开关(UI-04)。可缺省(默认 true);
* false 仅隐藏气泡(不产生 WS 订阅),照片滚动不受影响。仅 v2 生效。
* @default true
*/
reactionsEnabled: boolean;
};
/**
* @description 展示位条目(管理视角)。albumId/albumTitle 为当前绑定相册(null=未
* 绑定,公开端 404);albumTitle 按相册 defaultLocale 解析(管理列表
* 展示用)。任一管理面变更递增 configVersion。
*/
EmbedSlot: {
/** @description 展示位 ID。 */
readonly id: string;
/** @description 展示位公开令牌(嵌入代码 data-slot 引用,不可枚举)。 */
readonly publicToken: string;
/** @description 展示位名称(管理标识)。 */
name: string;
/** @description 是否启用;false 即下线(公开端 404,等同删除语义)。 */
enabled: boolean;
/** @description 绑定相册 ID;未绑定为 null。 */
readonly albumId: string | null;
/** @description 绑定相册标题(按相册 defaultLocale 解析);未绑定为 null。 */
readonly albumTitle: string | null;
/** @description 配置版本(任一管理面变更递增;嵌入端据此整体重置渲染,亦为公开端 ETag 组成部分)。 */
readonly configVersion: number;
settings: components["schemas"]["EmbedSlotSettings"];
/**
* Format: date-time
* @description 最近更新时间。
*/
readonly updatedAt: string;
};
EmbedSlotList: components["schemas"]["CursorPageMeta"] & {
/** @description 展示位条目(按 createdAt 与 ID 稳定倒序)。 */
items: components["schemas"]["EmbedSlot"][];
};
/** @description 创建展示位请求;settings 可整体缺省(各字段按缺省值落库),提供时字段齐全。 */
EmbedSlotCreateRequest: {
/** @description 展示位名称。 */
name: string;
settings?: components["schemas"]["EmbedSlotSettings"];
};
/**
* @description 展示位部分更新请求(仅提交的字段被修改,空请求体 400)。settings 为
* 整体替换(提供时字段齐全);albumId:非 null 绑定/换绑目标相册(相册
* 须存在),null 解绑(公开端随即 404)——albumId 值变化即 configVersion+1。
*/
EmbedSlotUpdateRequest: {
/** @description 展示位名称。 */
name?: string;
/** @description 启停;false 即下线(软停用,无删除端点)。 */
enabled?: boolean;
settings?: components["schemas"]["EmbedSlotSettings"];
/** @description 绑定相册 ID;null 解绑。 */
albumId?: string | null;
};
/**
* @description 广告位条目(管理视角)。albumIds 为绑定相册 ID 列表(null=全局投放,
* 空数组归一为 null);imageUrl 为现签 GET(TTL=SIGNED_URL_TTL_SECONDS),
* 过期后重拉列表刷新。
*/
AdminAdItem: {
/** @description 广告位 ID。 */
readonly id: string;
/** @description 后台备注名(不展示观众)。 */
title: string | null;
/** @description 版本化终键(换图递增版本,禁止覆盖)。 */
readonly imageObjectKey: string;
/** @description 现签 GET(TTL=SIGNED_URL_TTL_SECONDS)。 */
readonly imageUrl: string;
/** @description 跳转链接(观众点击新开标签)。 */
linkUrl: string;
/** @description 是否启用;false 公开端不可见(ov 投影行删除,无墓碑下线)。 */
enabled: boolean;
/** @description 排序权重(升序,并列按 createdAt 升序决胜)。 */
sortOrder: number;
/** @description 绑定相册 ID 列表;null=全局投放(未绑定)。 */
albumIds: string[] | null;
/**
* Format: date-time
* @description 创建时间。
*/
readonly createdAt: string;
/**
* Format: date-time
* @description 最近更新时间。
*/
readonly updatedAt: string;
};
/** @description 广告位列表(全量不分页;sortOrder 升序、并列 createdAt 升序)。 */
AdminAdListResponse: {
items: components["schemas"]["AdminAdItem"][];
};
/**
* @description 创建广告位请求;albumIds 未提供或空数组=全局投放(落库归一 null),
* 元素须为存在的相册 ID(去重后校验)。
*/
AdCreateRequest: {
/** @description 后台备注名(不展示观众)。 */
title?: string;
/** @description 跳转链接(http/https)。 */
linkUrl: string;
/** @description POST /admin/ads/uploads 返回的 staging 对象键。 */
imageStagingKey: string;
/** @description 申明字节数(须与 staging 对象一致;上限 AD_UPLOAD_MAX_BYTES=2MB)。 */
imageBytes: number;
/**
* @description 申明类型(须与 staging 对象一致);heic 除外:广告无变体流水线、原图直出,桌面浏览器(Chromium/Firefox)不渲染。
* @enum {string}
*/
imageContentType: "image/jpeg" | "image/png";
/** @description 排序权重(缺省 0)。 */
sortOrder?: number;
/** @description 绑定相册 ID 列表;未提供或空=全局。 */
albumIds?: string[];
};
/**
* @description 部分更新请求(仅提交的字段被修改,空请求体 400 VALIDATION_FAILED,
* 对照 EmbedSlotUpdateRequest 口径)。albumIds:未提供=不动,null=转
* 全局,数组=整体替换;imageStagingKey/imageBytes/imageContentType 三者
* 必须同时提供(换图,服务端核验 staging 后转存新版本键)。
*/
AdUpdateRequest: {
/** @description 后台备注名(不展示观众)。 */
title?: string;
/** @description 跳转链接(http/https)。 */
linkUrl?: string;
/** @description 启停;false 公开端不可见(停用事件走 high 优先级)。 */
enabled?: boolean;
/** @description 排序权重。 */
sortOrder?: number;
/** @description 绑定相册 ID 列表;null=转全局,数组=整体替换。 */
albumIds?: string[] | null;
/** @description 换图用 staging 对象键(与 imageBytes/imageContentType 同时提供)。 */
imageStagingKey?: string;
/** @description 换图申明字节数(上限 AD_UPLOAD_MAX_BYTES=2MB)。 */
imageBytes?: number;
/**
* @description 换图申明类型;heic 除外(同 AdCreateRequest.imageContentType:广告无变体流水线,桌面浏览器不渲染)。
* @enum {string}
*/
imageContentType?: "image/jpeg" | "image/png";
};
/** @description 广告图直传初始化请求(无会话概念,幂等由创建端 copyIfAbsent 承担)。 */
AdUploadInitRequest: {
/** @description 原始文件名(取扩展名定 staging 键)。 */
filename: string;
/** @description 申明字节数(上限 AD_UPLOAD_MAX_BYTES=2MB,超限 400)。 */
bytes: number;
/**
* @description MIME 类型白名单;heic 除外:广告无变体流水线、原图直出,桌面浏览器(Chromium/Firefox)不渲染。
* @enum {string}
*/
contentType: "image/jpeg" | "image/png";
};
AdUploadInitResponse: {
/** @description staging 键 photo-live/{env}/ads/staging/{cuid}.{ext}(创建/更新时引用)。 */
readonly objectKey: string;
credential: components["schemas"]["UploadCredential"];
};
/** @description 私有对象的短期签名 URL;不得写入持久分享链接,过期后经原入口刷新。 */
SignedUrl: {
/** @description 签名访问 URL。 */
readonly url: string;
/**
* Format: date-time
* @description URL 失效时间。
*/
readonly expiresAt: string;
};
/** @description 按请求 locale 回退解析后的单语言相册内容(locale 为实际返回语言)。 */
PublicAlbumTranslation: {
locale: components["schemas"]["Locale"];
/** @description 相册标题。 */
title: string;
/** @description 相册描述;无内容为 null。 */
description: string | null;
/** @description 场地名称;无内容为 null。 */
venue: string | null;
/** @description 场地地址;无内容为 null。 */
address: string | null;
};
/** @description 公开分类(名称已按请求 locale 回退解析)。 */
PublicCategory: {
/** @description 分类 ID。 */
readonly id: string;
/** @description 分类名称。 */
readonly name: string;
/** @description 排序序号(升序)。 */
readonly sortOrder: number;
};
/** @description 观众端相册信息(不泄露工作人员信息与内部存储键)。 */
PublicAlbum: {
/** @description 相册公开令牌。 */
readonly publicToken: string;
resolvedLocale: components["schemas"]["Locale"];
defaultLocale: components["schemas"]["Locale"];
/** @description 活动 IANA 时区(展示用,不随请求语言变化)。 */
readonly timezone: string;
/**
* Format: date-time
* @description 活动开始时间(UTC,客户端按时区格式化)。
*/
readonly startAt: string;
/**
* Format: date-time
* @description 活动结束时间;未定为 null。
*/
readonly endAt: string | null;
translation: components["schemas"]["PublicAlbumTranslation"];
/** @description 分类列表(按 sortOrder 升序)。 */
categories: components["schemas"]["PublicCategory"][];
/**
* @description 宣传图签名 URL;未设置为 null。宣传图/封面共用(2026-09-23 决策):
* 未配置宣传图时回退最新生效封面(传一张即可两用)。
*/
banner: components["schemas"]["SignedUrl"] | null;
/**
* Format: int64
* @description 累计浏览数。cn 部署返回 null(P1a 占位,Task 9 起由统计副本回填);
* ov 部署返回 album_stats 权威累计值(无行默认 0;计数由 /visits
* 端点维护,技术实施方案 §7.1)。
*/
readonly viewCount: number | null;
/**
* @description 浏览图下载开关(P4a Task 4 / A18):false 时观众端不出现下载入口,
* download 端点 browse/original 均 403 DOWNLOAD_DISABLED。
*/
readonly downloadEnabled: boolean;
/**
* @description 原图下载开关(更高级:需与 downloadEnabled 同时开启才允许
* variant=original;单独开启不生效——两级级联语义)。
*/
readonly originalDownloadEnabled: boolean;
};
/** @description 公开照片条目(仅 published 照片,处理完成即有宽高;URL 为短期签名,需在过期前刷新)。 */
PublicPhoto: {
/** @description 照片 ID。 */
readonly photoId: string;
/** @description 浏览图宽度(像素);用于列表占位,减少加载跳动。 */
readonly width: number;
/** @description 浏览图高度(像素)。 */
readonly height: number;
thumb: components["schemas"]["SignedUrl"];
browse: components["schemas"]["SignedUrl"];
/** @description 累计点赞数。 */
readonly likeCount: number;
/**
* Format: date-time
* @description 发布时间(列表排序依据)。
*/
readonly publishedAt: string;
};
PublicPhotoDetail: components["schemas"]["PublicPhoto"] & {
/** @description 所属分类 ID;未分类为 null。 */
readonly categoryId: string | null;
};
PublicPhotoList: components["schemas"]["CursorPageMeta"] & {
items: components["schemas"]["PublicPhoto"][];
};
/** @description 展示位绑定相册摘要(title 已按 lang→相册 defaultLocale 回退解析)。 */
PublicEmbedAlbum: {
/** @description 相册公开令牌(点击照片跳转 viewer 相册页用)。 */
readonly publicToken: string;
/** @description 相册标题(实际返回语言)。 */
readonly title: string;
defaultLocale: components["schemas"]["Locale"];
};
/**
* @description 展示位照片条目(小尺寸缩略图省流量,与公开列表的 browse 大图区分;
* 签名 URL 为短期凭证,过期后经本端点刷新)。
*/
PublicEmbedPhoto: {
/** @description 照片 ID(跳转 viewer 单图定位用)。 */
readonly photoId: string;
thumb: components["schemas"]["SignedUrl"];
/** @description 缩略图宽度(像素);用于占位,减少加载跳动。 */
readonly width: number;
/** @description 缩略图高度(像素)。 */
readonly height: number;
};
/**
* @description 展示位公开数据(嵌入组件数据源;ov 只读副本)。photos 为近期已发布
* 照片,按 publishedAt 与 ID 稳定倒序,上限 20(空数组=相册暂无已发布
* 照片,嵌入端展示空态卡)。album 当前恒非 null(未绑定/停用的展示位
* 公开端一律 404 防探测);null 为契约前瞻保留,嵌入端按空态处理。
* settings(UI-01 可选扩展)为后台配置的归一化全集(缺字段按默认值
* 补齐)——嵌入端据此应用后台配置,data-* 覆盖优先于它。
*/
PublicEmbedSlot: {
/** @description 展示位公开令牌(回显请求路径)。 */
readonly slotToken: string;
/** @description 配置版本(嵌入端变更检测:版本变化即整体重置渲染)。 */
readonly configVersion: number;
/**
* @description 展示设置(UI-01 可选扩展;ov 副本 JSON 按契约默认值归一化后返回,
* 恒为全集)。旧客户端忽略本字段不受影响。
*/
readonly settings?: components["schemas"]["EmbedSlotSettings"];
/** @description 绑定相册摘要;未绑定为 null(当前部署不会出现,见 schema 描述)。 */
album: components["schemas"]["PublicEmbedAlbum"] | null;
/** @description 近期照片(publishedAt 与 ID 稳定倒序,小尺寸缩略图)。 */
photos: components["schemas"]["PublicEmbedPhoto"][];
};
/** @description 观众端广告条目(仅展示所需字段,广告标识与关闭由前端渲染)。 */
PublicAd: {
/** @description 广告位 ID。 */
readonly adId: string;
/** @description 现签 GET(TTL=SIGNED_URL_TTL_SECONDS,过期后重拉本端点刷新)。 */
readonly imageUrl: string;
/** @description 跳转链接(新开标签)。 */
linkUrl: string;
};
/** @description 公开广告列表(无广告为空 items,非 404)。 */
PublicAdListResponse: {
items: components["schemas"]["PublicAd"][];
};
/**
* @description 下载版本(P4a A18):browse=当前生效浏览图(水印版);
* original=原图(需 originalDownloadEnabled 更高级开关)。
* @enum {string}
*/
DownloadVariant: "browse" | "original";
PublicPhotoDownload: components["schemas"]["SignedUrl"] & {
variant: components["schemas"]["DownloadVariant"];
};
/**
* @description 点赞批次上报请求。sessionId 为客户端生成的会话随机标识(会话期间复用);
* batchId 为批次幂等键,同一批的失败重试必须复用,跨批次不得复用。
*/
LikeBatchRequest: {
/** @description 会话标识(客户端随机生成,会话期间复用)。 */
sessionId: string;
/** @description 批次幂等键;同批重试复用,重复提交不加计。 */
batchId: string;
/** @description 本批新增点赞数(客户端短窗合并后的累计点击数)。 */
delta: number;
};
/**
* @description 点赞批次处理结果。total 恒为服务端权威累计值;batchAccepted 区分
* 本批是否被计入(幂等重复=true;窗口外过期批次=false 且不加计)。
*/
LikeBatchResponse: {
/**
* Format: int64
* @description 照片权威累计点赞数(客户端据此校准乐观计数)。
*/
readonly total: number;
/** @description 计数版本(单调递增,实时消息与校准的乱序判别依据)。 */
readonly countVersion: number;
/**
* @description 本批是否被计入:true=新批次或幂等重放已确认批次;
* false=窗口外过期批次(拒绝重放,返回权威 total)。
*/
readonly batchAccepted: boolean;
};
/**
* @description 浏览上报请求。visitorId 跨标签页共享(同一访客);requestId 为本次
* 访次的上报幂等键(建议 UUID),counted 确认前持久复用。
*/
VisitReportRequest: {
/** @description 访客标识(客户端持久化并在标签页间共享)。 */
visitorId: string;
/** @description 上报幂等键;重复提交不重复计数。 */
requestId: string;
};
/** @description 浏览上报结果。viewCount 恒为相册权威累计浏览数。 */
VisitReportResponse: {
/**
* Format: int64
* @description 相册权威累计浏览数。
*/
readonly viewCount: number;
/**
* @description 本次是否计入:true=新访次,或幂等重放已确认计入的 requestId
* (回显原结局);false=去重窗口内重复或过期 requestId 重放
* (均不重复计数)。
*/
readonly counted: boolean;
};
/**
* @description 同步实体类型(slot-state 为预留给后续阶段)。
* @enum {string}
*/
SyncEntityType: "album" | "category" | "photo" | "asset" | "slot-state" | "ad";
/**
* @description 推送优先级:high 为相册下线、照片隐藏/删除等需即时生效的事件
* (发送器即发,不等批间隔);normal 走常规批量推送。
* @enum {string}
*/
SyncPriority: "normal" | "high";
/**
* @description cn→ov 内容同步事件(线格式)。与 cn outbox 事件(src/events.ts)
* 一一对应:eventId 幂等、entityVersion 单调、tombstone 墓碑优先。
* payload 为实体类型相关载荷(album.updated 携带 translations/开关/
* banner 对象键,photo.* 携带对象键与宽高等展示字段)。
*/
SyncEvent: {
/** @description 事件 ID(全局唯一,接收方幂等键)。 */
eventId: string;
/** @description 载荷 schema 版本;当前为 1。 */
schemaVersion: number;
entityType: components["schemas"]["SyncEntityType"];
/** @description 实体 ID(albumId/categoryId/photoId/assetId 等)。 */
entityId: string;
/** @description 归属相册 ID(album 实体时与 entityId 相同)。 */
albumId: string;
/**
* Format: int64
* @description 实体版本(单调递增;接收方仅应用更高版本)。
*/
entityVersion: number;
/**
* @description 墓碑标记:true 表示实体删除,副本删除且不被旧事件复活。
* @default false
*/
tombstone: boolean;
priority: components["schemas"]["SyncPriority"];
/** @description 实体类型相关载荷;结构由发送方按 schemaVersion 约定。 */
payload: {
[key: string]: unknown;
};
};
/** @description 内容事件批量推送请求体。 */
ContentBatchRequest: {
/** @description 事件批次(单批上限对齐 SYNC_BATCH_SIZE,默认 100)。 */
batch: components["schemas"]["SyncEvent"][];
};
/** @description 批量推送受理结果。 */
ContentBatchResponse: {
/** @description 本批受理的事件 ID(含此前已应用的同 eventId 幂等重复)。 */
acceptedEventIds: string[];
/** @description 本批实际应用(新版本生效)的条数。 */
applied: number;
};
/**
* @description 统计快照种类。
* @enum {string}
*/
SyncStatKind: "likes" | "views";
/**
* @description ov→cn 统计快照:权威累计值的版本化替换单元(cn 侧仅更高 statVersion
* 替换副本列,绝不相加)。
*/
StatSnapshot: {
/** @description 照片 ID;kind=likes 时必填,kind=views 无此字段。 */
photoId?: string;
/** @description 归属相册 ID。 */
albumId: string;
kind: components["schemas"]["SyncStatKind"];
/**
* Format: int64
* @description 权威累计值(点赞数或浏览数)。
*/
total: number;
/**
* Format: int64
* @description 统计版本(单调递增;接收方幂等与替换依据)。
*/
statVersion: number;
/** @description 快照来源标识(如 ov)。 */
source: string;
/**
* Format: date-time
* @description 快照确认时间。
*/
confirmedAt: string;
};
/** @description 统计快照回传请求体。 */
StatSnapshotRequest: {
/** @description 增量快照批次。 */
snapshots: components["schemas"]["StatSnapshot"][];
};
/** @description 快照回传受理结果。 */
StatSnapshotResponse: {
/** @description 接受(应用或幂等确认)的快照条数;旧版本被忽略的不计。 */
accepted: number;
};
/** @description 对账拉取请求:某实体类型在 sinceVersion 之后的事件清单。 */
ReconcileRequest: {
entityType: components["schemas"]["SyncEntityType"];
/** @description 可选:限定单相册;缺省为该实体类型全部。 */
albumId?: string;
/**
* Format: int64
* @description 起始版本(exclusive;0 表示从头拉取,配合 bootstrap)。
*/
sinceVersion: number;
/**
* @description 本批拉取上限(分批重放,对齐 SYNC_BATCH_SIZE)。
* @default 100
*/
limit: number;
};
/**
* @description 对账结果:按 entityVersion 升序的**当前状态事件**(可直接重放的完整
* SyncEvent,非仅版本清单——P2 Task 4 设计决策:重放走既有
* content-batches 管道,无需第二条拉取通道;sinceVersion 之后无实体时为
* 空数组)。
*/
ReconcileResponse: {
/** @description 当前状态事件(升序);请求方按序经 content-batches 重放。 */
events: components["schemas"]["SyncEvent"][];
};
/** @description 全量快照引导请求。 */
BootstrapRequest: {
/** @description 指定相册;缺省为全部相册。 */
albumId?: string;
};
/** @description 全量快照规模与水位;事件本体经 reconcile 通道分批拉取。 */
BootstrapResponse: {
/** @description 快照事件总数(供拉取分批与完成校验)。 */
eventCount: number;
/**
* Format: int64
* @description 快照水位:后续增量对账的 sinceVersion 起点。
*/
watermark: number;
};
/** @description 对账摘要请求(P2 Task 4)。 */
DigestRequest: {
/** @description 指定相册;缺省为全部相册。 */
albumId?: string;
};
/**
* @description 单相册权威计数摘要。ov 侧比对口径:albums_ov.categories 元素数应等于
* categoryCount;photos_ov 行数落在 [publishedPhotoCount, photoCount]
* 区间内即视为一致(hidden/deleted 照片若从未以 published 态同步过,ov
* 合法地无行——缺席即撤下语义);相册行缺失即不一致。assetCount 供观测
* (ov 无 asset 副本行,不参与比对)。
*/
AlbumDigest: {
/** @description 相册 ID。 */
albumId: string;
/** @description 当前分类数(cn 权威行数)。 */
categoryCount: number;
/** @description 可见(published)照片数——ov 必须持有的副本行数下界。 */
publishedPhotoCount: number;
/** @description published+hidden+deleted 照片总数——ov 副本行数上界。 */
photoCount: number;
/** @description 生效(effective)资产数(观测用;ov 无 asset 副本行)。 */
assetCount: number;
};
/** @description 每相册计数摘要(albumId 升序)。 */
DigestResponse: {
/** @description 相册摘要清单;空库为空数组。 */
albums: components["schemas"]["AlbumDigest"][];
};
/** @description 紧急停用请求(albumToken 与 albumId 恰好提供其一)。 */
EmergencyDisableRequest: {
/** @description 公开令牌定位相册(与 albumId 二选一)。 */
albumToken?: string;
/** @description 相册 ID 定位(与 albumToken 二选一)。 */
albumId?: string;
/** @description 停用原因(审计留痕)。 */
reason: string;
};
/** @description 解除停用请求(albumToken 与 albumId 恰好提供其一)。 */
EmergencyEnableRequest: {
/** @description 公开令牌定位相册(与 albumId 二选一)。 */
albumToken?: string;
/** @description 相册 ID 定位(与 albumToken 二选一)。 */
albumId?: string;
};
/** @description 紧急停用通道操作结果。 */
EmergencyStatus: {
/** @description 操作后的停用状态(disable 恒 true / enable 恒 false)。 */
disabled: boolean;
/** @description 相册 ID。 */
albumId: string;
};
};
responses: {
/** @description 未认证:令牌缺失、无效或已过期(AUTH_TOKEN_EXPIRED)。 */
Unauthorized: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 服务器内部错误(INTERNAL_ERROR)。 */
InternalError: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
};
parameters: {
/** @description 相册 ID。 */
AlbumId: string;
/** @description 用户 ID。 */
UserId: string;
/** @description 分类 ID。 */
CategoryId: string;
/** @description 相册资产 ID。 */
AssetId: string;
/** @description 上传会话 ID。 */
UploadId: string;
/** @description 照片 ID。 */
PhotoId: string;
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
AlbumPublicToken: string;
/** @description 展示位 ID。 */
EmbedSlotId: string;
/** @description 展示位公开令牌(不可枚举,持有即可访问;格式见 EmbedSlot.publicToken)。 */
EmbedSlotToken: string;
/** @description 广告位 ID。 */
AdId: string;
/** @description 分页游标(上一页响应的 nextCursor)。 */
CursorQuery: string;
/** @description 请求语言;缺省或取值不支持时按相册 defaultLocale 回退(不报 400,响应 resolvedLocale 指示实际返回语言)。 */
LocaleQuery: components["schemas"]["Locale"];
};
requestBodies: never;
headers: never;
pathItems: never;
}
export type $defs = Record<string, never>;
export interface operations {
loginWithPassword: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["LoginRequest"];
};
};
responses: {
/** @description 登录成功,返回会话令牌与过期时间。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["LoginResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED,经全局校验管道)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 账号或密码错误(AUTH_INVALID_CREDENTIALS)。 */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/**
* @description 登录失败次数过多(AUTH_RATE_LIMITED,Task 13 契约修订)。
* 同账号+来源 IP 在窗口期内连续失败达到阈值后锁定一段时间。
*/
429: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
refreshSession: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 续期成功。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["RefreshResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED,经全局校验管道)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
500: components["responses"]["InternalError"];
};
};
logout: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 已退出,无响应体。 */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
/** @description 请求体不可解析(VALIDATION_FAILED,经全局校验管道)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
500: components["responses"]["InternalError"];
};
};
changePassword: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["PasswordChangeRequest"];
};
};
responses: {
/** @description 修改成功,无响应体;当前会话保留,其他会话已撤销。 */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
/** @description 参数校验失败(VALIDATION_FAILED,经全局校验管道)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 旧密码错误(AUTH_INVALID_CREDENTIALS)。 */
401: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listAlbums: {
parameters: {
query?: {
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数。 */
limit?: number;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 相册列表页。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AlbumList"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
500: components["responses"]["InternalError"];
};
};
createAlbum: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["AlbumCreateRequest"];
};
};
responses: {
/** @description 相册已创建(新相册 categories 为空数组)。 */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Album"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
500: components["responses"]["InternalError"];
};
};
getAlbum: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 相册详情。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Album"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 相册不存在,或当前用户非成员不可见(ALBUM_NOT_FOUND,避免枚举)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
deleteAlbum: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 已删除(幂等:重复删除同样 204)。 */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
401: components["responses"]["Unauthorized"];
/** @description 无「配置相册」权限(仅创建者或管理员,AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在(ALBUM_NOT_FOUND,含已删除)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
};
};
updateAlbum: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["AlbumUpdateRequest"];
};
};
responses: {
/** @description 更新后的相册详情。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Album"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅创建者或管理员可修改(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
getWatermarkJobs: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 当前配置与任务列表。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["WatermarkJobsStatus"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅创建者或管理员可查看(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
createWatermarkJob: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["WatermarkConfig"];
};
};
responses: {
/** @description 配置已保存、重生成任务已受理(异步执行,进度经 GET 查询)。 */
202: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["WatermarkJobCreated"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED;opacity/scalePercent/fontSize 越界等)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅创建者或管理员可管理水印(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listAlbumAssetStatus: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 生效资产列表(可能为空数组)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AssetStatusResponse"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 相册不存在(ALBUM_NOT_FOUND,含已删除)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
};
};
initAlbumAssetUpload: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["AssetInitRequest"];
};
};
responses: {
/** @description 资产上传会话已创建。 */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AssetInitResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED):文件超过大小限额或类型不接受。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅创建者或管理员可管理资产(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
completeAlbumAssetUpload: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
/** @description 相册资产 ID。 */
assetId: components["parameters"]["AssetId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 核验通过,资产已生效。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AssetCompleteResponse"];
};
};
/**
* @description 核验失败(UPLOAD_VERIFY_FAILED):对象缺失、字节数与申明不符
* 或完整性信息不可用。
*/
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 资产不存在或无权操作(AUTH_FORBIDDEN,不区分以避免枚举)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listAlbumMembers: {
parameters: {
query?: {
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数。 */
limit?: number;
};
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 成员列表页。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["MemberList"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
addAlbumMember: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["MemberAddRequest"];
};
};
responses: {
/** @description 成员已添加。 */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Member"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅创建者或管理员可管理成员(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 该用户已是相册成员(MEMBER_CONFLICT)。 */
409: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
removeAlbumMember: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 已移除,无响应体。 */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
401: components["responses"]["Unauthorized"];
/** @description 无管理权限,或试图移除创建者(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
createCategory: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["CategoryCreateRequest"];
};
};
responses: {
/** @description 分类已创建。 */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Category"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅创建者或管理员可管理分类(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
deleteCategory: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 分类 ID。 */
categoryId: components["parameters"]["CategoryId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 已删除,无响应体。 */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
401: components["responses"]["Unauthorized"];
/** @description 无所属相册的管理权限(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 分类不存在,或所属相册不存在/不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
updateCategory: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 分类 ID。 */
categoryId: components["parameters"]["CategoryId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["CategoryUpdateRequest"];
};
};
responses: {
/** @description 更新后的分类。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Category"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 无所属相册的管理权限(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 分类不存在,或所属相册不存在/不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listUploads: {
parameters: {
query?: {
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数。 */
limit?: number;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 会话记录列表页。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UploadSessionList"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
500: components["responses"]["InternalError"];
};
};
initUpload: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["UploadInitRequest"];
};
};
responses: {
/** @description 上传会话已创建(幂等重复调用返回原会话)。 */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UploadInitResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED):文件超过大小限额或类型不接受。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 无该相册的上传权限(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/**
* @description 相册已关闭上传(ALBUM_UPLOAD_DISABLED),或同 clientTaskId 已存在
* 且参数不一致(UPLOAD_SESSION_CONFLICT)。
*/
409: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
checkUploadDuplicates: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["UploadDuplicateCheckRequest"];
};
};
responses: {
/** @description 查重结果(命中子集;无命中时 duplicates 为空数组)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UploadDuplicateCheckResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED):items 为空/超 500 项或条目字段非法。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 无该相册的上传权限(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不可见或不存在(ALBUM_NOT_FOUND,不区分以避免枚举)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
renewUploadCredential: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 上传会话 ID。 */
uploadId: components["parameters"]["UploadId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 新凭证已签发(credential 为新值,其余字段回显原会话)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UploadInitResponse"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 无权操作该会话或会话不存在(AUTH_FORBIDDEN,不区分以避免枚举)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/**
* @description 相册已关闭上传(ALBUM_UPLOAD_DISABLED),或会话状态不允许续签
* (已完成/取消/过期,UPLOAD_SESSION_CONFLICT)。
*/
409: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
completeUpload: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 上传会话 ID。 */
uploadId: components["parameters"]["UploadId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 核验通过,照片进入处理流水线。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UploadCompleteResponse"];
};
};
/**
* @description 核验失败(UPLOAD_VERIFY_FAILED):对象缺失、字节数与申明不符
* 或完整性信息不可用。
*/
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 无权操作该会话或会话不存在(AUTH_FORBIDDEN,不区分以避免枚举)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 会话状态不允许完成(已取消或已过期,UPLOAD_SESSION_CONFLICT)。 */
409: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listAlbumPhotos: {
parameters: {
query?: {
/** @description 可见性过滤;缺省为全部状态。 */
visibility?: components["schemas"]["PhotoVisibility"];
/** @description 分类 ID 过滤。 */
categoryId?: string;
/**
* @description 数据范围(UI-01):all=本相册全部照片(缺省,仅 owner/admin);
* own=仅当前用户上传(任何有效成员,服务端过滤)。
*/
scope?: "all" | "own";
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数。 */
limit?: number;
};
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 管理照片列表页。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminPhotoList"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/**
* @description 仅创建者或管理员可访问全量管理列表(scope=all 或缺省时协作者
* AUTH_FORBIDDEN);scope=own 需相册有效成员。
*/
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
hidePhotosBatch: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["PhotoHideBatchRequest"];
};
};
responses: {
/** @description 批量处理结果(逐项;单项失败不影响其余项)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["BatchHideResult"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED;photoIds 空/超 200/含空串)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅创建者或管理员可管理照片(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
deletePhoto: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 已软删除,无响应体。 */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
401: components["responses"]["Unauthorized"];
/** @description 无该照片的管理权限(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 照片不存在(PHOTO_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
updatePhoto: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["PhotoVisibilityUpdateRequest"];
};
};
responses: {
/** @description 更新后的照片记录。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PhotoRecord"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED,visibility 取值非法)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 无该照片的管理权限(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 照片不存在(PHOTO_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
transferAlbum: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册 ID。 */
albumId: components["parameters"]["AlbumId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["AlbumTransferRequest"];
};
};
responses: {
/** @description 交接后的相册详情(ownerId 已变更)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Album"];
};
};
/**
* @description 参数校验失败(VALIDATION_FAILED;targetUserId 非法,或目标账号
* 不可被指定为 owner——不存在/停用/待激活/锁定)。
*/
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可交接相册负责人(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listAdminUsers: {
parameters: {
query?: {
/** @description 账号或姓名前缀(≥2 字符以防过宽匹配;提供即进入前缀模式;大小写敏感——中文姓名无大小写语义)。 */
accountPrefix?: string;
/**
* @description 管理列表过滤:账号或展示名前缀(大小写敏感二进制前缀匹配,同
* accountPrefix 规则;不做全文搜索)。
*/
query?: string;
/** @description 管理列表过滤:治理状态单值归类(归类优先级见 AdminUserStatusFilter)。 */
status?: components["schemas"]["AdminUserStatusFilter"];
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数(游标模式)。 */
limit?: number;
/**
* @description 页码(偏移分页模式):提供 page 且不带 cursor 时启用,响应返回
* total 且 nextCursor=null / hasMore=false(翻页由 total 驱动)。
* 未提供 → 游标模式(keyset,兼容旧客户端);提供 cursor 时忽略
* page。仅管理列表模式有意义。
*/
page?: number;
/** @description 偏移分页每页条数(仅 page 模式生效,缺省 20)。 */
pageSize?: number;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 用户列表页(前缀模式无匹配为空数组)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminUserList"];
};
};
/**
* @description 查询参数校验失败(VALIDATION_FAILED;accountPrefix/query 长度非法、
* status 取值非法、cursor/limit 非法)。
*/
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 管理列表模式仅 admin 可用(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
updateAdminUser: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["AdminUserUpdateRequest"];
};
};
responses: {
/** @description 更新后的用户条目。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminUser"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED;role 取值非法、displayName 长度非法、空请求体)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理用户(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 目标用户不存在(NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
resetAdminUserPassword: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody?: {
content: {
"application/json": components["schemas"]["AdminPasswordResetRequest"];
};
};
responses: {
/** @description 重置成功(newPassword 为请求指定或服务端生成)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminPasswordResetResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED;newPassword 长度非法)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可重置密码(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 目标用户不存在(NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
activateAdminUser: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 激活后的用户条目(credentialStatus=active)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminUser"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可激活用户(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 目标用户不存在(NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
deactivateAdminUser: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 用户 ID。 */
userId: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 停用后的用户条目(localLocked=true)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminUser"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可停用用户(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 目标用户不存在(NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
getUserSyncStatus: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 同步状态。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UserSyncStatus"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可查看同步状态(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listUserSyncRuns: {
parameters: {
query?: {
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数。 */
limit?: number;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 运行历史页。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UserSyncRunList"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED;cursor/limit 非法)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可查看运行历史(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
triggerUserSyncRun: {
parameters: {
query?: {
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数。 */
limit?: number;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 已受理(或复用进行中批次)。 */
202: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UserSyncRunCreated"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可手动触发(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listUserSyncErrors: {
parameters: {
query: {
/** @description 批次 ID。 */
runId: string;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 失败明细(createdAt 倒序;无失败为空数组)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UserSyncErrorList"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED;runId 缺失)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可查看失败明细(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
getUsageSummary: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 用量汇总。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UsageSummary"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可查看用量(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
updateUsageThresholds: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["UsageThresholdsUpdate"];
};
};
responses: {
/** @description 更新后的阈值。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["UsageThresholds"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED;负值或非整数)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可更新阈值(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listEmbedSlots: {
parameters: {
query?: {
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页条数。 */
limit?: number;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 展示位列表页。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EmbedSlotList"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED;cursor/limit 非法)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理展示位(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
createEmbedSlot: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["EmbedSlotCreateRequest"];
};
};
responses: {
/** @description 创建后的展示位条目。 */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EmbedSlot"];
};
};
/** @description 请求体校验失败(VALIDATION_FAILED;name 长度非法、settings 字段越界或取值非法)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理展示位(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
deleteEmbedSlot: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 展示位 ID。 */
id: components["parameters"]["EmbedSlotId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 已删除(幂等)。 */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
401: components["responses"]["Unauthorized"];
/** @description 非管理员(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 展示位不存在(EMBED_SLOT_NOT_FOUND,含已删除)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
};
};
updateEmbedSlot: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 展示位 ID。 */
id: components["parameters"]["EmbedSlotId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["EmbedSlotUpdateRequest"];
};
};
responses: {
/** @description 更新后的展示位条目。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EmbedSlot"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED;name 长度非法、settings 字段越界或取值非法、空请求体)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理展示位(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 展示位不存在(NOT_FOUND),或绑定目标相册不存在(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listAdminAds: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 广告位列表(全量)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminAdListResponse"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理广告位(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
createAd: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["AdCreateRequest"];
};
};
responses: {
/** @description 创建后的广告位条目。 */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminAdItem"];
};
};
/**
* @description 参数校验失败:linkUrl 非 http(s)/超长、albumIds 含不存在的相册
* (VALIDATION_FAILED),或 staging 核验失败——对象缺失/字节或类型
* 与申明不一致(UPLOAD_VERIFY_FAILED)。
*/
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理广告位(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
initAdUpload: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["AdUploadInitRequest"];
};
};
responses: {
/** @description staging 对象键与临时直传凭证。 */
201: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdUploadInitResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED):超过 2MB 限额、类型不接受或文件名扩展名非法。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理广告位(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
deleteAd: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 广告位 ID。 */
adId: components["parameters"]["AdId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 已删除。 */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理广告位(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 广告位不存在(NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
};
};
updateAd: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 广告位 ID。 */
adId: components["parameters"]["AdId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["AdUpdateRequest"];
};
};
responses: {
/** @description 更新后的广告位条目。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["AdminAdItem"];
};
};
/**
* @description 参数校验失败(VALIDATION_FAILED):字段非法、空请求体、换图三字段
* 未同时提供或 staging 核验失败(UPLOAD_VERIFY_FAILED)。
*/
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
401: components["responses"]["Unauthorized"];
/** @description 仅 admin 可管理广告位(AUTH_FORBIDDEN)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 广告位不存在(NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
getPublicAlbum: {
parameters: {
query?: {
/** @description 请求语言;缺省或取值不支持时按相册 defaultLocale 回退(不报 400,响应 resolvedLocale 指示实际返回语言)。 */
locale?: components["parameters"]["LocaleQuery"];
};
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 相册公开信息。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PublicAlbum"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED;locale 取值不支持时不报错,按 defaultLocale 回退)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在或未公开(ALBUM_NOT_PUBLIC,不区分以避免枚举)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listPublicPhotos: {
parameters: {
query?: {
/** @description 分类 ID 过滤(来自 PublicAlbum.categories 的 id)。 */
category?: string;
/**
* @description 排序模式:latest=发布时间倒序(缺省);hot=点赞数倒序(photoId 倒序
* 决胜,短期快照语义——服务端约 30s 缓冲,窗口内顺序不随点赞变化,
* 技术实施方案 §7)。hot 仅 ov 部署实现;cn 部署不感知该参数(固定
* latest 语义)。ov 部署对非法取值返回 400 VALIDATION_FAILED。
*/
sort?: "latest" | "hot";
/** @description 请求语言;缺省或取值不支持时按相册 defaultLocale 回退(不报 400,响应 resolvedLocale 指示实际返回语言)。 */
locale?: components["parameters"]["LocaleQuery"];
/** @description 分页游标(上一页响应的 nextCursor)。 */
cursor?: components["parameters"]["CursorQuery"];
/** @description 每页张数(技术实施方案 §7 建议 30-60)。 */
limit?: number;
};
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 公开照片列表页。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PublicPhotoList"];
};
};
/** @description 查询参数校验失败(category/cursor/limit;locale 取值不支持时不报错,按 defaultLocale 回退)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在或未公开(ALBUM_NOT_PUBLIC,不区分以避免枚举)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
getPublicPhoto: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 单图信息(含新签名的 thumb/browse URL)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PublicPhotoDetail"];
};
};
/**
* @description 相册不存在或未公开(ALBUM_NOT_PUBLIC),或照片不存在、未发布、
* 不属于该相册(PHOTO_NOT_PUBLIC)。
*/
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
listPublicAds: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 公开广告列表(可为空数组)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PublicAdListResponse"];
};
};
/** @description 相册不存在或未公开(ALBUM_NOT_PUBLIC,不区分以避免枚举)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
getPublicEmbedSlot: {
parameters: {
query?: {
/** @description 内容语言;auto(缺省)按相册 defaultLocale,取值不支持时静默回退(不报 400)。 */
lang?: components["schemas"]["EmbedSlotLang"];
};
header?: {
/** @description 条件请求:先前响应返回的 ETag 值;匹配则返回 304。 */
"If-None-Match"?: string;
};
path: {
/** @description 展示位公开令牌(不可枚举,持有即可访问;格式见 EmbedSlot.publicToken)。 */
slotToken: components["parameters"]["EmbedSlotToken"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 展示位公开数据。 */
200: {
headers: {
/** @description 强校验器(组成与失效语义见端点 description)。 */
ETag?: string;
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PublicEmbedSlot"];
};
};
/** @description 内容未变(If-None-Match 匹配);无响应体。 */
304: {
headers: {
/** @description 当前 ETag(与匹配值一致)。 */
ETag?: string;
[name: string]: unknown;
};
content?: never;
};
/** @description 查询参数校验失败(VALIDATION_FAILED;lang 取值不支持时不报错,按相册 defaultLocale 回退)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 展示位不存在、已停用或未绑定相册(NOT_FOUND;不区分以避免枚举)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
likePhotoBatch: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["LikeBatchRequest"];
};
};
responses: {
/**
* @description 本批处理结果(含被拒绝的过期批次——拒绝也返回 200 与权威 total,
* 语义由 batchAccepted 表达,避免客户端把重放当失败重试)。
*/
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["LikeBatchResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED;delta 越界 1..20 或字段长度非法)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/**
* @description 相册不存在或未公开(ALBUM_NOT_PUBLIC),或照片不存在、未发布、
* 不属于该相册(PHOTO_NOT_PUBLIC)。
*/
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 基础限速触发(RATE_LIMITED;sessionId+IP 滑窗)。 */
429: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
reportAlbumVisit: {
parameters: {
query?: never;
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["VisitReportRequest"];
};
};
responses: {
/** @description 上报结果(窗口内重复/重复 requestId/过期重放均 200 + counted=false)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["VisitReportResponse"];
};
};
/** @description 参数校验失败(VALIDATION_FAILED;visitorId/requestId 长度非法)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册不存在或未公开(ALBUM_NOT_PUBLIC)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 基础限速触发(RATE_LIMITED;visitorId 滑窗)。 */
429: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
downloadPublicPhoto: {
parameters: {
query: {
/** @description 下载版本。 */
variant: components["schemas"]["DownloadVariant"];
};
header?: never;
path: {
/** @description 相册公开令牌(不可枚举,持有即可访问)。 */
token: components["parameters"]["AlbumPublicToken"];
/** @description 照片 ID。 */
photoId: components["parameters"]["PhotoId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description 下载凭证(短期签名 URL)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["PublicPhotoDownload"];
};
};
/** @description 查询参数校验失败(VALIDATION_FAILED;variant 缺失或取值非法)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册下载开关关闭(DOWNLOAD_DISABLED;对应 variant 所需级别的开关未开)。 */
403: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/**
* @description 相册不存在或未公开(ALBUM_NOT_PUBLIC),或照片不存在、未发布、
* 不属于该相册(PHOTO_NOT_PUBLIC)。
*/
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
syncContentBatches: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["ContentBatchRequest"];
};
};
responses: {
/** @description 本批受理结果。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["ContentBatchResponse"];
};
};
/** @description 请求体校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
syncStatSnapshots: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["StatSnapshotRequest"];
};
};
responses: {
/** @description 回传受理结果。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["StatSnapshotResponse"];
};
};
/** @description 请求体校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
syncReconcile: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["ReconcileRequest"];
};
};
responses: {
/** @description 缺失事件清单(按 entityVersion 升序)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["ReconcileResponse"];
};
};
/** @description 请求体校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
syncBootstrap: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["BootstrapRequest"];
};
};
responses: {
/** @description 快照规模与水位。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["BootstrapResponse"];
};
};
/** @description 请求体校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
syncDigest: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["DigestRequest"];
};
};
responses: {
/** @description 每相册计数摘要(albumId 升序)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["DigestResponse"];
};
};
/** @description 请求体校验失败(VALIDATION_FAILED)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
emergencyDisable: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["EmergencyDisableRequest"];
};
};
responses: {
/** @description 已停用(幂等:重复停用返回同一结果)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EmergencyStatus"];
};
};
/** @description 请求体校验失败(VALIDATION_FAILED;含 albumToken/albumId 均缺省)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册副本不存在(ALBUM_NOT_FOUND——ov 尚未同步该相册)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
emergencyEnable: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["EmergencyEnableRequest"];
};
};
responses: {
/** @description 已恢复(幂等:重复启用返回同一结果)。 */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EmergencyStatus"];
};
};
/** @description 请求体校验失败(VALIDATION_FAILED;含 albumToken/albumId 均缺省)。 */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description 相册副本不存在(ALBUM_NOT_FOUND)。 */
404: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
500: components["responses"]["InternalError"];
};
};
}