69 lines
2.4 KiB
SQL
69 lines
2.4 KiB
SQL
-- CryptoWallet API — DB schema (idempotent, custodial v3.0)
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id VARCHAR(26) PRIMARY KEY,
|
|
email VARCHAR(255) NOT NULL UNIQUE,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
last_name VARCHAR(255),
|
|
first_name VARCHAR(255),
|
|
middle_name VARCHAR(255),
|
|
birth_date DATE,
|
|
crypto_wallet VARCHAR(255),
|
|
phone VARCHAR(64),
|
|
bik VARCHAR(64),
|
|
account_number VARCHAR(64),
|
|
card_number VARCHAR(64),
|
|
inn VARCHAR(64),
|
|
kyc_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
|
kyc_verified_at TIMESTAMPTZ,
|
|
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
|
encrypted_vault TEXT,
|
|
vault_salt VARCHAR(128),
|
|
encrypted_mnemonic TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_name = 'users' AND column_name = 'encrypted_mnemonic'
|
|
) THEN
|
|
ALTER TABLE users ADD COLUMN encrypted_mnemonic TEXT;
|
|
END IF;
|
|
END $$;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_constraint WHERE conname = 'users_encrypted_mnemonic_size'
|
|
) THEN
|
|
ALTER TABLE users
|
|
ADD CONSTRAINT users_encrypted_mnemonic_size
|
|
CHECK (encrypted_mnemonic IS NULL OR (char_length(encrypted_mnemonic) BETWEEN 140 AND 512));
|
|
END IF;
|
|
END $$;
|
|
|
|
CREATE TABLE IF NOT EXISTS wallets (
|
|
id VARCHAR(26) PRIMARY KEY,
|
|
user_id VARCHAR(26) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
chain VARCHAR(16) NOT NULL,
|
|
address VARCHAR(256) NOT NULL,
|
|
derivation_path VARCHAR(64) NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (user_id, chain)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_wallets_user_id ON wallets(user_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
id VARCHAR(26) PRIMARY KEY,
|
|
user_id VARCHAR(26) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON sessions(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON sessions(expires_at);
|