1
03-tech-stack
ila edited this page 2026-08-07 16:36:15 +08:00
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.

同步来源:docs/03-tech-stack.md · commit afc651f75a3a

技术栈

“用什么”的权威速查表。状态为“待验证”的项不能在代码中当作既成事实。

技术栈一览

维度 选型 状态 说明
Android 基础 Roubao main 的 Kotlin 原生 Android 代码,应用版本 1.4.2 已接入并构建 固定 main@c8a6d7f...,来源与调整见 android-buyer/UPSTREAM.md。
Android IDE/JDK Android Studio Hedgehog 2023.1.1 或更高;JDK 17 JDK/CLI 已验证,IDE 可选安装 命令行构建不依赖 Android Studio;首次用 IDE 导入时不接受自动升级。
Android 构建链 Gradle 8.2;AGP 8.2.0;Kotlin 1.9.20;JVM target 17 已验证 已补齐上游缺失的 gradlew.bat,不依赖全局 Gradle。
Android SDK compileSdk/targetSdk 34;minSdk 26;SDK Build Tools 34.0.0 已验证 支持 Android 8.0+;本机使用 Command-line Tools 22.0。
Android UI Jetpack Compose + Material 3;Compose Compiler 1.5.5 上游已核实 Compose BOM 为 2023.10.01。
Android 自动化 AccessibilityService 语义节点动作;Shizuku 保留为上游兼容路径 搜索与 5 个候选已真机验证 T-101/T-102 已完成精确输入、结果页确认、候选卡识别、详情截图和验证返回;没有坐标或 shell 降级。上游 main 仍保留 Shizuku 13.1.5。
Android 候选证据 API 30+ AccessibilityService.takeScreenshot + App cache JSON/PNG 已真机验证 匿名 PNG 与只含 SHA-256、计数、尺寸的 manifest;转换/压缩使用独立 executor,文件 IO 使用 Dispatchers.IO。API 26-29 明确不支持该截图探针。
第一层任务源 UTF-8 无 BOM 四行蝦皮订单文本 + 同订单号 JPEG 已实现 task-contract 共享 ProbeTask/TaskSource;CLI 输出到 .local/,只有显式 Debug 属性才注入 APK,默认构建会清除私有资产。
Android 长任务 前台服务 + 持续通知 T-207 已实现 30 秒 heartbeat、加密状态恢复、离线截止、SAFE_STOPPED 和加密结果 outbox。
后端语言 Go 1.23.0 MVP 已定 与现有本机工具链一致;构建测试必须设置 GOTOOLCHAIN=local 防止静默升级。
后端骨架 Go Blueprint v0.10.11 生成的最小 Gin + SQLite 工程 已接入并收敛 只作为一次性脚手架输入;演示路由、默认 CORS、.env 自动加载、单例和 fatal 行为均已删除。
后端框架 Gin v1.11.0 MVP 已定 这是 go.mod 明确支持 Go 1.23.0 的最高已核实 Gin 版本。
数据访问 标准库 database/sql MVP 已定 领域层通过仓储接口访问,避免先引入 ORM 和代码生成复杂度。
数据迁移 Goose v3.26.0,使用嵌入式 SQL migration 已验证 v3.26.0 是已核实仍声明 Go 1.23.0 的最高版本;v3.27.x 要求 Go 1.25。
管理 Web Gin + html/template + embed + 少量原生 JS/CSS MVP 已定 不单独引入 SPA 工程,模板和静态资源随服务构建。
ERP 直连适配 Go 标准库 net/http、net/http/cookiejar T-227 已验证 Go 侧固定顺运宝验证码、登录、会话校验、分页、详情批量和最小字段归一化;不需要 Python 服务或共享 API Key。
数据库 SQLite MVP 已定 单服务、单设备验证足够;多实例或并发提升前迁移 PostgreSQL。
图片/截图 后端受控本地文件目录 + golang.org/x/image v0.28.0 已验证 JPEG/PNG/WebP 真解码后白底缩放并编码为 JPEG;数据库只存元数据和随机相对键。
管理鉴权 bcrypt + 固定30天 opaque 服务端会话 Cookie T-204/T-267 已验证 authctl 预置 ADMIN;绝对期限不滚动续期,数据库只存密码 hash 与 session SHA-256,完整 RBAC 为 V2。
App 鉴权 BUYER 密码 + 预授权设备 secret + 30天 opaque token T-204/T-266 已验证 首次原子绑定空闲设备;数据库只存 token SHA-256,不提供自助登记/refresh;禁用或撤销立即生效。
VLM 接入 Android 应用内统一适配器,优先兼容 OpenAI 风格多模态接口 T-207/T-272 已实现,供应商待定 手机直连 provider;后端不代理模型;Key 使用 Keystore 加密存储。规格兜底复用单次结构化客户端,只上传有界节点 JSON 与裁剪截图,并回传非秘密 provenance/计数。
离线执行 服务端运行授权 + Android 加密本地状态 T-207 已实现 默认 30 分钟、5-120 分钟可配;30 秒 best-effort heartbeat,过期持久安全停止且 RUNNING 不自动重分配;结果通过加密 outbox 重放。
通知 MVP 不使用推送 已定 点击“获取任务”调用原子 claim API;V2 再评估厂商推送/WebSocket。
后端测试 标准库 testing + httptest T-206 已验证 当前含子测试 193 次覆盖配置、迁移、图片限制、任务事务、鉴权隔离、设备就绪、原子领取、幂等重放、有限离线租约、取消确认、跨连接与真实 TCP 并发。
Android 测试 Gradle test + kotlinx-coroutines-test 1.7.3 + MockWebServer 4.12.0 + 真实设备 smoke T-206 已验证 184 次测试覆盖 runner、页面分类、VLM schema、人工确认、后台端点/JSON/图片同源契约和离线时钟;PKG110 完成私有 fixture/VLM mock 及后台登录、领取、95 秒断线、恢复、取消真机 smoke。
部署 单机局域网 Go 服务;容器化后置 MVP 已定 Android 测试机必须能通过 HTTPS 或受控测试网络访问。

