-- +goose Up -- +goose StatementBegin CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255), password_hash VARCHAR(255), email_verified BOOLEAN DEFAULT FALSE, provider VARCHAR(50) NOT NULL DEFAULT 'email', provider_id VARCHAR(255), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), last_login_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); CREATE INDEX IF NOT EXISTS idx_users_provider ON users(provider, provider_id); CREATE TABLE IF NOT EXISTS magic_links ( token VARCHAR(255) PRIMARY KEY, user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, email VARCHAR(255) NOT NULL, used BOOLEAN DEFAULT FALSE, expires_at TIMESTAMP WITH TIME ZONE NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_magic_links_user_id ON magic_links(user_id); CREATE INDEX IF NOT EXISTS idx_magic_links_expires ON magic_links(expires_at) WHERE used = FALSE; -- +goose StatementEnd -- +goose Down -- +goose StatementBegin DROP TABLE IF EXISTS magic_links; DROP TABLE IF EXISTS users; -- +goose StatementEnd