XuqmGroup-Server/docs/SDK_PLATFORM_V2_HANDOFF.md

5.8 KiB

SDK 平台 V2 实施与接手说明

更新时间2026-07-26。本文记录当前源码事实与尚未执行的部署动作;不得把本文当作生产环境已发布证明。

当前边界

  • Config 文件唯一格式为 XUQM-CONFIG-V2,V1 不再接受。
  • Config 文件由租户服务生成;客户端只验证签名、有效期和包名,不在线检查吊销状态。
  • BugCollect 运行时上报失败不得影响宿主业务;服务关闭时固定返回 HTTP 403,消息码为 BUGCOLLECT_DISABLED
  • 构建产物上传唯一入口为 POST /bugcollect/v1/artifacts/upload
  • 已废弃的 App 离线激活 license 服务已从聚合构建、租户服务、网关和 Web 入口删除;它与签名 SDK 无关。

Config 文件契约

格式:

XUQM-CONFIG-V2.<keyId>.<salt>.<iv>.<ciphertext>.<signature>
  • 内容加密AES-256-GCM。
  • 密钥派生PBKDF2-HMAC-SHA256,120000 次。
  • 完整性与发布方身份Ed25519 对前五段的 ASCII 原文签名。
  • 时间统一使用 UTC Instant
  • 重新生成会产生新的 configId 和递增 revision;旧文件只在后续构建时被拦截,不影响已安装客户端运行。
  • 构建校验接口:
POST /api/sdk/build/config/validate
Content-Type: application/json

{"content":"...","packageName":"com.example.app"}

签名密钥只能由运行环境注入:

  • SDK_CONFIG_SIGNING_KEY_ID
  • SDK_CONFIG_SIGNING_PRIVATE_KEY_BASE64PKCS#8 DER Base64
  • SDK_CONFIG_SIGNING_PUBLIC_KEY_BASE64X.509 DER Base64

公共互操作向量位于 common/src/test/resources/xuqm-config-v2-vector.json。私钥不得进入仓库、日志或普通文档。

SDK 动态配置

GET /api/sdk/config 的功能开关按 appKey + platform + serviceType 精确读取。版本更新登录要求来自 update-service 的权威字段 allowAnonymousUpdateCheck,对外返回 updateRequiresLogin

租户服务访问 update-service 使用 500ms 连接超时、800ms 读取超时和 15s 小 TTL 缓存。依赖不可用时安全返回 updateRequiresLogin=true

BugCollect 产物契约

构建工具必须携带:

Authorization: Bearer <XUQM_API_TOKEN>

Token 复用租户平台 API Key 权威校验,不存在 BugCollect 私有密钥。认证得到的 appKey 必须和上传表单中的 appKey 相同。 该产物端点只接受 Bearer 形式,单独传 X-API-Key 必须返回 401;通用业务接口原有的 X-API-Key 过滤行为不变。微服务向租户服务校验 Token 时使用受内部令牌保护的 POST /api/internal/sdk/validate-api-key JSON 请求体,严禁把 Token 放入 URL、查询参数或日志。

共同字段:

  • artifactType
  • appKey
  • platform
  • appVersion
  • buildId
  • file

RN_SOURCEMAP 额外要求 moduleIdmoduleVersionbundleHash,以完整七元组精确匹配,不允许“取最新”回退。source map 不允许内嵌 sourcesContentsources 不允许绝对路径、Windows 盘符或 .. 穿越。

R8_MAPPING 仅支持 Android,文件名必须为 mapping.txt,并要求 artifactHash 与文件 SHA-256 一致。R8 与 RN 产物独立保存和查询。

运行时 /issues/batch/events/batch 不使用 CI API Token;它们继续遵循客户端签名与服务开关策略。

数据库迁移

  • tenant-serviceV3 Config V2 元数据、V4 平台专属 App 包名、V5 移除离线 license 服务数据和枚举值。
  • xuqm-bugcollect-serviceV9 引入精确 bundle 身份和独立产物字段。

执行迁移前必须备份对应数据库。不得修改已在目标环境执行过的历史迁移文件。

Web 与 Jenkins

  • 应用详情页展示 Config 签发元数据,并支持“长期有效”或选择 UTC 到期时间后重新生成。
  • 符号化产物页同时展示 RN sourcemap 和 R8 mapping。
  • Web 依赖管理统一使用仓库声明的 Yarn 1;不再保留不同步的 package-lock.json
  • Server 与 tenant-web Jenkins 默认 DEPLOY_ENV=development,development 只验证,不推送、不部署、不提交版本号。
  • production 必须经过人工确认,并从 Jenkins Credentials 读取 Git 与 Config 签名凭据。

已执行验证

mvn -Dmaven.repo.local=/private/tmp/xuqm-m2 \
  -pl tenant-service,xuqm-bugcollect-service -am test

2026-07-26 结果BUILD SUCCESS。common 共 3 项测试通过,tenant-service 共 3 项测试通过, xuqm-bugcollect-service 共 7 项测试通过;覆盖 Config 向量、通用 X-API-Key 行为、 受保护的内部 POST 请求体、更新配置失败安全缓存、BugCollect 固定错误、路径校验、 R8 校验,以及产物 API Token 的无 Bearer、仅 X-API-Key、无效 Bearer、有效归属场景。

Server 全聚合 mvn -DskipTests compile 结果BUILD SUCCESS,聚合构建中已不包含 license-service。

Web 验证命令:

yarn install --frozen-lockfile
yarn build:tenant
yarn build:ops
yarn workspace @xuqm/docs-site build

2026-07-26 三项 Web 构建均通过。最终结果以当前任务交接记录为准。

尚未执行

  • 未提交、未推送。
  • 未触发 Jenkins,未部署任何环境。
  • 未运行真实 MySQL 迁移。
  • Jenkins 中的 Git、Config 签名凭据以及生产主机运行环境变量必须由有权限的维护者配置后,才能进行生产发布。

2026-07-27 Jenkins SCM 凭据收口

  • Server 流水线的显式 checkout 已改用 Gitea SSH URL 和 Jenkins jenkins-ssh-key,不再引用未配置的 XUQM_GIT_CREDENTIALS,也不允许在 URL 中嵌入用户名、密码或访问令牌。生产版本回写的 pull/push 同样放入 sshagent(jenkins-ssh-key),不依赖 checkout 步骤的临时认证环境。
  • 该修改尚未通过下一次 Server Jenkins 构建验证;触发部署前应先执行一次只构建不 部署的流水线或确认 checkout 阶段成功。