init
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
-- Phase 1: auth foundation
|
||||
-- Requires Postgres. citext for case-insensitive email; pgcrypto for gen_random_uuid.
|
||||
CREATE EXTENSION IF NOT EXISTS citext;
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email CITEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
display_name TEXT,
|
||||
email_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- One row per user; created on registration.
|
||||
CREATE TABLE user_settings (
|
||||
user_id UUID PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
||||
locale TEXT NOT NULL DEFAULT 'de', -- 'de' | 'en'
|
||||
currency TEXT NOT NULL DEFAULT 'EUR',
|
||||
theme TEXT NOT NULL DEFAULT 'breakcore',
|
||||
notify_email BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- Email verification + password reset tokens.
|
||||
-- Only the SHA-256 hash of the token is stored; raw token lives in the emailed link.
|
||||
CREATE TYPE token_purpose AS ENUM ('verify_email', 'password_reset');
|
||||
|
||||
CREATE TABLE auth_tokens (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
token_hash BYTEA NOT NULL UNIQUE,
|
||||
purpose token_purpose NOT NULL,
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
consumed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_auth_tokens_user ON auth_tokens(user_id);
|
||||
CREATE INDEX idx_auth_tokens_expires ON auth_tokens(expires_at);
|
||||
|
||||
-- Touch updated_at on row changes.
|
||||
CREATE OR REPLACE FUNCTION set_updated_at() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER trg_users_updated
|
||||
BEFORE UPDATE ON users
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
CREATE TRIGGER trg_user_settings_updated
|
||||
BEFORE UPDATE ON user_settings
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
Reference in New Issue
Block a user