Super Productivity SuperSync Server 部署与架构指南:基于 PostgreSQL 的追加写同步服务
发布时间:2026/9/13 3:48:43 作者:尧图编辑部 阅读量:1,286

Super Productivity SuperSync Server 部署与架构指南基于 PostgreSQL 的追加写同步服务【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivitySuperSync Server 是 Super Productivity 项目自带的专用同步服务端采用操作日志Event Sourcing风格的追加写协议替代 WebDAV专为客户端的高效同步需求设计。本文以该服务的官方文档为主体结合仓库中的部署脚本、环境变量模板、Compose 配置与源码实现完整讲解其架构模型、Docker 与手动两种部署路径、全部环境变量、认证与同步 API、维护脚本、安全特性以及多实例部署的边界条件帮助读者独立搭建并运维一套可用的同步后端。核心架构追加写保留式操作日志SuperSync Server 本质上是一个经过认证的 PostgreSQL 中继、排序与上传冲突仲裁服务。它并不理解应用状态语义而是忠实记录客户端上传的原子操作并为每个用户维护严格的顺序。其数据模型建立在PostgreSQL通过 Prisma ORM之上的追加写保留式操作日志Operations操作客户端上传原子操作Create 创建、Update 更新、Delete 删除、Move 移动以及SYNC_IMPORT、BACKUP_IMPORT、REPAIR等全量状态操作。Sequence Numbers序列号服务器为当前同步数据集内的每个用户分配严格递增的server_seq作为该用户操作的全序编号。Synchronization同步客户端请求序列号 X 之后的所有操作实现增量拉取。Full-state boundaries全量状态边界客户端可以通过因果全量状态操作快速前进可选的明文缓存支持服务端重放与恢复。关键设计原则原则说明受限的服务端权威服务端只负责每个用户的操作顺序与上传接受结果不裁决应用状态语义两段式冲突处理服务端检测上传冲突客户端负责解决被拒绝的操作与下载侧并发端到端加密支持可选的负载加密路由与因果元数据保持明文幂等上传持久化的操作 ID 唯一性作为兜底请求 ID 额外提供五分钟的进程本地缓存从源码结构看这条设计边界在 packages/super-sync-server/docs/architecture.md 中被明确为所有权与信任边界服务端是每个用户保留操作顺序和上传接受结果的权威而sp/shared-schema拥有 HTTP 线上契约见 packages/shared-schema/src/supersync-http-contract.tssp/sync-core拥有客户端与服务端共享的向量时钟算法。全系统视角可参考 docs/sync-and-op-log/sync-architecture.html同步架构现场指南。快速开始Docker 部署推荐SuperSync 最快捷的运行方式是使用仓库内提供的 Docker Compose 配置。部署主机需要具备 Docker含 Compose 插件、curl、git与jq镜像修订检查要求 Docker Compose 支持docker compose config --format json。镜像没有发布标签。官方镜像ghcr.io/super-productivity/supersync只发布latest与master-sha两个标签且都构建自master因此默认部署跟踪的是上游master而非某个发布版本。需要固定版本时请将SUPERSYNC_IMAGE锁定为具体的master-sha标签。部署步骤# 1. 克隆仓库deploy.sh 从这个 checkout 运行并进入本目录 # 如果你已有一份仓库 checkout直接 cd 到对应目录即可 cd 仓库根目录/packages/super-sync-server # 2. 复制环境变量示例 cp env.example .env # 3. 配置 .env必须设置 JWT_SECRET、DOMAIN、POSTGRES_PASSWORD nano .env # 4. 部署整个栈并执行数据库迁移 ./scripts/deploy.shdeploy.sh 的行为细节./scripts/deploy.sh是生产部署的唯一推荐入口它按顺序完成以下工作对应 packages/super-sync-server/scripts/deploy.sh校验 Caddyfile 语法用 compose 中指定的 Caddy 镜像执行caddy validate。拉取镜像默认从注册表拉取--build时改为本地构建。先迁移后替换在替换应用容器之前执行prisma migrate deploy让在线索引构建在旧应用仍对外服务时完成迁移失败会直接终止部署。拉起整个栈并验证健康端点等待所有容器通过健康检查再通过 HTTPS 探测/health。关于--build./scripts/deploy.sh --build会在部署主机上编译整个 monorepo与正在运行的栈并行耗时数分钟且峰值内存需额外超过 1.5 GB容器本身约预留 2.5 GB每次构建还会积累约 1.4 GB 且永不自动清理的 BuildKit 缓存。小内存 VPS 上优先使用拉取镜像或在其他机器构建后设置SUPERSYNC_IMAGE需传递相同的VCS_REF。--build还拒绝在镜像输入存在未提交或未跟踪改动时执行错误信息会列出具体文件。为什么不能用docker compose up代替容器启动时迁移默认是禁用的RUN_MIGRATIONS_ON_STARTUP默认false以避免应用重启与部署迁移器产生竞态。因此docker compose pull docker compose up -d可能让应用跑在未应用的迁移之上——生产更新请始终使用./scripts/deploy.sh。镜像修订检查deploy.sh会校验拉取/构建的supersync镜像的org.opencontainers.image.revision标签是否与影响 SuperSync 镜像输入的最新提交一致防止部署脚本在过期的镜像上运行迁移。如果你发布自定义镜像请在 Docker 构建时传入相同源码修订作为VCS_REF仅当刻意手动覆盖时才设置SUPERSYNC_SKIP_IMAGE_REVISION_CHECKtrue。迁移过程中的注意事项CREATE INDEX CONCURRENTLY阻塞与超时部分迁移使用CREATE INDEX CONCURRENTLY在繁忙数据库上会被长事务阻塞。应用 schema 变更建议安排在非高峰时段并适当调高MIGRATION_TIMEOUT秒默认900。deploy.sh退出码124表示迁移超时——待阻塞事务结束后重跑即可。设置了自身短lock_timeout的锁受限 reloption 迁移如operations_entity_ids_gin会快速失败而非排队并被原生地有限重试若每次尝试都超时它会保持回滚状态需要清理阻塞事务后重新部署。Prisma 迁移失败码如果部署在 Prisma 记录某个迁移失败后被中断后续部署可能以P3009停止包含CREATE/DROP INDEX CONCURRENTLY的迁移无法在单个事务块中运行可能触发P3018。镜像内的 packages/super-sync-server/scripts/migrate-deploy.sh 会通用地处理安全 drop-then-create 并发索引场景必要时解决失败记录、在 Prisma migrate 之外应用迁移 SQL、标记迁移已应用并重试migrate deploy。它还会原生重试锁受限的 reloption 迁移按迁移形状识别绝不按名称其余所有失败形状都会停下来等待人工审查。0_init基线迁移链现在以创建基础表的0_init基线开始全新数据库可以仅凭迁移完成初始化。而 schema 早于该基线的既有数据库必须在下次部署前告诉 Prisma 其 schema 已反映哪些迁移否则migrate deploy会尝试重建已存在对象而失败报relation users already exists或P3005。这同样适用于无人值守部署路径Helm 的migrate-dbinitContainer 与 Docker 的RUN_MIGRATIONS_ON_STARTUPtrue启动。有既有 Prisma 迁移历史旧迁移记录在_prisma_migrations只标记基线为已应用。npx prisma migrate resolve --applied 0_init用prisma db push创建的数据库无迁移历史其逻辑 schema 已匹配最新schema.prisma但db push无法表达存储 reloptionoperations_entity_ids_gin的 fastupdate 设置与operations表的 autovacuum 因子。需要先用prisma db execute以显式事务应用两个数据库级状态并清空旧的 pending list再逐个prisma migrate resolve --applied标记整个链( set -e printf %s\n \ BEGIN; \ SET LOCAL lock_timeout 1s; \ ALTER INDEX operations_entity_ids_gin SET (fastupdate off); \ COMMIT; | npx prisma db execute --schema prisma/schema.prisma --stdin printf %s\n \ BEGIN; \ SET LOCAL lock_timeout 5s; \ ALTER TABLE operations SET (autovacuum_vacuum_insert_scale_factor 0.02); \ COMMIT; | npx prisma db execute --schema prisma/schema.prisma --stdin printf %s\n \ BEGIN; \ SET LOCAL statement_timeout 300s; \ SELECT gin_clean_pending_list(operations_entity_ids_gin); \ COMMIT; | npx prisma db execute --schema prisma/schema.prisma --stdin for m in prisma/migrations/*/; do npx prisma migrate resolve --applied $(basename $m) done )注这仅补齐 reloption 缺口——20260512000000、20260514000000和20260514000002中的部分索引同样无法用db push表达仍是已知缺口与schema.prisma中的部分索引注释对应。全新数据库无需任何上述操作migrate deploy会自动应用0_init及后续整个迁移链。本地开发数据库对本地prisma migrate devshadow 数据库同样需要把含CREATE INDEX CONCURRENTLY的迁移放到事务外通过prisma db execute应用后再标记迁移镜像生产部署的绕过方案。外部 PostgreSQL如果DATABASE_URL指向外部 PostgreSQL将POSTGRES_SERVICE设为空值deploy.sh就只启动 app/proxy 服务关闭 compose 依赖不再要求捆绑的 Postgres 容器Prisma 迁移仍针对配置的DATABASE_URL运行。版本下限受支持的版本是 PostgreSQL 16 或更新版本CI 与生产环境均运行它捆绑 compose 镜像是postgres:16-alpine。PostgreSQL 14/15 仍可工作并接收全部迁移migrate-deploy.sh会警告并继续只是不在测试套件覆盖范围内。Linux 主机上的 PostgreSQL 14 是硬性下限由连接而非文档强制迁移管道在连接上设置client_connection_check_interval使被遗弃的CREATE INDEX CONCURRENTLY能自我取消而非持有表锁更老或非 Linux 的服务器会以 FATALunrecognized configuration parameter拒绝该启动选项。应用回滚如果本次部署后测量的插入延迟回退可以恢复 PostgreSQL 默认设置作为一个单独审批的数据库变更执行printf %s\n \ BEGIN; \ SET LOCAL lock_timeout 1s; \ ALTER INDEX operations_entity_ids_gin RESET (fastupdate); \ COMMIT; | npx prisma db execute --schema prisma/schema.prisma --stdinPayload 字节回填回填对启动是可选的增量存储计数器没有它也能工作。但当一个用户仍有payload_bytes 0的旧行时该用户的精确配额对账会被延迟服务器拒绝用近似和覆盖精确计数器。要让旧账户的配额对账生效请运行回填npm run migrate-payload-bytes在源码 checkout 且尚未npm run build时使用npm run migrate-payload-bytes:dev手动搭建开发环境不使用 Docker 时可按以下步骤在本地运行# 安装依赖 npm install # 生成 Prisma Client npx prisma generate # 设置 .env cp env.example .env # 编辑 .env将 DATABASE_URL 指向你的 PostgreSQL 实例并设置 JWT_SECRET # 和 POSTGRES_PASSWORD —— 两者默认均为空服务器缺了它们拒绝启动 # 向数据库推送 schema npx prisma db push # 启动服务器 npm run dev # 或构建并运行 npm run build npm start配置全部环境变量所有配置都通过环境变量完成。以下为核心配置总表默认值与env.example及 packages/super-sync-server/docker-compose.yml 一致变量默认值说明PORT1900服务器端口HOST0.0.0.0服务器绑定地址IPv6 独占部署用::DATABASE_URL-PostgreSQL 连接串如postgresql://user:passlocalhost:5432/dbJWT_SECRET-必填。用于签署 JWT 的密钥至少 32 字符PUBLIC_URL-必填。邮件链接使用的公开 URL如https://sync.example.com。NODE_ENVproductionDocker 默认下必须以https://开头否则拒绝启动CORS_ORIGINShttps://app.super-productivity.com允许的 CORS 来源。*允许任意来源——生产环境禁用因为 CORS 以credentials: true运行SMTP_HOST-发信 SMTP 服务器WEBAUTHN_RP_IDlocalhostpasskey 必填。你的域名不带协议与端口。passkey 与它绑定——改动会使所有已注册凭据失效WEBAUTHN_ORIGINhttp://localhost:1900passkey 必填。用户访问认证 UI 的地址带协议WEBAUTHN_RP_NAMEWEBAUTHN_RP_ID的值用户系统 passkey 提示中显示的名称ALLOWED_EMAILS-任何人可注册逗号分隔的精确地址和/或*domain规则SUPERSYNC_DEFAULT_STORAGE_QUOTA_BYTES104857600100 MB之后创建账户的配额已有账户保留其行上存储的值必填项与初始化注意事项env.example中的三个必填值在模板里刻意留空一个随镜像分发的占位符就是公开已知的签名密钥因此服务器在生成自己的密钥之前拒绝启动。推荐生成方式openssl rand -base64 32 # 用于 JWT_SECRET≥32 字符 openssl rand -base64 24 # 用于 POSTGRES_PASSWORD此外.env还需设置DOMAIN不带https://的域名Caddy 会自动为该域名申请 SSL 证书与PUBLIC_URL。SMTP 配置SMTP_HOST、SMTP_PORT默认 587、SMTP_SECURE、SMTP_USER、SMTP_PASS、SMTP_FROM是邮件验证链路所必需的。数据库连接串的高级参数env.example对DATABASE_URL给出了一条重要的工程建议务必附加?connection_limitNpool_timeout10来约束 Prisma 连接池。Prisma 的默认池大小约为主机 CPU 数 × 2读取的是宿主核心数而非容器 CPU 限制——在多数核主机上无界连接池会静默耗尽 postgres 的max_connections上限compose 内为 120导致迁移、psql、旧操作清理任务与崩溃恢复后的重连风暴挤不到连接出现sorry, too many clients already。N 应远低于max_connections如 60。compose 默认的DATABASE_URL已携带这些参数一旦手动设置该变量这些参数不会被继承必须显式带上DATABASE_URLpostgresql://supersync:passwordexample.com:5432/supersync?connection_limit60pool_timeout10env.example还记录了可选的恢复护栏通过...options-c%20statement_timeout%3D60000设置全局语句超时保持%20与%3D编码避免单个退化查询计划占住连接池导致整个池耗尽、所有用户同步失败。注意它默认不启用_computeSnapshotVectorClock见packages/super-sync-server/src/sync/services/operation-download.service.ts会在持久化快照时钟元数据缺失/过期/无效时聚合用户全量历史的向量时钟长历史账户可能合法超过 60 秒。迁移器与监控脚本会分别用自己的超时覆盖该上限。法律页面Legal pages镜像不内置任何服务条款也不会在你表明自己是数据控制者之前提供隐私政策——这是刻意设计官方文档以德国法律、莱比锡法院地及其联系方式命名若在你的域名下发布这些文档等于以你的名义做出虚假的法律声明。必须全部设置以下五个变量才会发布/privacy.html并显示注册同意提示全部不设置则完全不提供法律页面只设置一部分是启动错误而非静默降级变量说明PRIVACY_CONTACT_NAME控制者名称个人或公司PRIVACY_ADDRESS_STREET街道地址PRIVACY_ADDRESS_CITY邮编与城市PRIVACY_ADDRESS_COUNTRY国家PRIVACY_CONTACT_EMAIL数据保护请求的联系邮箱PRIVACY_DATA_REGION与上述五项相互独立设为EU或EEA会在落地页显示Data hosted in EU徽章任何其他值都不显示徽章。两个可选段落未设置时整体从政策中省略PRIVACY_HOSTING_PROVIDER第三方处理数据的托管商与PRIVACY_SUPERVISORY_AUTHORITY对你主管的监督机构不设置时政策引导用户联系其居住地机构。要发布你自己的服务条款把 HTML 放到DATA_DIR/legal/terms.html启动时会被复制到/terms.html并从同意提示中链接。使用捆绑 compose 文件意味着要 bind-mount 它见docker-compose.yml中被注释的示例由scripts/deploy.sh驱动的部署可在.env中设置SUPERSYNC_INSTALL_REPO_TERMStrue在每次部署时把 checkout 里的legal/terms.html同步进数据卷——仅当 checkout 中该文件确实属于你时才这么做。附带模板只是起点而非法律建议发布前务必对照实际运营方式逐节审查。API 端点认证生产环境的账户创建与登录使用passkey 或邮件 magic link没有生产可用的密码式/api/register或/api/login端点。端点组用途/api/register/passkey/*开始与验证 passkey 注册/api/register/magic-link注册仅邮件账户/api/verify-email激活账户对 passkey 注册还激活其绑定凭据/api/login/passkey/*开始与验证 passkey 认证/api/login/magic-link*请求与消费一次性登录链接/api/recover/passkey*通过邮件令牌恢复后替换 passkey/api/replace-token撤销所有更早的 JWT 并返回替代令牌从源码看可执行路由与 schema 位于 packages/super-sync-server/src/api.ts令牌行为位于 packages/super-sync-server/src/auth.tsWebAuthn 行为位于 packages/super-sync-server/src/passkey.ts。更完整的生命周期与安全边界见 packages/super-sync-server/docs/authentication.md。其中的关键机制包括Passkey 注册采用待定机制服务器验证 WebAuthn 仪式但不立即信任提交的凭据而是将其存储为绑定到精确邮件验证令牌的PendingPasskeyRegistration令牌被消费时服务器原子地验证用户、删除该账户其他待定/活动凭据只提升与该链接绑定的凭据。JWT 生命周期JWT 签名但不作为会话存储携带userId、email、tokenVersion有效期 365 天。校验后账户字段在进程本地缓存 30 秒以避免每次请求查库账户删除、验证、令牌替换与恢复会使本地缓存失效。邮件令牌即凭据验证24 小时、magic login15 分钟、passkey 恢复1 小时令牌是 32 随机字节的明文存储值属一次性且由受保护的数据库更新消费。包含未过期令牌的数据库转储、应用日志与代理日志必须视为凭据泄露。WebSocket 令牌传输WebSocket 握手使用与 HTTP 相同的全访问 365 天 JWT经token查询参数传递不是更窄的仅 WebSocket 凭据。同步所有 HTTP 同步端点都要求 bearer 认证Authorization: Bearer jwt-token。1. 上传操作——把新变更发给服务器POST /api/sync/ops2. 下载操作——获取其他设备的变更GET /api/sync/ops?sinceSeq1233. 同步状态诊断——检查同步状态与存储信息生产客户端不使用供运维/调试GET /api/sync/statusdocs/architecture.md中记录了更完整的稳定 API 表面POST /api/sync/snapshot上传SYNC_IMPORT、BACKUP_IMPORT或REPAIR全量状态操作、DELETE /api/sync/data擦除用户同步数据集并重置序列状态、GET /api/sync/restore-points列出因果全量状态重放边界、GET /api/sync/restore/:serverSeq在保留的序列号处重建明文状态以及GET /api/sync/ws仅通知其他客户端有新操作绝不流式传输操作负载负载始终走 HTTP。不存在GET /api/sync/snapshot端点。线上形状由 packages/shared-schema/src/supersync-http-contract.ts 所有——例如操作类型常量CRT/UPD/DEL/MOV/BATCH/SYNC_IMPORT/BACKUP_IMPORT/REPAIR、单次上传最多 100 个操作、错误码词表CONFLICT_CONCURRENT、STORAGE_QUOTA_EXCEEDED、RATE_LIMITED等都定义于此。客户端配置在 Super Productivity 中配置 Custom Sync自定义同步提供者Base URL基础地址https://sync.your-domain.com或你的部署地址Auth Token认证令牌登录得到的 JWT维护脚本服务端提供了若干管理脚本均使用配置好的数据库# 删除一个用户账户 npm run delete-user -- userexample.com # 清空同步数据保留账户 npm run clear-data -- userexample.com # 清空全部同步数据危险操作 npm run clear-data -- --all从 packages/super-sync-server/package.json 还可以看到更完整的运维命令族npm run docker:backup备份、npm run docker:monitor及docker:monitor:all监控、npm run dry-run-old-ops-sweep只读演练旧操作清扫、npm run monitor/analyze-storage存储分析等。其中旧操作清理按有界批次删除单条 DELETE 语句以 serverSeq 窗口为宽度默认OLD_OPS_CLEANUP_DELETE_BATCH_SIZE5000单轮上限OLD_OPS_CLEANUP_MAX_DELETED_PER_RUN25000清扫每天只跑一次——若保留策略长期失效形成积压如 440 万行默认速率约需半年才能清完应按实际数字临时调大预算再用dry-run-old-ops-sweep验证后恢复。安全特性特性实现认证passkey 或 magic-link 登录签发 JWT bearer 令牌枚举抵抗中性的邮件流程响应与 dummy passkey 选项输入验证验证操作 ID、实体 ID、schema 版本速率限制按路由的认证限制与按用户的同步限制向量时钟消毒共享 schema 限制仅在冲突检测后修剪实体类型白名单防止注入非法实体类型请求去重五分钟进程缓存加持久化操作 ID 唯一性全账户 JWT 撤销令牌版本化加 30 秒进程本地认证缓存安全注意事项生产环境务必将JWT_SECRET设为安全随机值≥32 字符。若你在env.example停止附带占位符之前部署过请立即检查.env早期版本随附JWT_SECRETyour-secure-jwt-secret-minimum-32-characters32 字符能通过校验。若你的.env仍是它签名密钥就是公开的——任何人可为任意用户铸造令牌。用openssl rand -base64 32替换并重启轮换会使所有已签发令牌失效所有用户需重新登录。将邮件验证、登录与恢复链接视为凭据。其令牌当前明文存储过期防止使用但不是通用的自动删除边界。详见 packages/super-sync-server/docs/authentication.md。生产环境必须使用 HTTPS 与 WSS。所有反向代理日志设置都必须从访问日志与请求失败/错误日志中省略敏感查询值与携带令牌的Referer头登录与恢复页面必须发送Referrer-Policy: no-referrer。仓库附带的 packages/super-sync-server/Caddyfile 会替换完整日志查询后缀、从两条 Caddy 日志路径删除Referer并提供响应策略——这是必要的因为 WebSocket 经?tokenJWT认证且该 JWT 365 天有效若不过滤每次 WS 升级都会把一个整年有效的全同步凭据写进 stdout/docker logs。应用错误日志器同样替换完整查询后缀。自定义部署必须提供等价保护。生产环境限制 CORS 来源CORS_ORIGINS支持子域通配符https://*.example.com切勿在生产使用*。建议为生产部署配置数据库备份详见 packages/super-sync-server/docs/backup-and-recovery.md。多实例部署的边界条件捆绑的 Helm chart 刻意将 SuperSync 限制为单副本。自定义多实例部署在提供同等保证前必须处理以下进程本地状态认证缓存与撤销问题成功的 JWT 验证会把账户的验证与令牌版本状态在每个进程缓存 30 秒。令牌版本写入只使执行该写入的进程失效。影响令牌替换、passkey 恢复或账户删除后另一个副本在最坏情况下仍可接受此前缓存的 JWT剩余缓存 TTL 内。令牌替换与 passkey 恢复还会强制关闭该账户的 WebSocket 连接但仅限处理请求的实例——其他副本上已撤销设备的 socket 在下次重连失败前仍持续收到操作通知仅元数据不含操作数据。多实例方案使用共享失效或集中验证。一致性按账户路由可缩小暴露窗口但不是共享失效的通用替代。Passkey 挑战存储问题WebAuthn 挑战存储在内存 Map 中跨实例无效。症状挑战生成请求命中实例 A、验证请求命中实例 B 时passkey 注册/登录失败。多实例方案实现共享挑战存储或对完整 WebAuthn 仪式使用粘性会话。当前状态生产启动时会记录内存存储的警告日志。快照生成锁问题并发快照生成防护使用内存 Map。症状同一用户可能在不同实例触发重复的快照计算。影响仅性能影响无数据损坏——快照是确定性的。多实例方案实现 Redis 分布式锁可选仅性能考虑。请求与配额协调问题请求结果去重、进行中的存储对账与强制存储对账标记都是进程本地的。影响路由到另一实例的重试可能被重算但持久化操作 ID 唯一性仍阻止同一操作被插入两次。强制存储计数器对账信号不跨进程重启或迁移存活后续精确对账必须自愈任何偏差。单实例部署单实例部署不适用上述跨实例限制但进程重启仍会清空内存协调状态。源码级实现佐证排序、事务与 E2EE 边界如需深入原理packages/super-sync-server/docs/architecture.md 提供了权威细节几个关键点如下每用户排序与事务不变式serverSeq是单个用户当前同步数据集内的全序。被接受的上传在 PostgreSQLRepeatableRead事务内提交每次被接受的操作通过一次对user_sync_state.lastSeq的原子更新保留其序列号并串行化该用户的写入者。读到了同一更早快照的并发事务必须失败重试而非提交冲突操作。因果REPAIR额外锁定该行并须证明repairBaseServerSeq lastSeq。干净的全量状态上传删除先前数据集但保留lastSeq防止既有客户端看到序列号复用只有显式DELETE /api/sync/data会擦除整个数据集并将序列重置为零。该串行化机制是承重设计决策见 ARCHITECTURE-DECISIONS.md 中 ADR #4实现位于 packages/super-sync-server/src/sync/sync.service.ts 与 packages/super-sync-server/src/sync/services/operation-upload.service.ts。存储、保留、快照与恢复点operations表追加写但并非永久保留行在被保留期间不可变清理、配额回收、干净替换与显式数据删除可移除它们。默认保留期为 45 天。清理只会在已证明的因果全量状态边界之前移除旧操作前缀同时保留该边界及其重放尾部边界来自操作流本身而非快照游标因此纯加密与无快照历史同样可被修剪。加密全量上传仍是操作但无法成为服务器可读的状态缓存——服务器生成恢复在所需重放范围包含加密操作时不可用。持久化权威是 packages/super-sync-server/prisma/schema.prisma保留与重放逻辑位于src/sync/cleanup.ts、storage-quota.service.ts、snapshot.service.ts与op-replay.ts。E2EE 边界启用 SuperSync E2EE 时只有operation.payload被客户端加密服务器无密钥并以其为不透明值存储。路由与因果元数据操作与客户端 ID、action 与操作类型、实体 ID、向量时钟、时间戳、schema 版本、导入原因与加密标志保持明文供校验、排序与冲突检测使用。AES-GCM 标签不认证明文元数据因此 E2EE 提供负载机密性与完整性而非元数据机密性或完整操作的端到端真实性详见 docs/sync-and-op-log/supersync-encryption-architecture.md。测试保障承重的 PostgreSQL 竞态覆盖在tests/integration/仓库内packages/super-sync-server/tests/integration/尤其是 repair-causality、clean-slate 原子性、冲突检测与快照向量时钟套件package.json中列出了完整集成测试清单涉及注册竞态、批量冲突计划、状态替换守卫、旧操作清扫、迁移部署锁重试等场景。托管部署的实测 I/O 上限及其对查询编写的影响见 packages/super-sync-server/docs/production-capacity.md。小结SuperSync Server 以追加写操作日志 每用户严格序列 服务端冲突检测的简洁模型为 Super Productivity 提供了高吞吐的专用同步后端。生产部署应始终经由./scripts/deploy.sh先迁移后替换、镜像修订校验、在线索引迁移恢复配置上务必守住四条底线随机的JWT_SECRET、PUBLIC_URL使用 HTTPS、WEBAUTHN_RP_ID/ORIGIN与域名一致、CORS 来源收窄。理解多实例边界与 E2EE 边界后无论是单机自托管还是更大规模部署都能据此做出正确的架构取舍。【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考