first commit
This commit is contained in:
150
database/init.sql
Normal file
150
database/init.sql
Normal file
@@ -0,0 +1,150 @@
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
CREATE TABLE users (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name text NOT NULL,
|
||||
email text NOT NULL UNIQUE,
|
||||
password_hash text NOT NULL,
|
||||
avatar_file text,
|
||||
created_at timestamptz NOT NULL DEFAULT NOW(),
|
||||
updated_at timestamptz NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE sessions (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
token_hash text NOT NULL UNIQUE,
|
||||
expires_at timestamptz NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX sessions_user_id_idx ON sessions(user_id);
|
||||
CREATE INDEX sessions_expires_at_idx ON sessions(expires_at);
|
||||
|
||||
CREATE TABLE subscriptions (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
amount double precision NOT NULL,
|
||||
billing_cycle text NOT NULL,
|
||||
activation_date text NOT NULL,
|
||||
first_payment_date text NOT NULL,
|
||||
end_date text,
|
||||
occurrence_count integer CHECK (occurrence_count > 0),
|
||||
custom_interval_value integer CHECK (custom_interval_value > 0),
|
||||
custom_interval_unit text CHECK (
|
||||
custom_interval_unit IN ('days', 'weeks', 'months', 'years')
|
||||
),
|
||||
subscription_status text NOT NULL,
|
||||
created_at text NOT NULL,
|
||||
updated_at text NOT NULL,
|
||||
CONSTRAINT subscriptions_amount_positive CHECK (amount > 0),
|
||||
CONSTRAINT subscriptions_billing_cycle_valid CHECK (
|
||||
billing_cycle IN ('weekly', 'monthly', 'yearly', 'custom')
|
||||
),
|
||||
CONSTRAINT subscriptions_status_valid CHECK (
|
||||
subscription_status IN ('active', 'suspended', 'terminated')
|
||||
),
|
||||
CONSTRAINT subscriptions_dates_valid CHECK (
|
||||
activation_date <= first_payment_date
|
||||
AND (end_date IS NULL OR end_date >= first_payment_date)
|
||||
)
|
||||
);
|
||||
CREATE INDEX subscriptions_user_id_idx ON subscriptions(user_id);
|
||||
CREATE INDEX subscriptions_first_payment_date_idx ON subscriptions(first_payment_date);
|
||||
|
||||
CREATE TABLE subscription_payments (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
subscription_id uuid NOT NULL REFERENCES subscriptions(id) ON DELETE CASCADE,
|
||||
renewal_date text NOT NULL,
|
||||
status text NOT NULL,
|
||||
payment_date text,
|
||||
linked_payment_id uuid,
|
||||
created_at text NOT NULL,
|
||||
updated_at text NOT NULL,
|
||||
UNIQUE (subscription_id, renewal_date, user_id)
|
||||
);
|
||||
CREATE INDEX subscription_payments_user_id_idx ON subscription_payments(user_id);
|
||||
|
||||
CREATE TABLE bills (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
amount double precision NOT NULL,
|
||||
due_date text NOT NULL,
|
||||
status text NOT NULL,
|
||||
payment_date text,
|
||||
linked_payment_id uuid,
|
||||
created_at text NOT NULL,
|
||||
updated_at text NOT NULL
|
||||
);
|
||||
CREATE INDEX bills_user_id_idx ON bills(user_id);
|
||||
CREATE INDEX bills_due_date_idx ON bills(due_date);
|
||||
|
||||
CREATE TABLE one_time_payments (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
amount double precision NOT NULL,
|
||||
date text NOT NULL,
|
||||
linked_payment_id uuid,
|
||||
created_at text NOT NULL,
|
||||
updated_at text NOT NULL
|
||||
);
|
||||
CREATE INDEX one_time_payments_user_id_idx ON one_time_payments(user_id);
|
||||
|
||||
CREATE TABLE payments_ledger (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
amount double precision NOT NULL,
|
||||
date text NOT NULL,
|
||||
source_type text NOT NULL,
|
||||
source_id uuid NOT NULL,
|
||||
created_at text NOT NULL,
|
||||
updated_at text NOT NULL,
|
||||
UNIQUE (source_type, source_id, user_id)
|
||||
);
|
||||
CREATE INDEX payments_ledger_user_id_idx ON payments_ledger(user_id);
|
||||
CREATE INDEX payments_ledger_date_idx ON payments_ledger(date);
|
||||
|
||||
CREATE TABLE payment_titles (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
normalized_name text NOT NULL,
|
||||
payment_type text NOT NULL,
|
||||
created_at text NOT NULL,
|
||||
updated_at text NOT NULL,
|
||||
CONSTRAINT payment_titles_type_valid CHECK (
|
||||
payment_type IN ('subscription', 'bill', 'one_time', 'income', 'any')
|
||||
),
|
||||
UNIQUE (user_id, normalized_name, payment_type)
|
||||
);
|
||||
CREATE INDEX payment_titles_user_id_idx ON payment_titles(user_id);
|
||||
|
||||
CREATE TABLE income (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
amount double precision NOT NULL,
|
||||
type text NOT NULL,
|
||||
date text NOT NULL,
|
||||
created_at text NOT NULL,
|
||||
updated_at text NOT NULL
|
||||
);
|
||||
CREATE INDEX income_user_id_idx ON income(user_id);
|
||||
|
||||
CREATE TABLE user_settings (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL UNIQUE REFERENCES users(id) ON DELETE CASCADE,
|
||||
full_name text,
|
||||
monthly_income_goal double precision,
|
||||
monthly_savings_goal double precision,
|
||||
currency text NOT NULL,
|
||||
locale text NOT NULL,
|
||||
first_day_of_week text NOT NULL,
|
||||
default_dashboard_view text NOT NULL,
|
||||
created_at text NOT NULL,
|
||||
updated_at text NOT NULL
|
||||
);
|
||||
Reference in New Issue
Block a user