137 lines
4.1 KiB
SQL
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;
|