diff --git a/docs/plans/2026-09-17-P1a-后端核心链路.md b/docs/plans/2026-09-17-P1a-后端核心链路.md index 9ce0cc4..b6142c6 100644 --- a/docs/plans/2026-09-17-P1a-后端核心链路.md +++ b/docs/plans/2026-09-17-P1a-后端核心链路.md @@ -429,7 +429,7 @@ model upload_sessions { expectedBytes Int contentType String @db.VarChar(128) multipartId String? - state String @default("pending_upload") // pending_upload|uploaded|confirmed|failed + state String @default("pending") // pending|confirmed|cancelled|expired(对齐契约 UploadSessionState;核验失败是请求级错误不改会话态,expired 由 expiresAt 判定或 sweep 置位) expiresAt DateTime @db.DateTime(6) createdAt DateTime @default(now()) @db.DateTime(6) @@unique([userId, clientTaskId]) // 幂等锚点(A03) @@ -648,4 +648,4 @@ export interface StoragePort { - env:命令一律在仓库根执行;根 `.env` 为唯一 env 文件,脚本经 dotenv-cli 注入、测试经 `test/load-env.ts` 载入(Task 7 约定;`services/worker/test` 与 `packages/storage/test` 复制同约定 load-env.ts——两者到仓库根同为三级向上,路径一致);新增 env 变量必须同步 `.env.example`;密钥不入库。 - 发现契约需变更时:先改 `packages/contracts` 并重新生成类型、在任务提交信息中登记,再改消费端(契约单一事实源)。 - 与总纲冲突处以总纲为准并回写修订;HEIC、MySQL 行值比较等 D12 复核项结论写入验收记录。 -- P1a 完成后:编写 P1b 计划(viewer 基础页 + admin 最小页 + **宣传图/封面/Logo 上传链路(album_assets 的 presign+确认,复用照片上传机制,R09 依赖)** + Playwright 冒烟)。 +- P1a 完成后:编写 P1b 计划(viewer 基础页 + admin 最小页 + **宣传图/封面/Logo 上传链路(album_assets 的 presign+确认,复用照片上传机制,R09 依赖)** + **GET /albums/{albumId}/photos 管理端照片列表**(含未发布/隐藏态,照片管理入口)+ **用户账号查询接口**(邀请协作者时按 account 搜索)+ Playwright 冒烟)。 diff --git a/packages/contracts/openapi.yaml b/packages/contracts/openapi.yaml index dfd4187..1fd58be 100644 --- a/packages/contracts/openapi.yaml +++ b/packages/contracts/openapi.yaml @@ -75,11 +75,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /auth/refresh: post: @@ -103,17 +99,9 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 令牌缺失、无效或已过期(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /auth/logout: post: @@ -133,17 +121,9 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 令牌缺失、无效或已过期(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' # ─────────────────────────── albums ─────────────────────────── @@ -178,17 +158,9 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' get: operationId: listAlbums @@ -221,17 +193,9 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /albums/{albumId}: parameters: @@ -251,11 +215,7 @@ paths: schema: $ref: '#/components/schemas/Album' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '404': description: 相册不存在,或当前用户非成员不可见(ALBUM_NOT_FOUND,避免枚举)。 content: @@ -263,11 +223,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' patch: operationId: updateAlbum @@ -298,11 +254,7 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 仅创建者或管理员可修改(AUTH_FORBIDDEN)。 content: @@ -316,11 +268,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' # ─────────────────────────── members ─────────────────────────── @@ -354,11 +302,7 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 仅创建者或管理员可管理成员(AUTH_FORBIDDEN)。 content: @@ -378,11 +322,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' get: operationId: listAlbumMembers @@ -415,11 +355,7 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '404': description: 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 content: @@ -427,11 +363,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /albums/{albumId}/members/{userId}: parameters: @@ -450,11 +382,7 @@ paths: '204': description: 已移除,无响应体。 '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 无管理权限,或试图移除创建者(AUTH_FORBIDDEN)。 content: @@ -468,11 +396,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' # ─────────────────────────── categories ─────────────────────────── @@ -506,11 +430,7 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 仅创建者或管理员可管理分类(AUTH_FORBIDDEN)。 content: @@ -524,11 +444,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /categories/{categoryId}: parameters: @@ -560,11 +476,7 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 无所属相册的管理权限(AUTH_FORBIDDEN)。 content: @@ -578,11 +490,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' delete: operationId: deleteCategory @@ -595,11 +503,7 @@ paths: '204': description: 已删除,无响应体。 '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 无所属相册的管理权限(AUTH_FORBIDDEN)。 content: @@ -613,11 +517,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' # ─────────────────────────── uploads ─────────────────────────── @@ -652,11 +552,7 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 无该相册的上传权限(AUTH_FORBIDDEN)。 content: @@ -672,11 +568,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' get: operationId: listUploads @@ -709,17 +601,9 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /uploads/{uploadId}/renew: parameters: @@ -739,11 +623,7 @@ paths: schema: $ref: '#/components/schemas/UploadInitResponse' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 无权操作该会话或会话不存在(AUTH_FORBIDDEN,不区分以避免枚举)。 content: @@ -759,11 +639,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /uploads/{uploadId}/complete: parameters: @@ -793,11 +669,7 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 无权操作该会话或会话不存在(AUTH_FORBIDDEN,不区分以避免枚举)。 content: @@ -811,11 +683,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' # ─────────────────────────── photos ─────────────────────────── @@ -849,11 +717,7 @@ paths: schema: $ref: '#/components/schemas/Error' '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 无该照片的管理权限(AUTH_FORBIDDEN)。 content: @@ -867,11 +731,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' delete: operationId: deletePhoto @@ -884,11 +744,7 @@ paths: '204': description: 已软删除,无响应体。 '401': - description: 未认证(AUTH_TOKEN_EXPIRED)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/Unauthorized' '403': description: 无该照片的管理权限(AUTH_FORBIDDEN)。 content: @@ -902,11 +758,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' # ─────────────────────────── public ─────────────────────────── @@ -943,11 +795,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /public/albums/{token}/photos: parameters: @@ -996,11 +844,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' /public/albums/{token}/photos/{photoId}: parameters: @@ -1030,11 +874,7 @@ paths: schema: $ref: '#/components/schemas/Error' '500': - description: 服务器内部错误(INTERNAL_ERROR)。 - content: - application/json: - schema: - $ref: '#/components/schemas/Error' + $ref: '#/components/responses/InternalError' components: securitySchemes: @@ -1091,6 +931,7 @@ components: description: 分页游标(上一页响应的 nextCursor)。 schema: type: string + maxLength: 512 LocaleQuery: name: locale in: query @@ -1098,6 +939,20 @@ components: schema: $ref: '#/components/schemas/Locale' + responses: + Unauthorized: + description: 未认证:令牌缺失、无效或已过期(AUTH_TOKEN_EXPIRED)。 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + InternalError: + description: 服务器内部错误(INTERNAL_ERROR)。 + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + schemas: # ── 通用 ── @@ -1135,7 +990,7 @@ components: CursorPageMeta: type: object required: [nextCursor, hasMore] - description: 游标分页元信息;各列表响应以 allOf 内嵌本结构(条目 schema 在业务端点中定义)。 + description: 游标分页元信息;各列表响应以 allOf 内嵌本结构(条目 schema 在业务端点中定义)。不变式:hasMore=true 当且仅当 nextCursor≠null,两者必须成对填充。 properties: nextCursor: type: [string, 'null'] @@ -1199,6 +1054,7 @@ components: $ref: '#/components/schemas/Locale' title: type: string + minLength: 1 description: 相册标题。 description: type: [string, 'null'] @@ -1310,6 +1166,7 @@ components: publicToken: type: string readOnly: true + pattern: '^[0-9a-z]{20,32}$' description: 公开访问令牌(不可枚举)。 ownerId: type: string @@ -1319,10 +1176,10 @@ components: type: string readOnly: true default: active - description: 相册状态。 + description: 相册状态;offline 表示下线(停止公开访问与新授权签发)。 enum: - active - - archived + - offline defaultLocale: $ref: '#/components/schemas/Locale' timezone: @@ -1460,6 +1317,7 @@ components: $ref: '#/components/schemas/Locale' name: type: string + minLength: 1 description: 分类名称。 CategoryCreateRequest: @@ -1517,7 +1375,11 @@ components: UploadSessionState: type: string - description: 上传会话状态(服务端视角;本地任务状态见技术实施方案 §5.5)。 + description: | + 上传会话状态(服务端视角;本地任务状态见技术实施方案 §5.5)。 + 会话没有 failed 状态:完成核验失败属于单次请求错误(UPLOAD_VERIFY_FAILED), + 会话保持 pending 可重试;cancelled 为用户主动取消; + expired 为超过 expiresAt 未完成(核验时推导或由补偿扫描落定)。 enum: - pending - confirmed @@ -1555,9 +1417,11 @@ components: description: 目标分类 ID;缺省为相册默认分类。 clientTaskId: type: string + maxLength: 128 description: 客户端任务幂等键;同一任务的重试必须复用(会话与照片 ID 均复用)。 filename: type: string + maxLength: 255 description: 原始文件名(仅元数据,不作对象唯一标识)。 bytes: type: integer @@ -1566,7 +1430,8 @@ components: description: 申明文件字节数;完成核验时逐一比对。 contentType: type: string - description: MIME 类型;仅接受图片类型(JPEG/PNG/HEIC)。 + enum: [image/jpeg, image/png, image/heic] + description: MIME 类型白名单;image/heic 为暂定项,解码能力待 G2 真机验证后确认。 UploadCredential: type: object @@ -1850,7 +1715,7 @@ components: - timezone - startAt - endAt - - translations + - translation - categories - banner - viewCount @@ -1858,6 +1723,7 @@ components: publicToken: type: string readOnly: true + pattern: '^[0-9a-z]{20,32}$' description: 相册公开令牌。 resolvedLocale: $ref: '#/components/schemas/Locale' @@ -1877,7 +1743,7 @@ components: format: date-time readOnly: true description: 活动结束时间;未定为 null。 - translations: + translation: $ref: '#/components/schemas/PublicAlbumTranslation' categories: type: array @@ -1896,8 +1762,8 @@ components: PublicPhoto: type: object - description: 公开照片条目(仅 published 照片;URL 为短期签名,需在过期前刷新)。 - required: [photoId, thumb, browse, likeCount, publishedAt] + description: 公开照片条目(仅 published 照片,处理完成即有宽高;URL 为短期签名,需在过期前刷新)。 + required: [photoId, width, height, thumb, browse, likeCount, publishedAt] properties: photoId: type: string diff --git a/packages/contracts/src/generated/openapi.d.ts b/packages/contracts/src/generated/openapi.d.ts index dfdc810..6f1bff1 100644 --- a/packages/contracts/src/generated/openapi.d.ts +++ b/packages/contracts/src/generated/openapi.d.ts @@ -410,7 +410,7 @@ export interface components { /** @description 请求追踪 ID。 */ readonly requestId: string; }; - /** @description 游标分页元信息;各列表响应以 allOf 内嵌本结构(条目 schema 在业务端点中定义)。 */ + /** @description 游标分页元信息;各列表响应以 allOf 内嵌本结构(条目 schema 在业务端点中定义)。不变式:hasMore=true 当且仅当 nextCursor≠null,两者必须成对填充。 */ CursorPageMeta: { /** @description 下一页游标;null 表示没有更多数据。 */ readonly nextCursor: string | null; @@ -522,11 +522,11 @@ export interface components { /** @description 创建者用户 ID。 */ readonly ownerId: string; /** - * @description 相册状态。 + * @description 相册状态;offline 表示下线(停止公开访问与新授权签发)。 * @default active * @enum {string} */ - readonly status: "active" | "archived"; + readonly status: "active" | "offline"; defaultLocale: components["schemas"]["Locale"]; /** @description 活动 IANA 时区。 */ timezone: string; @@ -637,6 +637,9 @@ export interface components { }; /** * @description 上传会话状态(服务端视角;本地任务状态见技术实施方案 §5.5)。 + * 会话没有 failed 状态:完成核验失败属于单次请求错误(UPLOAD_VERIFY_FAILED), + * 会话保持 pending 可重试;cancelled 为用户主动取消; + * expired 为超过 expiresAt 未完成(核验时推导或由补偿扫描落定)。 * @enum {string} */ UploadSessionState: "pending" | "confirmed" | "cancelled" | "expired"; @@ -664,8 +667,11 @@ export interface components { * @description 申明文件字节数;完成核验时逐一比对。 */ bytes: number; - /** @description MIME 类型;仅接受图片类型(JPEG/PNG/HEIC)。 */ - contentType: string; + /** + * @description MIME 类型白名单;image/heic 为暂定项,解码能力待 G2 真机验证后确认。 + * @enum {string} + */ + contentType: "image/jpeg" | "image/png" | "image/heic"; }; /** @description staging 对象的临时直传凭证;仅可写入指定 objectKey,不可访问 originals/variants。 */ UploadCredential: { @@ -833,7 +839,7 @@ export interface components { * @description 活动结束时间;未定为 null。 */ readonly endAt: string | null; - translations: components["schemas"]["PublicAlbumTranslation"]; + translation: components["schemas"]["PublicAlbumTranslation"]; /** @description 分类列表(按 sortOrder 升序)。 */ categories: components["schemas"]["PublicCategory"][]; /** @description 封面图签名 URL;未设置为 null。 */ @@ -841,14 +847,14 @@ export interface components { /** @description P1a 占位 null;浏览计数由后续 /visits 端点提供(技术实施方案 §7.1)。 */ readonly viewCount: null; }; - /** @description 公开照片条目(仅 published 照片;URL 为短期签名,需在过期前刷新)。 */ + /** @description 公开照片条目(仅 published 照片,处理完成即有宽高;URL 为短期签名,需在过期前刷新)。 */ PublicPhoto: { /** @description 照片 ID。 */ readonly photoId: string; /** @description 浏览图宽度(像素);用于列表占位,减少加载跳动。 */ - readonly width?: number; + readonly width: number; /** @description 浏览图高度(像素)。 */ - readonly height?: number; + readonly height: number; thumb: components["schemas"]["SignedUrl"]; browse: components["schemas"]["SignedUrl"]; /** @description 累计点赞数。 */ @@ -867,7 +873,26 @@ export interface components { items: components["schemas"]["PublicPhoto"][]; }; }; - responses: never; + 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; @@ -932,15 +957,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; refreshSession: { @@ -970,24 +987,8 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 令牌缺失、无效或已过期(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; + 500: components["responses"]["InternalError"]; }; }; logout: { @@ -1015,24 +1016,8 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 令牌缺失、无效或已过期(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; + 500: components["responses"]["InternalError"]; }; }; listAlbums: { @@ -1067,24 +1052,8 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; + 500: components["responses"]["InternalError"]; }; }; createAlbum: { @@ -1118,24 +1087,8 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; + 500: components["responses"]["InternalError"]; }; }; getAlbum: { @@ -1159,15 +1112,7 @@ export interface operations { "application/json": components["schemas"]["Album"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 相册不存在,或当前用户非成员不可见(ALBUM_NOT_FOUND,避免枚举)。 */ 404: { headers: { @@ -1177,15 +1122,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; updateAlbum: { @@ -1222,15 +1159,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 仅创建者或管理员可修改(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -1249,15 +1178,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; listAlbumMembers: { @@ -1295,15 +1216,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 相册不存在,或当前用户不可见(ALBUM_NOT_FOUND)。 */ 404: { headers: { @@ -1313,15 +1226,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; addAlbumMember: { @@ -1358,15 +1263,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 仅创建者或管理员可管理成员(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -1394,15 +1291,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; removeAlbumMember: { @@ -1426,15 +1315,7 @@ export interface operations { }; content?: never; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 无管理权限,或试图移除创建者(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -1453,15 +1334,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; createCategory: { @@ -1498,15 +1371,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 仅创建者或管理员可管理分类(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -1525,15 +1390,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; deleteCategory: { @@ -1555,15 +1412,7 @@ export interface operations { }; content?: never; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 无所属相册的管理权限(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -1582,15 +1431,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; updateCategory: { @@ -1627,15 +1468,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 无所属相册的管理权限(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -1654,15 +1487,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; listUploads: { @@ -1697,24 +1522,8 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; + 500: components["responses"]["InternalError"]; }; }; initUpload: { @@ -1748,15 +1557,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 无该相册的上传权限(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -1778,15 +1579,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; renewUploadCredential: { @@ -1810,15 +1603,7 @@ export interface operations { "application/json": components["schemas"]["UploadInitResponse"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 无权操作该会话或会话不存在(AUTH_FORBIDDEN,不区分以避免枚举)。 */ 403: { headers: { @@ -1840,15 +1625,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; completeUpload: { @@ -1884,15 +1661,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 无权操作该会话或会话不存在(AUTH_FORBIDDEN,不区分以避免枚举)。 */ 403: { headers: { @@ -1911,15 +1680,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; deletePhoto: { @@ -1941,15 +1702,7 @@ export interface operations { }; content?: never; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 无该照片的管理权限(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -1968,15 +1721,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; updatePhoto: { @@ -2013,15 +1758,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 未认证(AUTH_TOKEN_EXPIRED)。 */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 401: components["responses"]["Unauthorized"]; /** @description 无该照片的管理权限(AUTH_FORBIDDEN)。 */ 403: { headers: { @@ -2040,15 +1777,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; getPublicAlbum: { @@ -2093,15 +1822,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; listPublicPhotos: { @@ -2152,15 +1873,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; getPublicPhoto: { @@ -2198,15 +1911,7 @@ export interface operations { "application/json": components["schemas"]["Error"]; }; }; - /** @description 服务器内部错误(INTERNAL_ERROR)。 */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Error"]; - }; - }; + 500: components["responses"]["InternalError"]; }; }; }