Files
nexus/Project/fonrey/TECH_STACK/客户端发布管理技术方案.md
2026-04-30 20:33:51 +08:00

12 KiB
Raw Blame History

For AI assistants: Read this entire file before writing any code. All decisions here are final. Do not suggest alternatives unless asked.

Fonrey 客户端发布管理技术方案

版本: 1.0
项目: Fonrey 房产经纪管理系统
技术栈: Django 4.x + HTMX + PostgreSQL 16public schema+ Redis + Celery + Electron + electron-updater + Cloudflare R2/CDN
关联 PRD: PRD/发布管理/客户端发布管理模块PRD.mdv1.2
关联数据模型: DATA_MODEL/DATA_MODEL_PUBLIC.mdclient_releases / client_heartbeats
关联枚举字典: DATA_MODEL/ENUMS.md(含中文显示标签)
关联契约规范: TECH_STACK/API_CONTRACT.md
最后更新: 2026-04-30


变更历史

日期 变更人 变更内容
2026-04-30 Atlas 补充“变更历史”章节(文档治理)

一、文档定位与边界

本文件定义客户端发布管理模块(apps/release)的实现口径:

  1. Electron 客户端壳应用与运行时安全边界
  2. EV 代码签名与构建发布链路
  3. Heartbeat 上报与版本分布统计方案
  4. 自动升级、强制升级与失败回退策略
  5. 客户端下载完整性校验SHA256
  6. R2 版本资产管理(对象键、状态流转、回滚)
  7. 公司下载站点(官网)分发方案
  8. 便携版Portable ZIP落地方案

本文件不重复 DDL。表结构与索引以 DATA_MODEL_PUBLIC.md 为唯一权威。


二、范围定义(以 PRD v1.2 为准)

2.1 P0 必须覆盖

  • Windows 客户端win32下载安装与登录使用
  • 平台运营后台版本管理(草稿/发布/下线、普通/强制)
  • 自动更新(启动 + 每 4 小时检测)
  • SHA256 完整性校验EXE/ZIP
  • Heartbeat启动时上报与版本分布/租户活跃统计
  • 官方下载页(公司站点)
  • 便携版 ZIP可选上传、受控分发

2.2 非目标(本期不做)

  • macOS / Linux 客户端
  • 移动端 App
  • 客户端离线模式
  • 客户端反逆向加固v2

三、模块架构边界

3.1 模块职责(apps/release

  • 管理端:客户端版本元数据管理、发布状态流转、回滚
  • 公共接口客户端更新检测、下载引导、Heartbeat 上报
  • 统计接口:版本分布、租户活跃数、历史装机总数
  • 资产管理R2 对象键规范、发布包引用与审计

3.2 分层与鉴权

子能力 Schema 鉴权 说明
版本管理后台 API public Platform Admin 必须认证 跨租户统一运营能力
更新检测 API public 公开(客户端调用) 仅返回当前发布版本,不暴露草稿/下线版本
Heartbeat API public 已登录客户端会话或签名设备票据 防伪造上报、防刷统计
统计 API public Platform Admin 必须认证 提供 Story 5 所需聚合指标

3.3 外部依赖

依赖 用途
Electron + electron-updater 客户端壳应用、更新下载与安装
electron-builder 打包 NSIS EXE + Portable ZIP
EV 代码签名证书 Windows SmartScreen 信任
Cloudflare R2 + CDN 发布包存储与分发
Celery 异步计算 checksum / 文件扫描 / 可选预热

四、API 设计原则

  1. 路径以 PRD 为准:统一使用 /api/release/... 命名空间。
  2. 只允许单一生效版本:同 platform + arch 仅 1 条 published
  3. 公开接口最小暴露:客户端仅获取更新必要字段,不返回后台内部字段。
  4. 统计可信优先Heartbeat 仅“启动上报”,按 (tenant_id, device_id) Upsert。
  5. 完整性优先于安装:校验失败禁止安装,保留当前版本可用。
  6. 强制更新可控release_type=force + min_required_version 双保险。

五、端点清单(核心)

5.1 页面路由(平台运营后台)

路径 方法 鉴权 说明
/platform/release/updates/ GET Platform Admin 版本列表页
/platform/release/updates/new/ GET Platform Admin 新建版本页
/platform/release/updates/{id}/edit/ GET Platform Admin 编辑版本页
/platform/release/metrics/ GET Platform Admin 版本分布与租户活跃榜

5.2 JSON API对齐 PRD + 数据模型)

