Files
cmroubao/backend-api/migrations/00003_auth.sql
T

137 lines
4.1 KiB
SQL

-- +goose Up
CREATE TABLE users (
id TEXT PRIMARY KEY NOT NULL
CHECK (length(id) = 36),
username TEXT NOT NULL UNIQUE
CHECK (
length(trim(username)) > 0
AND username = lower(trim(username))
AND length(CAST(username AS BLOB)) <= 128
),
password_hash TEXT NOT NULL
CHECK (
length(password_hash) > 0
AND length(CAST(password_hash AS BLOB)) <= 255
),
role TEXT NOT NULL
CHECK (role IN ('ADMIN', 'BUYER')),
is_active INTEGER NOT NULL
CHECK (is_active IN (0, 1)),
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE devices (
id TEXT PRIMARY KEY NOT NULL
CHECK (length(id) = 36),
name TEXT NOT NULL
CHECK (
length(trim(name)) > 0
AND length(CAST(name AS BLOB)) <= 128
),
token_hash TEXT NOT NULL UNIQUE
CHECK (
length(token_hash) = 64
AND token_hash NOT GLOB '*[^0-9a-f]*'
),
bound_user_id TEXT
REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
app_version TEXT
CHECK (
app_version IS NULL
OR (
length(trim(app_version)) > 0
AND length(CAST(app_version AS BLOB)) <= 128
)
),
android_version TEXT
CHECK (
android_version IS NULL
OR (
length(trim(android_version)) > 0
AND length(CAST(android_version AS BLOB)) <= 128
)
),
pdd_version TEXT
CHECK (
pdd_version IS NULL
OR (
length(trim(pdd_version)) > 0
AND length(CAST(pdd_version AS BLOB)) <= 128
)
),
last_seen_at TEXT,
is_enabled INTEGER NOT NULL
CHECK (is_enabled IN (0, 1)),
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX devices_bound_user_idx
ON devices (bound_user_id);
CREATE TABLE admin_sessions (
id TEXT PRIMARY KEY NOT NULL
CHECK (length(id) = 36),
token_hash TEXT NOT NULL UNIQUE
CHECK (
length(token_hash) = 64
AND token_hash NOT GLOB '*[^0-9a-f]*'
),
user_id TEXT NOT NULL
REFERENCES users(id) ON UPDATE RESTRICT ON DELETE CASCADE,
expires_at TEXT NOT NULL,
revoked_at TEXT,
created_at TEXT NOT NULL
);
CREATE INDEX admin_sessions_user_expires_idx
ON admin_sessions (user_id, expires_at);
CREATE TABLE access_tokens (
id TEXT PRIMARY KEY NOT NULL
CHECK (length(id) = 36),
token_hash TEXT NOT NULL UNIQUE
CHECK (
length(token_hash) = 64
AND token_hash NOT GLOB '*[^0-9a-f]*'
),
user_id TEXT NOT NULL
REFERENCES users(id) ON UPDATE RESTRICT ON DELETE CASCADE,
device_id TEXT NOT NULL
REFERENCES devices(id) ON UPDATE RESTRICT ON DELETE CASCADE,
expires_at TEXT NOT NULL,
revoked_at TEXT,
created_at TEXT NOT NULL
);
CREATE INDEX access_tokens_user_device_expires_idx
ON access_tokens (user_id, device_id, expires_at);
ALTER TABLE purchase_tasks
ADD COLUMN created_by_user_id TEXT
REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT;
ALTER TABLE task_events
ADD COLUMN actor_user_id TEXT
REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT;
CREATE INDEX purchase_tasks_created_by_user_idx
ON purchase_tasks (created_by_user_id, created_at DESC, id DESC);
CREATE INDEX task_events_actor_user_idx
ON task_events (actor_user_id, occurred_at DESC, id DESC);
-- +goose Down
DROP INDEX IF EXISTS task_events_actor_user_idx;
DROP INDEX IF EXISTS purchase_tasks_created_by_user_idx;
ALTER TABLE task_events DROP COLUMN actor_user_id;
ALTER TABLE purchase_tasks DROP COLUMN created_by_user_id;
DROP INDEX IF EXISTS access_tokens_user_device_expires_idx;
DROP TABLE IF EXISTS access_tokens;
DROP INDEX IF EXISTS admin_sessions_user_expires_idx;
DROP TABLE IF EXISTS admin_sessions;
DROP INDEX IF EXISTS devices_bound_user_idx;
DROP TABLE IF EXISTS devices;
DROP TABLE IF EXISTS users;