把 V4.0 骨架以来的全部功能开发固化为主干基线,内容包括:
· client/ 全量 Android/macOS 客户端(Flutter + Rust 核心)
· server/ 网关、业务服务、仓储层
· deploy/ compose、Dockerfile、init.sql + migrate.sql(幂等迁移)
· shared/ tests/ 协议、编解码、指标清单与全部测试套件
· docs/ README 架构方案与运维手册
本轮之前修复的主要缺陷(详见各文件注释与 client/README.md):
· 首次部署路径(init.sql 的 device_tokens 建表顺序)
· 每 20 分钟硬切以外的设备身份漂移与**设备归并**(shared/device-identity.js)
· 配置无版本号、无校验导致的病态残留(host/config_migration.dart)
· 数据库迁移从不执行(deploy/migrate.sql + compose 的 migrate 服务)
验证:客户端 282/282、全量回归 20 套件 0 失败。
⚠️ 水墨屏专属实现(看板、水墨屏令牌、einkMode、常亮)**不在本分支**,
由 feature/eink 承载,主干不受其影响。
45 lines
3.1 KiB
SQL
45 lines
3.1 KiB
SQL
-- ==================== 幂等增量迁移(**每次启动都跑**)====================
|
||
--
|
||
-- ⚠️ 为什么要单独一个文件(2026-09-15 修的运维坑)────────────────────────
|
||
-- 迁移段原先只写在 `init.sql` 末尾,而 `init.sql` 挂在
|
||
-- `/docker-entrypoint-initdb.d/` —— **那个目录只在数据目录为空时才执行**。
|
||
-- 也就是说:**已有库上,这段代码从来没跑过**,全靠人手敲 SQL。
|
||
--
|
||
-- 后果不是"少个字段",而是**静默的链路中断**:新增 `devices.hardware_id` 后,
|
||
-- `registerDevice` 会写一个不存在的列 → SQL 报错 → 网关侧 catch 掉只记日志
|
||
-- (`[gateway] 设备落库失败`)→ **设备不再落库,而服务健康检查全绿**。
|
||
-- 与 `init.sql` 里那段"首次部署才走、结果云上全废"是同一个病:
|
||
-- 凡是"只在某种时序下执行"的代码,都必须有一个不受时序影响的执行点。
|
||
--
|
||
-- 故:本文件是**所有 schema 变更的唯一落点**,
|
||
-- · 全新库:`init.sql` 末尾 `\i /migrate.sql` 走一遍;
|
||
-- · 已有库:compose 里的 `migrate` 一次性服务在 postgres healthy 后跑一遍。
|
||
-- 两条路径共用同一份定义(单一真相源),且全部语句幂等(可反复执行)。
|
||
--
|
||
-- ⚠️ 纪律:**新增任何列/索引/表,都加到这里**(而不是只改上面的 CREATE TABLE,
|
||
-- 那只对全新库有效)。改完跑 `bash tests/run-all.sh` ——
|
||
-- `schema-consistency-test.js` 会校验建表顺序与清单一致性。
|
||
|
||
-- ---- 指标列(骨架期只有 7 列,权威清单有 17 个字段,缺列的指标只能落在 payload)----
|
||
ALTER TABLE device_metrics ADD COLUMN IF NOT EXISTS mem_used_mb DOUBLE PRECISION;
|
||
ALTER TABLE device_metrics ADD COLUMN IF NOT EXISTS mem_total_mb DOUBLE PRECISION;
|
||
ALTER TABLE device_metrics ADD COLUMN IF NOT EXISTS disk_free_gb DOUBLE PRECISION;
|
||
ALTER TABLE device_metrics ADD COLUMN IF NOT EXISTS disk_total_gb DOUBLE PRECISION;
|
||
ALTER TABLE device_metrics ADD COLUMN IF NOT EXISTS disk_write_mbps DOUBLE PRECISION;
|
||
ALTER TABLE device_metrics ADD COLUMN IF NOT EXISTS battery_temp DOUBLE PRECISION;
|
||
|
||
-- ---- 账号体系的凭据列(新表走 CREATE TABLE IF NOT EXISTS,已存在的库只需补列)----
|
||
ALTER TABLE users ADD COLUMN IF NOT EXISTS secret_hash TEXT;
|
||
ALTER TABLE users ADD COLUMN IF NOT EXISTS secret_salt TEXT;
|
||
ALTER TABLE users ADD COLUMN IF NOT EXISTS secret_updated_at TIMESTAMPTZ;
|
||
ALTER TABLE users ADD COLUMN IF NOT EXISTS disabled_at TIMESTAMPTZ;
|
||
|
||
-- ---- 设备硬件指纹(2026-09-15)----
|
||
-- 用途见 `server/shared/device-identity.js`:让服务端能认出"这还是同一台机",
|
||
-- 从而把同一台设备因 device_id 漂移产生的多条记录归并掉。
|
||
--
|
||
-- ⚠️ 存量行留 NULL,**不要**拿 device_id 回填:device_id 是**派生的、会变的值**,
|
||
-- 拿它当"稳定指纹"等于把 bug 固化进数据。NULL 只是让它走"后缀兜底"判据。
|
||
ALTER TABLE devices ADD COLUMN IF NOT EXISTS hardware_id TEXT;
|
||
CREATE INDEX IF NOT EXISTS idx_devices_hardware ON devices(owner_id, hardware_id);
|