Files
photo-live/services/api/src/shared/ov-browse-key.ts
T
浅念 2bb6f291d3 feat(ov,viewer): two-tier download with wechat guidance
P4a Task 4(T12 收口):ov 域公开照片下载端点 + viewer 下载 UI。

- interactions 增 downloads:GET /public/albums/{token}/photos/{photoId}
  /download?variant=browse|original。两级开关(A18):browse 需
  downloadEnabled;original 需叠加 originalDownloadEnabled(级联,browse 关
  则两者均 403 DOWNLOAD_DISABLED)。水印相册 browse 现签 watermark pattern
  key(browse-key 解析抽取 shared/ov-browse-key 与 public-ov 复用);原图
  现签 originalObjectKey(SIGNED_URL_TTL)。来源 IP 固定窗限速
  (DOWNLOAD_WINDOW_REQUESTS/DOWNLOAD_WINDOW_SECONDS,env 可调);零浏览
  计数写入(排除规则)。STORAGE_PORT_OV 经新 StorageOvModule 与 public-ov
  共享同一实例。
- 契约微调登记:PublicAlbum 增 readOnly 必返 downloadEnabled/
  originalDownloadEnabled(cn+ov 同形返回;public e2e 精确键断言同步)。
- viewer:lightbox 下载入口随开关渲染(无/单按钮/分体菜单两选项)、过期
  凭证静默重取一次、微信内置浏览器(MicroMessenger UA)出保存图片指引
  浮层(复制深链 + 反馈)替代直接下载;i18n zh/en 词条。
- tests:api e2e +7(开关矩阵 + URL/字节级断言、水印键一致、隐藏 404、
  限速 429、零计数行);viewer vitest +9(UA/矩阵/菜单/重取/失败/指引/
  复制);viewer Playwright +3(入口矩阵、微信 UA 浮层、真实端点 200 +
  签名 URL 模式)。

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

32 lines
1.5 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.
// services/api/src/shared/ov-browse-key.ts —— ov 侧浏览图对象键的单一推导
// 实现(P4a Task 4 自 public-ov.service 抽出):公开读(列表/单图 browse 现签)
// 与下载端点(variant=browse 的下载键)必须落同一对象——水印开启时两者都是
// 模式键(watermarkVariantObjectKey),关闭时都是 photos_ov 内联 browse 键。
// 键由 (albumId, photoId, 有效版本) 确定性构成(ov 无变体副本表);对象存在性
// 由 cn 侧 done 任务收尾不变量保证(见 packages/contracts/src/watermark.ts 与
// public-ov.service 头注)。
import { watermarkVariantObjectKey } from '@photo/storage';
/** 相册级水印服务上下文(albums_ov 副本位 + 归属 albumId)。 */
export interface WatermarkContextOv {
albumId: string;
enabled: boolean;
configVersion: number;
}
/**
* ov 浏览图对象键:水印开启(enabled && 有效版本 > 0)→ 模式键
* variants/{photoId}/{有效版本}/watermark.jpg(cn worker 直写同一对象空间,
* 失败照片由任务收尾回退拷贝旧图——键恒有对象);否则 → photos_ov 内联
* browse 键(disable 版任务完成后回落,水印键对象保留历史可溯)。
*/
export function ovBrowseKey(
watermark: WatermarkContextOv,
photoId: string,
browseObjectKey: string,
): string {
return watermark.enabled && watermark.configVersion > 0
? watermarkVariantObjectKey(watermark.albumId, photoId, watermark.configVersion)
: browseObjectKey;
}