-- schema/public.sql
-- Sequences
CREATE SEQUENCE public.users_id_seq;
-- Tables
CREATE TABLE public.users (
id INTEGER NOT NULL DEFAULT nextval('public.users_id_seq'::regclass),
username TEXT NOT NULL,
email TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
status TEXT NOT NULL DEFAULT 'active',
CONSTRAINT users_pkey PRIMARY KEY (id),
CONSTRAINT users_username_key UNIQUE (username),
CONSTRAINT users_email_key UNIQUE (email),
CONSTRAINT check_email_format CHECK (email ~* '^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$'),
CONSTRAINT check_status_values CHECK (status IN ('active', 'inactive', 'suspended'))
);
ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id;
CREATE TABLE public.user_profiles (
user_id INTEGER NOT NULL,
bio TEXT,
avatar_url TEXT,
CONSTRAINT user_profiles_pkey PRIMARY KEY (user_id),
CONSTRAINT fk_user_profiles_users FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE
);
-- Indexes
CREATE INDEX idx_users_email ON public.users(email);
CREATE INDEX idx_users_created_at ON public.users(created_at);
CREATE INDEX idx_users_status ON public.users(status) WHERE status != 'inactive';
-- Views
CREATE VIEW public.active_users AS
SELECT id, username, email, created_at
FROM public.users
WHERE status = 'active';
-- Functions
CREATE FUNCTION public.get_user_count()
RETURNS INTEGER
LANGUAGE sql
AS $$
SELECT COUNT(*) FROM public.users;
$$;