feat(api): upload duplicate pre-check endpoint (checkUploadDuplicates)
「上传查重前置到入队前」Task 1:POST /v1/uploads/duplicates/check 只读批量 查重预检——用户点上传(确认入队)时刻预判服务端历史重复(跨设备/重装/改名 均可查到),不再等任务在上传中心以 PHOTO_DUPLICATE 失败才暴露。 - 契约纯增量:/uploads/duplicates/check + UploadDuplicateCheck(Item|Request| Duplicate|Response) schemas;regen openapi.d.ts。 - 判定谓词与 init ③.5 服务端查重逐字一致:同 albumId + uploaderId=当前用户 + bytes 相等 + visibility != 'deleted'(filename 刻意不参与),保证「预检 即真相」;命中条目按请求下标逐项返回(同 bytes 多请求条目各一条)。 - 权限链同 init(canView 404 防枚举 / canUpload 403 / 相册空值兜底 404), 刻意不校验 uploadEnabled:只读预览,init 真正入队时仍按开关 409 兜底。 - 查询走 idx_photos_dedup:请求条目去重字节集一次 findMany,内存建 bytes→最早 uploadedAt 映射后按请求下标回射。 - items 1..500(minItems/maxItems + 嵌套逐项校验,越界 400)。 - e2e 追加 describe 7 用例:命中含双条目同 bytes/未命中/uploaderId 隔离/ deleted 不命中/非成员 404/items 边界 400/未认证 401。 契约 lint ✅ · contracts+api typecheck ✅ · api 单测 56/56 ✅ · uploads e2e 28/28 ✅ Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -909,6 +909,56 @@ paths:
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalError'
|
||||
|
||||
/uploads/duplicates/check:
|
||||
post:
|
||||
operationId: checkUploadDuplicates
|
||||
tags: [uploads]
|
||||
summary: 上传查重预检(批量,只读)
|
||||
description: |
|
||||
批量查重预检:对每个请求条目判定「同相册 + 同上传者(当前用户)+ 同字节数」
|
||||
的非 deleted 照片是否已存在——判定谓词与 initUpload 的 PHOTO_DUPLICATE
|
||||
查重逐字一致(含 uploaderId 隔离;filename 刻意不参与)。命中条目按请求
|
||||
下标逐项返回(两个请求条目共享同一命中 bytes 时各返回一条)。
|
||||
不校验 uploadEnabled:预检是只读预览,相册关闭上传时仍可查询历史重复
|
||||
(init 在真正入队时仍按开关 409 兜底)。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UploadDuplicateCheckRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: 查重结果(命中子集;无命中时 duplicates 为空数组)。
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UploadDuplicateCheckResponse'
|
||||
'400':
|
||||
description: 参数校验失败(VALIDATION_FAILED):items 为空/超 500 项或条目字段非法。
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
description: 无该相册的上传权限(AUTH_FORBIDDEN)。
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
description: 相册不可见或不存在(ALBUM_NOT_FOUND,不区分以避免枚举)。
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalError'
|
||||
|
||||
/uploads/{uploadId}/renew:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/UploadId'
|
||||
@@ -3536,6 +3586,67 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/UploadSessionRecord'
|
||||
|
||||
UploadDuplicateCheckItem:
|
||||
type: object
|
||||
description: 查重预检请求条目(与 initUpload 入参同形;filename 仅元数据)。
|
||||
required: [filename, bytes]
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 255
|
||||
description: 原始文件名(仅元数据;查重谓词不使用,与 init 查重一致)。
|
||||
bytes:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 1
|
||||
description: 申明文件字节数(查重键)。
|
||||
|
||||
UploadDuplicateCheckRequest:
|
||||
type: object
|
||||
description: 批量查重预检请求;单批上限 500 项,客户端按 500 分块顺序调用。
|
||||
required: [albumId, items]
|
||||
properties:
|
||||
albumId:
|
||||
type: string
|
||||
description: 目标相册 ID。
|
||||
items:
|
||||
type: array
|
||||
minItems: 1
|
||||
maxItems: 500
|
||||
description: 待查重条目(1..500 项)。
|
||||
items:
|
||||
$ref: '#/components/schemas/UploadDuplicateCheckItem'
|
||||
|
||||
UploadDuplicateCheckDuplicate:
|
||||
type: object
|
||||
description: 单条命中结果;每个命中的「请求条目」一条(index 指向请求数组)。
|
||||
required: [index, bytes, uploadedAt]
|
||||
properties:
|
||||
index:
|
||||
type: integer
|
||||
minimum: 0
|
||||
description: 命中条目在请求 items 数组中的下标(0 起)。
|
||||
bytes:
|
||||
type: integer
|
||||
format: int64
|
||||
description: 命中字节数(与对应请求条目一致)。
|
||||
uploadedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 服务端既有照片的上传时间(同 bytes 多条命中取最早)。
|
||||
|
||||
UploadDuplicateCheckResponse:
|
||||
type: object
|
||||
description: 查重预检结果(命中子集,按请求下标升序)。
|
||||
required: [duplicates]
|
||||
properties:
|
||||
duplicates:
|
||||
type: array
|
||||
description: 命中子集;无命中为空数组。
|
||||
items:
|
||||
$ref: '#/components/schemas/UploadDuplicateCheckDuplicate'
|
||||
|
||||
# ── 照片(管理端) ──
|
||||
|
||||
PhotoVisibilityUpdateRequest:
|
||||
|
||||
Reference in New Issue
Block a user