CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE TYPE category_type AS ENUM ( 'bill', 'variable_expense', 'debt', 'saving', 'investment', 'income' ); CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), email TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL DEFAULT '', oidc_subject TEXT, display_name TEXT NOT NULL DEFAULT '', preferred_locale TEXT NOT NULL DEFAULT 'en', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_users_email ON users (email); CREATE UNIQUE INDEX idx_users_oidc_subject ON users (oidc_subject) WHERE oidc_subject IS NOT NULL; CREATE TABLE IF NOT EXISTS categories ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, name TEXT NOT NULL, type category_type NOT NULL, icon TEXT NOT NULL DEFAULT '', sort_order INT NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_categories_user_id ON categories (user_id); CREATE TABLE IF NOT EXISTS budgets ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, name TEXT NOT NULL, start_date DATE NOT NULL, end_date DATE NOT NULL, currency TEXT NOT NULL DEFAULT 'EUR', carryover_amount NUMERIC(12, 2) NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_budgets_user_id ON budgets (user_id); CREATE TABLE IF NOT EXISTS budget_items ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), budget_id UUID NOT NULL REFERENCES budgets(id) ON DELETE CASCADE, category_id UUID NOT NULL REFERENCES categories(id) ON DELETE RESTRICT, budgeted_amount NUMERIC(12, 2) NOT NULL DEFAULT 0, actual_amount NUMERIC(12, 2) NOT NULL DEFAULT 0, notes TEXT NOT NULL DEFAULT '', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_budget_items_budget_id ON budget_items (budget_id); CREATE INDEX idx_budget_items_category_id ON budget_items (category_id); CREATE TABLE IF NOT EXISTS schema_migrations ( version INT PRIMARY KEY, applied_at TIMESTAMPTZ NOT NULL DEFAULT now() );