-- 设备唯一键 UNIQUE(uuid) → UNIQUE(user_id, uuid)（F3:同机换账号 403 死结）
--
-- device_id 是客户端按「安装」生成并持久的,跨账号复用;全局 UNIQUE(uuid) 使同一台
-- 机器登第二个账号时 RegisterIfAbsent 永远 403 → ConnectNode 判 DEVICE_NOT_REGISTERED,
-- 且提示的「重新登录」无法自救。改为按用户隔离:同一物理设备在每个账号下各有一行。
-- 顺手落地 migration 16 头注释里推迟的两件事:本唯一键改造 + platform CHECK 加 linux
-- (normalizePlatform 已接受 linux,但旧 CHECK 会拒 INSERT)。
--
-- SQLite 无法删除列级 UNIQUE,须重建表。sessions 对 devices 有 ON DELETE CASCADE 外键
-- 且连接开启 foreign_keys=ON:直接 DROP devices 会级联清空全部会话(=全员被登出)。
-- 安全次序(单事务内成立,不依赖 PRAGMA foreign_keys=OFF):
--   ① RENAME devices → devices_old(sessions 的 FK 定义随 rename 跟走到 devices_old);
--   ② 建新 devices(复合唯一键),按原 id 复制数据;
--   ③ RENAME sessions → sessions_old,建新 sessions(FK 指向新 devices),复制数据;
--   ④ 先 DROP 子表 sessions_old,再 DROP 已无引用的 devices_old;重建全部索引。

ALTER TABLE devices RENAME TO devices_old;

CREATE TABLE devices (
  id                 INTEGER PRIMARY KEY AUTOINCREMENT,
  uuid               TEXT NOT NULL,
  user_id            INTEGER NOT NULL,
  name               TEXT NOT NULL,
  platform           TEXT NOT NULL CHECK (platform IN ('ios','android','windows','macos','linux')),
  last_seen          DATETIME NULL,
  created_at         DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  client_version     TEXT NULL,
  totp_trusted_until DATETIME NULL,
  dp_uuid            TEXT NULL,
  UNIQUE (user_id, uuid),
  FOREIGN KEY (user_id) REFERENCES users(id)
);

INSERT INTO devices (id, uuid, user_id, name, platform, last_seen, created_at,
                     client_version, totp_trusted_until, dp_uuid)
SELECT id, uuid, user_id, name, platform, last_seen, created_at,
       client_version, totp_trusted_until, dp_uuid
FROM devices_old;

ALTER TABLE sessions RENAME TO sessions_old;

CREATE TABLE sessions (
  id             INTEGER PRIMARY KEY AUTOINCREMENT,
  user_id        INTEGER NOT NULL,
  device_id      INTEGER NOT NULL,
  refresh_jti    TEXT NOT NULL UNIQUE,
  client_ip      TEXT NULL,
  client_version TEXT NULL,
  created_at     DATETIME NOT NULL,
  last_active    DATETIME NULL,
  revoked_at     DATETIME NULL,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (device_id) REFERENCES devices(id) ON DELETE CASCADE
);

INSERT INTO sessions (id, user_id, device_id, refresh_jti, client_ip, client_version,
                      created_at, last_active, revoked_at)
SELECT id, user_id, device_id, refresh_jti, client_ip, client_version,
       created_at, last_active, revoked_at
FROM sessions_old;

DROP TABLE sessions_old;
DROP TABLE devices_old;

CREATE INDEX idx_devices_user ON devices (user_id);
CREATE UNIQUE INDEX idx_devices_dp_uuid ON devices (dp_uuid);
CREATE INDEX idx_sessions_user ON sessions (user_id);
CREATE INDEX idx_sessions_device ON sessions (device_id);
