Files
web-hosts/domains/coppertone.tech/backend/migrations/001_create_users_and_identities.up.sql
2025-12-26 13:38:04 +01:00

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();