feat(contracts): p1b asset upload, management photo list, account lookup
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
+385
@@ -118,6 +118,60 @@ export interface paths {
|
||||
patch: operations["updateAlbum"];
|
||||
trace?: never;
|
||||
};
|
||||
"/albums/{albumId}/assets": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
/** @description 相册 ID。 */
|
||||
albumId: components["parameters"]["AlbumId"];
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
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;
|
||||
@@ -294,6 +348,31 @@ export interface paths {
|
||||
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 稳定倒序
|
||||
* 游标分页。
|
||||
*/
|
||||
get: operations["listAlbumPhotos"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/photos/{photoId}": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -321,6 +400,32 @@ export interface paths {
|
||||
patch: operations["updatePhoto"];
|
||||
trace?: never;
|
||||
};
|
||||
"/admin/users": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* 账号前缀查询
|
||||
* @description 邀请协作者的前置查询:按账号前缀搜索激活用户,返回脱敏列表
|
||||
* (id/account/displayName,不含邮箱、手机与状态字段)。
|
||||
* 访问策略(P1b 决策):任何已认证工作人员可用——邀请的发起方不限于
|
||||
* 创建者/管理员,而泄露面仅为激活用户的最小展示字段、接收方为已认证
|
||||
* 内部人员,风险可接受;未认证一律 401。前缀匹配为大小写敏感
|
||||
* (服务端按二进制校对执行 LIKE prefix%);按账号升序返回,无游标
|
||||
* (前缀搜索 + 小上限即取即用)。
|
||||
*/
|
||||
get: operations["lookupUsersByAccount"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/public/albums/{token}": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -573,6 +678,45 @@ export interface components {
|
||||
/** @description 相册分类(按 sortOrder 升序)。 */
|
||||
categories: components["schemas"]["Category"][];
|
||||
};
|
||||
/**
|
||||
* @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;
|
||||
};
|
||||
MemberAddRequest: {
|
||||
/** @description 被添加用户的 ID(须为已开通账号)。 */
|
||||
userId: string;
|
||||
@@ -790,6 +934,35 @@ export interface components {
|
||||
/** @description 累计点赞数。 */
|
||||
readonly likeCount: number;
|
||||
};
|
||||
/** @description 管理列表条目内嵌的上传人脱敏信息(不含邮箱、手机等凭据字段)。 */
|
||||
AdminPhotoUploader: {
|
||||
/** @description 上传人用户 ID(与 PhotoRecord.uploaderId 一致)。 */
|
||||
readonly userId: string;
|
||||
/** @description 登录账号。 */
|
||||
readonly account: string;
|
||||
/** @description 展示姓名(来自用户资料)。 */
|
||||
readonly displayName: string;
|
||||
};
|
||||
AdminPhoto: components["schemas"]["PhotoRecord"] & {
|
||||
uploader: components["schemas"]["AdminPhotoUploader"];
|
||||
};
|
||||
AdminPhotoList: components["schemas"]["CursorPageMeta"] & {
|
||||
items: components["schemas"]["AdminPhoto"][];
|
||||
};
|
||||
/** @description 账号查询条目(脱敏:仅邀请协作者所需的最小字段,不含邮箱/手机/状态)。 */
|
||||
AdminUserLookupItem: {
|
||||
/** @description 用户 ID(用于 POST /albums/{albumId}/members 的 userId)。 */
|
||||
readonly id: string;
|
||||
/** @description 登录账号。 */
|
||||
readonly account: string;
|
||||
/** @description 展示姓名。 */
|
||||
readonly displayName: string;
|
||||
};
|
||||
/** @description 账号前缀查询结果;无游标(前缀搜索 + 小上限即取即用)。 */
|
||||
AdminUserLookupList: {
|
||||
/** @description 匹配的激活用户(按账号升序)。 */
|
||||
items: components["schemas"]["AdminUserLookupItem"][];
|
||||
};
|
||||
/** @description 私有对象的短期签名 URL;不得写入持久分享链接,过期后经原入口刷新。 */
|
||||
SignedUrl: {
|
||||
/** @description 签名访问 URL。 */
|
||||
@@ -900,6 +1073,8 @@ export interface components {
|
||||
UserId: string;
|
||||
/** @description 分类 ID。 */
|
||||
CategoryId: string;
|
||||
/** @description 相册资产 ID。 */
|
||||
AssetId: string;
|
||||
/** @description 上传会话 ID。 */
|
||||
UploadId: string;
|
||||
/** @description 照片 ID。 */
|
||||
@@ -1193,6 +1368,119 @@ export interface operations {
|
||||
500: components["responses"]["InternalError"];
|
||||
};
|
||||
};
|
||||
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?: {
|
||||
@@ -1695,6 +1983,67 @@ export interface operations {
|
||||
500: components["responses"]["InternalError"];
|
||||
};
|
||||
};
|
||||
listAlbumPhotos: {
|
||||
parameters: {
|
||||
query?: {
|
||||
/** @description 可见性过滤;缺省为全部状态。 */
|
||||
visibility?: components["schemas"]["PhotoVisibility"];
|
||||
/** @description 分类 ID 过滤。 */
|
||||
categoryId?: string;
|
||||
/** @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 仅创建者或管理员可访问管理列表(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;
|
||||
@@ -1792,6 +2141,42 @@ export interface operations {
|
||||
500: components["responses"]["InternalError"];
|
||||
};
|
||||
};
|
||||
lookupUsersByAccount: {
|
||||
parameters: {
|
||||
query: {
|
||||
/** @description 账号前缀(≥2 字符以防过宽匹配)。 */
|
||||
accountPrefix: string;
|
||||
/** @description 返回条数上限。 */
|
||||
limit?: number;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description 匹配的激活用户列表(无匹配为空数组)。 */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["AdminUserLookupList"];
|
||||
};
|
||||
};
|
||||
/** @description 查询参数校验失败(VALIDATION_FAILED;accountPrefix 缺失或长度非法)。 */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["Error"];
|
||||
};
|
||||
};
|
||||
401: components["responses"]["Unauthorized"];
|
||||
500: components["responses"]["InternalError"];
|
||||
};
|
||||
};
|
||||
getPublicAlbum: {
|
||||
parameters: {
|
||||
query?: {
|
||||
|
||||
Reference in New Issue
Block a user