Roubao 上游版本基线

核实日期:2026-07-25。

项目 已核实值
上游仓库 Turbo1123/roubao
许可证 MIT
默认分支 main
核实时 main commit c8a6d7f03422eb01744b01f3ee77bf7757741f7e
main 应用版本 1.4.2(versionCode 7)
当前采购验证版 1.4.12(versionCode 17)
开发 IDE Android Studio Hedgehog 2023.1.1 或更高
JDK / JVM target 17 / 17
Android SDK compileSdk 34、targetSdk 34、minSdk 26
SDK Build Tools 34.0.0(AGP 8.2 官方兼容基线)
Gradle / AGP 8.2 / 8.2.0
Kotlin 1.9.20
Compose Compose BOM 2023.10.01、Compiler 1.5.5、Material 3
自动化依赖 Shizuku API/Provider 13.1.5
无障碍开发分支 roubao2.0+AccessibilityService,核实时 commit 5b114c0a9476c359b27cfe994743fc7beb0a3554

上述版本已在 2026-07-25 使用 JDK 17.0.13、SDK 34 和 Build Tools 34.0.0 完成 Windows Debug 构建。上游无障碍分支落后于 main 的修复和 1.4.2 能力,因此不整体 切换分支;后续只选择性移植无障碍服务。

上游 Firebase 配置依赖未提交的 google-services.json,且第一层不需要遥测。 接入基线已移除 Google Services、Firebase Analytics/Crashlytics 及云端崩溃上报 设置,保留本地 CrashHandler,从而无需伪造或提交 Firebase 凭证。

关键决策

  • 统一后端同时服务管理 Web 与 Android App;不是两套业务后端。
  • 首版管理页面使用服务端渲染,避免在验证阶段维护独立前端构建链。
  • Go Blueprint 只生成起始目录;正式代码必须删除演示逻辑,并按 04-architecture.md 的领域边界重组。
  • SQLite 只服务单实例验证;出现多服务实例、并发写或正式备份要求时迁移 PostgreSQL。
  • VLM 厂商可替换,领域层只接收结构化请求和结果,不传播供应商 SDK 类型。
  • 需求提取与通用 MobileAgent 分离;只有声明 supportsRequirementExtraction 的 OpenAI 兼容 provider 可以进入 T-103 链路。
  • 规格 VLM 是候选发现的可空 adapter:规则快速路径不调用模型,定位只接受当前快照 的临时 node ID,最终视觉证明与截图 SHA-256 绑定;订单 dry-run 不复用该能力。
  • 拼多多自动化是独立工作流模块,不能耦合后端数据库实现或管理页面。

骨架选择记录

  • 来源:Melkeydev/go-blueprint
  • 固定版本:v0.10.11(MIT)
  • 生成目标:Gin + SQLite
  • 不启用:React、HTMX、WebSocket、Redis、Docker 等高级特性

计划生成命令:

go install github.com/melkeydev/go-blueprint@v0.10.11
go-blueprint create --name backend-api --framework gin --driver sqlite --git skip

Go Blueprint v0.10.11 当前生成的是 Go 1.25.0 + Gin 1.12.0,不能直接作为本项目 的 go.mod。2026-07-25 已在仓库外临时目录核实生成树,并把正式 go.mod 固定为:

go 1.23.0
github.com/gin-gonic/gin v1.11.0
github.com/mattn/go-sqlite3 v1.14.48
github.com/pressly/goose/v3 v3.26.0