端点 方法 说明
/api/release/updates/latest/ GET 客户端检查最新版本(公开)
/api/release/updates/ GET 管理端查询版本列表
/api/release/updates/ POST 管理端创建版本(草稿/发布)
/api/release/updates/{id}/ PATCH 修改状态、版本类型、日志
/api/release/updates/{id}/rollback/ POST 回滚至历史版本(原子切换 published
/api/release/heartbeats/ POST 客户端启动上报Upsert
/api/release/metrics/version-distribution/ GET 版本活跃分布
/api/release/metrics/tenant-installs/ GET 指定租户活跃安装数 + 历史装机数
/api/release/metrics/tenant-leaderboard/ GET 全平台租户活跃榜

说明:heartbeats/metrics 为实现 Story 5 与 DATA_MODEL_PUBLIC 聚合查询所需端点,归属同一模块。


六、关键 API 规范(请求/响应)

6.1 更新检测

GET /api/release/updates/latest/?platform=win32&arch=x64&current_version=1.2.0

响应(有更新):

{
  "has_update": true,
  "latest_version": "1.3.0",
  "force_update": false,
  "min_required_version": "1.0.0",
  "download_url": "https://download.fonrey.com/releases/system/v1.3.0/fonrey-setup-1.3.0-win.exe",
  "portable_url": "https://download.fonrey.com/releases/system/v1.3.0/fonrey-portable-1.3.0-win.zip",
  "checksum_sha256": "<exe_sha256>",
  "portable_checksum_sha256": "<zip_sha256>",
  "file_size_bytes": 157286400,
  "release_notes": "## v1.3.0\n- ...",
  "release_date": "2026-05-01"
}

6.2 Heartbeat 上报

POST /api/release/heartbeats/

{
  "device_id": "9e6de37b-8c49-4f9b-af47-52f4e5b8b7f2",
  "client_version": "1.3.0",
  "platform": "win32",
  "arch": "x64",
  "os_version": "Windows 11 23H2"
}

处理要求:

  • 服务端从登录上下文解析 tenant_iduser_id
  • 使用 INSERT ... ON CONFLICT (tenant_id, device_id) DO UPDATE
  • 更新 last_seen_atlaunch_count = launch_count + 1

6.3 版本发布(管理端)

POST /api/release/updates/

{
  "version": "1.3.0",
  "platform": "win32",
  "arch": "x64",
  "release_type": "normal",
  "min_required_version": "1.0.0",
  "download_url": "https://download.fonrey.com/releases/system/v1.3.0/fonrey-setup-1.3.0-win.exe",
  "portable_url": "https://download.fonrey.com/releases/system/v1.3.0/fonrey-portable-1.3.0-win.zip",
  "checksum_sha256": "<exe_sha256>",
  "portable_checksum_sha256": "<zip_sha256>",
  "release_notes": "## v1.3.0\n- ...",
  "status": "published"
}

七、HTMX 交互约定(平台运营后台)

  • 列表筛选(状态/版本号)使用 HTMX 局刷表格区域
  • 发布/下线/回滚操作使用确认弹窗 + 局部刷新
  • 成功:HX-Trigger: toast-success
  • 失败:HX-Trigger: toast-error(同时返回标准错误码)

模板建议:

  • templates/release/updates_list.html
  • templates/release/fragments/updates_table.html
  • templates/release/fragments/version_distribution_chart.html
  • templates/release/fragments/tenant_leaderboard_table.html

八、权限与数据范围

8.1 最小权限矩阵

能力 permission_code
客户端版本列表查看 platform.release.view.allow
创建/编辑发布版本 platform.release.edit.allow
发布/下线/回滚 platform.release.publish.allow
版本分布与租户统计查看 platform.release.metrics.view.allow

8.2 范围规则

  • 所有管理能力仅 Platform Admin 可访问
  • Tenant Admin / Agent 不可访问平台发布后台
  • 数据物理存储在 public schema逻辑上属于平台级共享数据

九、异步任务与缓存策略

9.1 异步任务

任务 触发时机 说明
release_compute_checksum_task 文件上传后 计算 EXE/ZIP SHA256 并回填
release_publish_cdn_warmup_task 版本发布后 可选,预热热点下载节点
release_scan_artifact_task 文件上传后 可选,执行恶意文件扫描与审计

9.2 Redis Key 建议

Key TTL 说明
release:latest:{platform}:{arch} 60s 最新发布版本缓存
release:metrics:version_distribution 60s 版本分布聚合缓存
release:metrics:tenant:{tenant_id} 60s 单租户安装/活跃统计缓存
release:download:ratelimit:{ip} 60s 下载链接接口限流

十、性能与可靠性约束

  • 更新检测接口:p95 < 120ms(缓存命中)
  • Heartbeat 写入:p95 < 80ms
  • 版本列表页:p95 < 200ms
  • 发布状态切换使用事务,保证“下线旧版 + 发布新版”原子完成
  • 任意更新失败不影响当前版本继续运行(可恢复原则)

十一、安全与合规

  1. Electron 必须启用:contextIsolation=truenodeIntegration=falsesandbox=true
  2. 更新包仅允许 HTTPS 下载;域名白名单固定为 download.fonrey.com
  3. EV 证书私钥仅在 CI 密钥库中可用,禁止落盘到开发机。
  4. 校验值由服务端生成并签名传输(至少 TLS + 服务端可信源)。
  5. Heartbeat 接口必须防重放/防刷(鉴权 + 频控 + 审计)。
  6. 管理端操作(发布、回滚、下线)全部记录审计日志。

十二、错误码建议

code HTTP 中文含义
RELEASE_VERSION_INVALID 400 版本号不符合 SemVer
RELEASE_PUBLISHED_CONFLICT 409 当前平台架构已存在发布版本
RELEASE_ARTIFACT_NOT_FOUND 404 发布包不存在或不可访问
RELEASE_CHECKSUM_MISMATCH 400 安装包完整性校验失败
RELEASE_HEARTBEAT_INVALID 400 心跳参数非法
RELEASE_PERMISSION_DENIED 403 权限不足
RELEASE_RATE_LIMITED 429 请求过于频繁

十三、测试映射P0

Story 测试关注点
Story 1 下载安装 官网下载链接可用、签名有效、安装步骤 ≤3、首次启动直达登录
Story 2 客户端使用 Chromium 内核能力、HTMX/Alpine/Tailwind 渲染一致性、文件上传下载
Story 3 自动升级 启动 + 4h 检测、普通更新/强制更新分支、失败可恢复
Story 4 发布管理 版本创建/发布/下线/回滚、唯一 published 约束
Story 5 版本分布 Heartbeat Upsert、活跃统计24h、租户活跃榜排序

测试文件建议:tests/integration/release/test_us_release.py


十四、落地顺序建议

  1. apps/release 模型/服务/API 基础骨架(先打通 /api/release/updates/latest/
  2. 平台运营后台版本管理页(列表 + 新建 + 发布/下线)
  3. Electron 壳应用最小可运行版本(加载 Web + 标题版本)
  4. 自动更新链路electron-updater + 后端 latest API
  5. Heartbeat 上报 + 统计 API + 后台图表
  6. 官网下载页上线(公司域名)
  7. 便携版 ZIP 与企业无安装权限场景验收

十五、文档同步规则

  • PRD 发布管理模块变更:同步本文件
  • client_releases/client_heartbeats 字段变更:同步 DATA_MODEL_PUBLIC.md
  • 枚举值变更:同步 DATA_MODEL/ENUMS.md(含中文标签)
  • API 包络/错误契约变更:同步 TECH_STACK/API_CONTRACT.md
  • 若将来新增独立测试用例文档:同步 TECH_STACK/测试规范.md 与测试用例注册表

附:你关注的 8 个专题落地结论

  1. Electron 方案:采用 Electron + electron-updater客户端坚持“壳应用”原则。
  2. EV 证书方案CI 自动签名,证书私钥仅在密钥管理系统。
  3. Heartbeat 方案:仅启动上报,(tenant_id, device_id) Upsert支撑活跃与版本分布。
  4. 自动升级方案:启动 + 每 4h 轮询,普通/强制双模式,失败可恢复。
  5. 完整性验证:下载后先 SHA256 校验,再安装;失败禁止覆盖当前版本。
  6. R2 版本管理releases/system/v{version}/... 路径规范,发布状态驱动可见性。
  7. 公司网站下载download.fonrey.com 静态下载页 + 版本信息 + 更新日志。
  8. 便携版实现electron-builder 输出 ZIP首次运行写入用户目录配置不修改系统级安装。