36082c5a74
P2 Task 4(inbox 对账):
- services/sync 新增 SyncReconciler(runOnce 可测;main 双循环,间隔
SYNC_RECONCILE_INTERVAL_MS env 可调,CN_API_URL 指向 cn 入口):每轮
先按 album/category/photo/asset 逐类分页拉取 cn reconcile「当前状态
事件」并直接签名推送到既有 content-batches 管道。sinceVersion 取 0
(全量当前态)而非 per-type 已应用最大版本——cn reconcile 以类型级
全局版本阈值过滤,类型内单实体滞后会被 max 掩蔽;ov 的 eventId 幂等
+ 版本单调把已追平实体全部判重(recon 确定性 eventId 重扫零成本),
偏差登记:计划原文对账返回「缺失清单」,契约已定为可重放 SyncEvent
数组(免建第二条拉取通道),openapi 描述同步更新
- cn 新增 POST /internal/sync/digest:每相册权威计数 {categoryCount,
publishedPhotoCount, photoCount, assetCount};ov 比对副本计数(照片
取 [publishedPhotoCount, photoCount] 区间口径——hidden/deleted 照片
若从未以 published 态同步过 ov 合法无行,缺席即撤下),不一致相册
自动触发 cn bootstrap 重建;ov-only 相册(cn 行已删,bootstrap 无法
表达删除)告警登记不自动处置
- 收敛语义两处落位:① sync-inbox 版本比较改「严格更旧才拒绝」——
同版本新 eventId(bootstrap/reconcile 快照重发)为当前态幂等重断言
应用,修复 ov 缺失副本行;A26 不受影响(更旧版本仍拒绝,cn 侧
entityVersion 与状态一一对应)② album.updated 快照载荷(bootstrap/
reconcile)携带分类全量清单,ov 存在即整体替换 albums_ov.categories
——修复错过的 category 墓碑(Task 3 登记边界:cn 行已删,无现存实体
事件可重放,唯全量替换可收敛)
- e2e(reconcile.e2e-spec):漏事件追赶(ov v1/cn v5 事件投后即失)→
清扫追平;digest 修复缺失 photos_ov 行(bootstrap 重发 → 同版本
重断言重建);digest 修复丢失的分类墓碑(全量清单替换收敛);稳态
空转(applied=0、无 bootstrap);Task 3 套件保持绿
Co-Authored-By: Claude Code <noreply@anthropic.com>
42 lines
1.8 KiB
Bash
42 lines
1.8 KiB
Bash
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
|
||
CORS_ORIGINS=http://localhost: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 起被 services/sync 读取,其余为
|
||
# 前瞻登记(Task 7+ 逐个接线)。
|
||
SYNC_BATCH_SIZE=100
|
||
SYNC_PUSH_INTERVAL_MS=2000
|
||
SYNC_RECONCILE_INTERVAL_MS=300000
|
||
STAT_RETURN_INTERVAL_MS=60000
|
||
VISIT_WINDOW_MINUTES=30
|
||
LIKE_BATCH_WINDOW_HOURS=24
|
||
VISIT_REQUEST_TTL_MINUTES=35
|