-- 回退:UNIQUE(user_id,uuid) → 全局 UNIQUE(uuid),platform CHECK 去掉 linux。 -- 有损:同一 uuid 跨用户的重复行只保留最早一行(id 最小),linux 平台行删除 -- (旧 CHECK 不接受)。次序与 up 相同(rename → 重建 → 复制 → drop)。 ALTER TABLE devices RENAME TO devices_old; CREATE TABLE devices ( id INTEGER PRIMARY KEY AUTOINCREMENT, uuid TEXT NOT NULL UNIQUE, user_id INTEGER NOT NULL, name TEXT NOT NULL, platform TEXT NOT NULL CHECK (platform IN ('ios','android','windows','macos')), 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, 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 o WHERE o.platform IN ('ios','android','windows','macos') AND o.id = (SELECT MIN(i.id) FROM devices_old i WHERE i.uuid = o.uuid); 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 s.id, s.user_id, s.device_id, s.refresh_jti, s.client_ip, s.client_version, s.created_at, s.last_active, s.revoked_at FROM sessions_old s WHERE EXISTS (SELECT 1 FROM devices d WHERE d.id = s.device_id); 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);