Files
inkwatch/deploy/migrate.sql
T
PMon Dev f632672a82 feat: PMon V4.0 功能开发收口(1.0.9)—— 主干
把 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 承载,主干不受其影响。
2026-09-16 01:06:24 +08:00

45 lines
3.1 KiB
SQL
Raw Blame History

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.
-- ==================== 幂等增量迁移(**每次启动都跑**)====================
--
-- ⚠️ 为什么要单独一个文件(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);