-- +goose Up CREATE TABLE device_credentials ( device_id TEXT PRIMARY KEY CHECK ( length(device_id) = 36 AND substr(device_id, 9, 1) = '-' AND substr(device_id, 14, 1) = '-' AND substr(device_id, 19, 1) = '-' AND substr(device_id, 24, 1) = '-' AND length(replace(device_id, '-', '')) = 32 AND replace(device_id, '-', '') NOT GLOB '*[^0-9a-f]*' AND substr(device_id, 15, 1) = '4' AND substr(device_id, 20, 1) IN ('8', '9', 'a', 'b') ), display_name TEXT NOT NULL CHECK ( display_name = trim(display_name) AND length(display_name) BETWEEN 1 AND 128 ), token_sha256 BLOB NOT NULL UNIQUE CHECK ( typeof(token_sha256) = 'blob' AND length(token_sha256) = 32 ), status TEXT NOT NULL CHECK (status IN ('ACTIVE', 'REVOKED')), created_at TEXT NOT NULL CHECK ( created_at = trim(created_at) AND length(created_at) >= 20 AND substr(created_at, 11, 1) = 'T' AND substr(created_at, -1, 1) = 'Z' AND julianday(created_at) IS NOT NULL ), revoked_at TEXT CHECK ( revoked_at IS NULL OR ( revoked_at = trim(revoked_at) AND length(revoked_at) >= 20 AND substr(revoked_at, 11, 1) = 'T' AND substr(revoked_at, -1, 1) = 'Z' AND julianday(revoked_at) IS NOT NULL ) ), CHECK ( (status = 'ACTIVE' AND revoked_at IS NULL) OR ( status = 'REVOKED' AND revoked_at IS NOT NULL AND julianday(revoked_at) >= julianday(created_at) ) ) ); CREATE INDEX device_credentials_status_created_idx ON device_credentials (status, created_at, device_id); -- +goose Down -- 已签发凭据是安全配置;回滚不得静默删除并让设备身份审计链消失。 CREATE TABLE device_credentials_downgrade_guard ( valid INTEGER NOT NULL CHECK (valid = 1) ); INSERT INTO device_credentials_downgrade_guard (valid) SELECT CASE WHEN (SELECT COUNT(*) FROM device_credentials) = 0 THEN 1 ELSE 0 END; DROP TABLE device_credentials_downgrade_guard; DROP TABLE device_credentials;