Files
photo-live/.env.example
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

66 lines
3.6 KiB
Bash
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.
DATABASE_URL_CN=mysql://root:root@127.0.0.1:3306/photo_cn?connection_limit=10
REDIS_URL_CN=redis://127.0.0.1:6379
S3_ENDPOINT=http://127.0.0.1:9000
S3_REGION=us-east-1
S3_ACCESS_KEY=photo-dev
S3_SECRET_KEY=photo-dev-secret
S3_BUCKET=photo-dev
SIGNED_URL_TTL_SECONDS=900
AUTH_SESSION_TTL_SECONDS=2592000
UPLOAD_MAX_BYTES=52428800
PORT=8080
# viewer(P2 Task 6 起直连 ov 8081,跨源)需两形 origin:Playwright/本机访问
# 常走 127.0.0.1,浏览器 Origin 头按实际 host 发出——localhost 与 127.0.0.1
# 是两个不同 origin,缺一则直连 fetch 被 CORS 拦截。admin(5176)走自身
# /v1 代理同源,不依赖此清单。
CORS_ORIGINS=http://localhost:5175,http://127.0.0.1:5175,http://localhost:5176
LOG_LEVEL=info
ADMIN_ACCOUNT=admin
ADMIN_PASSWORD=admin-secret-change-me
# ── P2 双地域仿真(ov 域)──
# 本任务(Task 1)即被读取的键:内部同步 HMAC 密钥与 ov 双库连接。
SYNC_INTERNAL_KEY=dev-sync-secret-change-me
DATABASE_URL_OV=mysql://root:root@127.0.0.1:3309/photo_ov?connection_limit=10
REDIS_URL_OV=redis://127.0.0.1:6381
# P2 Task 2:ov 入口监听端口(main-ov.ts 读取;与 cn PORT=8080 同机双入口)。
PORT_OV=8081
# P2 Task 3:sync 发送器(services/sync)推送目标——ov 入口基址(不含路径,
# 端点路径由发送器拼接为 /v1/internal/sync/content-batches)。
OV_API_URL=http://127.0.0.1:8081
# P2 Task 4:对账调度器(services/sync reconciler)拉取 reconcile/digest 与
# 触发 bootstrap 的 cn 入口基址(不含路径)。
CN_API_URL=http://127.0.0.1:8080
# 以下为 P2 决策初值(D07/D11)的 env 覆盖键:默认值见
# packages/contracts/src/constants.ts(HEARTBEAT_MS 见 src/realtime.ts),
# 此处登记供运维可见与调整;SYNC_BATCH_SIZE/SYNC_PUSH_INTERVAL_MS 自 Task 3
# 起、SYNC_RECONCILE_INTERVAL_MS 自 Task 4 起、STAT_RETURN_INTERVAL_MS 自
# Task 9 起被 services/sync 读取,其余为前瞻登记(Task 7+ 逐个接线)。
SYNC_BATCH_SIZE=100
SYNC_PUSH_INTERVAL_MS=2000
SYNC_RECONCILE_INTERVAL_MS=300000
# P2 Task 6:ov 公开列表 sort=hot 的排序快照 TTL(毫秒,缺省 30000)——
# 顺序冻结窗口(点赞数仍逐请求现读),由 services/api public-ov 惰性读取;
# e2e 以短 TTL 加速翻转断言。另:viewer 的 API 基址是构建期变量
# VITE_API_BASE(缺省 http://127.0.0.1:8081 ov 入口;空串=同源网关)——
# Vite 只读 apps/viewer/.env*,根 .env 对前端无效(见 apps/viewer/src/api/client.ts)。
HOT_SORT_TTL_MS=30000
STAT_RETURN_INTERVAL_MS=60000
VISIT_WINDOW_MINUTES=30
LIKE_BATCH_WINDOW_HOURS=24
# P2 Task 7:点赞基础限速(Redis ov 滑窗,窗口=LIKE_BATCH_WINDOW_HOURS)与
# likes.burst 实时合并窗口——sessionId 窗口累计 delta 上限 / 来源 IP 上限 /
# 同照片批次合并毫秒数(0=不合并)。默认值见 packages/contracts/src/constants.ts。
LIKE_SESSION_WINDOW_DELTA=500
LIKE_IP_WINDOW_DELTA=2000
LIKE_BURST_MERGE_MS=500
VISIT_REQUEST_TTL_MINUTES=35
# P2 Task 8:浏览上报基础限速(visitorId+IP 固定窗,窗口=VISIT_WINDOW_MINUTES,
# 每窗请求数上限——去重本身为主缓解)与 ov 互动流水清理调度间隔(分钟,0=停用;
# 清理 like_batches/visit_requests/visit_sessions 超窗口行,累计总数永不清)。
VISIT_WINDOW_REQUESTS=60
# P4a Task 4:公开照片下载端点基础限速(来源 IP 固定窗,窗口=60s 固定;
# 每窗请求数上限——签名现算无幂等面,限速定位是误客户端缓冲,P5 速率层接防)。
DOWNLOAD_WINDOW_REQUESTS=120
CLEANUP_INTERVAL_MINUTES=60