Gin v1.12.0 的 go.mod 要求 Go 1.25.0,因此本项目禁止升级到 Gin 1.12.x,除非先 单独批准升级 Go 工具链。正式接入还必须修正:

  • 健康检查不得调用 log.Fatal 终止进程。
  • 删除包级数据库单例和包加载阶段读取环境变量的写法。
  • 关闭不需要的默认 CORS,不提交生成的 .env。
  • 正确关闭数据库和 HTTP Server,注入 config/repository 以便测试。
  • mattn/go-sqlite3 需要 CGO 和 GCC;构建环境必须显式验证。

不选择 go-admin-team/go-admin:Vue、多租户、Casbin RBAC、代码生成和定时任务 超出 MVP。不选择 evrone/go-clean-template:当前模板以 Fiber、PostgreSQL、 RabbitMQ、NATS 和 gRPC 为主,不符合最小 Gin + SQLite 边界。

计划目录

android-buyer/      # 已接入的 Roubao Kotlin Android App
backend-api/
  cmd/api/                         # API 进程装配、信号和优雅关闭
  cmd/migrate/                     # 显式 migration up/down/status
  internal/config/                 # 环境变量和安全默认
  internal/platform/database/      # SQLite 打开、pragma 和生命周期
  internal/platform/migration/     # Goose provider 封装
  internal/platform/shunyunbao/    # ERP 会话、协议、直连查询与 allowlist
  internal/transport/httpapi/      # Gin 路由、健康检查和 HTTP Server
  migrations/                      # 嵌入式 Goose SQL migration
  var/                             # 本地运行数据,必须忽略
docs/

T-203 已建立 domain/usecase/repository/sqlite 和 transport/webui,handler 不直接 执行 SQL,Web 与 JSON API 复用同一 usecase。 T-205 已在该分层上增加独立 LifecycleService 与 SQLite immediate transaction, 固定 client-generated claim token、设备 readiness、CLAIMED/运行租约、execution、 安全取消和 task-scoped 参考图授权;当前 90 秒运行租约将在 T-206 扩展为默认 30 分钟有限离线授权,Android HTTP TaskSource 同时接入。

构建与运行命令

用途 命令 当前状态
Android 标准验证 .\init.ps1 已验证
Android 构建 android-buyer\gradlew.bat assembleDebug --no-daemon 已验证
Android 测试任务 android-buyer\gradlew.bat test --no-daemon 已验证;当前全工程 166 次测试通过
Android 安装/启动 $env:RUN_START_COMMAND="1"; .\init.ps1 已在 Android 16 真机验证
后端依赖 $env:GOTOOLCHAIN="local"; go mod download(在 backend-api/) 已验证
后端测试 $env:GOTOOLCHAIN="local"; go test ./...; go test -race ./...; go vet ./... 已验证;192 个测试,全包 race 通过
后端构建 go build -o bin/cmroubao-api.exe ./cmd/api 与 ./cmd/migrate 已验证
后端启动 go run ./cmd/api 已完成本机 HTTP smoke
数据迁移 go run ./cmd/migrate up 已完成 status/up/up/down/up smoke

gradlew installDebug 在当前 Android 16 设备上由旧版 AGP/ddmlib 返回 -99, 但 SDK Platform Tools 37.0.0 的 adb install -r -t 成功。标准脚本因此使用 SDK 内新版 ADB 安装,避免 PATH 中旧版 ADB 1.0.32。

依赖纪律

  • 接入 Roubao 后优先使用其已有 HTTP、序列化、依赖注入和 UI 方案。
  • 扩大 Shizuku 使用范围,或新增 OCR、浏览器自动化和第二套网络库前必须证明已有 能力不足。
  • 后端新增库要说明用途;验证版不引入 ORM、消息队列、Redis、微服务或 SPA 框架。
  • Go 依赖必须固定到 go.mod/go.sum;构建和 CI 不使用未固定的 @latest。
  • go.mod 必须声明 go 1.23.0;验证使用 GOTOOLCHAIN=local go test ./... 或 PowerShell 等价环境变量,确保依赖没有暗中要求更高 Go 版本。
  • handler 不直接写 SQL,repository 不依赖 Gin,domain/usecase 不导入具体数据库驱动。
  • 密钥和设备令牌通过环境变量或本地忽略配置注入,不进入 Git。
  • Go internal/platform/shunyunbao 固定同一套脱敏协议契约,并在 API 进程内装配受锁 会话与 FreightSource;会话只在进程内,不引入 Redis。
  • ERP 账号、密码、Cookie、JWT 和验证码只通过后端环境变量或受控人工输入流转;不得进入 SQLite、浏览器、VLM、fixture 或普通日志。Go 适配器不得记录完整响应或 PII。