65 lines
2.4 KiB
PL/PgSQL
65 lines
2.4 KiB
PL/PgSQL
-- Create users table
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
email VARCHAR(255) UNIQUE, -- Nullable for blockchain-only users
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Create index on email for faster lookups
|
|
CREATE INDEX idx_users_email ON users(email) WHERE email IS NOT NULL;
|
|
|
|
-- Create enum for identity types
|
|
CREATE TYPE identity_type AS ENUM ('email_password', 'blockchain_address', 'did');
|
|
|
|
-- Create identities table for multi-factor authentication
|
|
CREATE TABLE IF NOT EXISTS identities (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
type identity_type NOT NULL,
|
|
identifier VARCHAR(500) NOT NULL, -- Email, blockchain address, or DID
|
|
credential TEXT, -- Password hash, public key, or other credential data
|
|
is_primary_login BOOLEAN DEFAULT false,
|
|
metadata JSONB, -- Store additional identity-specific data
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(type, identifier)
|
|
);
|
|
|
|
-- Create indexes for identities
|
|
CREATE INDEX idx_identities_user_id ON identities(user_id);
|
|
CREATE INDEX idx_identities_type_identifier ON identities(type, identifier);
|
|
CREATE INDEX idx_identities_primary_login ON identities(user_id, is_primary_login) WHERE is_primary_login = true;
|
|
|
|
-- Create enum for user roles
|
|
CREATE TYPE user_role AS ENUM ('ADMIN', 'STAFF', 'CLIENT');
|
|
|
|
-- Create user_roles table for role-based access control
|
|
CREATE TABLE IF NOT EXISTS user_roles (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
role user_role NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(user_id, role)
|
|
);
|
|
|
|
-- Create index on user_roles
|
|
CREATE INDEX idx_user_roles_user_id ON user_roles(user_id);
|
|
|
|
-- Create function to update updated_at timestamp
|
|
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = CURRENT_TIMESTAMP;
|
|
RETURN NEW;
|
|
END;
|
|
$$ language 'plpgsql';
|
|
|
|
-- Create triggers for updated_at
|
|
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_identities_updated_at BEFORE UPDATE ON identities
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|