CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, password VARCHAR(255), enabled BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS merchants ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), name VARCHAR(255) NOT NULL, icon_name VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS categories ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), name VARCHAR(255) NOT NULL, icon_name VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS transactions ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), category_id INTEGER REFERENCES categories(id), type VARCHAR(50) NOT NULL, -- 'INCOME' or 'EXPENSE' or 'INVESTMENT' amount DECIMAL(10, 2) NOT NULL, date DATE NOT NULL, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS budgets ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), category_id INTEGER REFERENCES categories(id), monthly_limit DECIMAL(10, 2) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(user_id, category_id) ); CREATE TABLE IF NOT EXISTS recurring_transactions ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), category_id INTEGER REFERENCES categories(id), type VARCHAR(50) NOT NULL, amount DECIMAL(10, 2) NOT NULL, frequency VARCHAR(50) NOT NULL, next_execution_date DATE NOT NULL, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS wallets ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, owner_id INTEGER REFERENCES users(id), nature VARCHAR(50) DEFAULT 'CASH', -- 'CASH', 'DEPOSIT', 'EXPENSE', 'INCOME', 'SAVINGS', 'LOAN', etc. balance DECIMAL(15, 2) DEFAULT 0.00, currency VARCHAR(10) DEFAULT 'INR', icon VARCHAR(255), color VARCHAR(50), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS user_wallets ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), wallet_id INTEGER REFERENCES wallets(id), role VARCHAR(50) DEFAULT 'MEMBER', joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE (user_id, wallet_id) ); ALTER TABLE wallets ADD COLUMN IF NOT EXISTS nature VARCHAR(50) DEFAULT 'CASH'; ALTER TABLE wallets ADD COLUMN IF NOT EXISTS balance DECIMAL(15, 2) DEFAULT 0.00; ALTER TABLE wallets ADD COLUMN IF NOT EXISTS currency VARCHAR(10) DEFAULT 'INR'; ALTER TABLE wallets ADD COLUMN IF NOT EXISTS icon VARCHAR(255); ALTER TABLE wallets ADD COLUMN IF NOT EXISTS color VARCHAR(50); ALTER TABLE transactions ADD COLUMN IF NOT EXISTS wallet_id INTEGER REFERENCES wallets(id); ALTER TABLE transactions ADD COLUMN IF NOT EXISTS from_wallet_id INTEGER REFERENCES wallets(id); ALTER TABLE transactions ADD COLUMN IF NOT EXISTS to_wallet_id INTEGER REFERENCES wallets(id); ALTER TABLE transactions ADD COLUMN IF NOT EXISTS notes TEXT; ALTER TABLE transactions ADD COLUMN IF NOT EXISTS due_date DATE; ALTER TABLE transactions ADD COLUMN IF NOT EXISTS alert_schedule VARCHAR(50); ALTER TABLE transactions ADD COLUMN IF NOT EXISTS alert_time TIME; ALTER TABLE transactions ADD COLUMN IF NOT EXISTS investment_status VARCHAR(20) DEFAULT 'OPEN'; ALTER TABLE transactions ADD COLUMN IF NOT EXISTS maturity_amount DECIMAL(10, 2); ALTER TABLE transactions ADD COLUMN IF NOT EXISTS profit_loss DECIMAL(10, 2); ALTER TABLE transactions ADD COLUMN IF NOT EXISTS closing_date DATE; CREATE TABLE IF NOT EXISTS transaction_items ( id SERIAL PRIMARY KEY, transaction_id INTEGER REFERENCES transactions(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, amount DECIMAL(10, 2) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS transaction_attachments ( id SERIAL PRIMARY KEY, transaction_id INTEGER REFERENCES transactions(id) ON DELETE CASCADE, file_name VARCHAR(255) NOT NULL, file_path VARCHAR(1024) NOT NULL, content_type VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ALTER TABLE budgets ADD COLUMN IF NOT EXISTS wallet_id INTEGER REFERENCES wallets(id); ALTER TABLE budgets ADD COLUMN IF NOT EXISTS is_shared BOOLEAN DEFAULT FALSE; -- Ensure budget can be either category-specific or wallet-specific ALTER TABLE budgets ALTER COLUMN category_id DROP NOT NULL; ALTER TABLE recurring_transactions ADD COLUMN IF NOT EXISTS from_wallet_id INTEGER REFERENCES wallets(id); ALTER TABLE recurring_transactions ADD COLUMN IF NOT EXISTS to_wallet_id INTEGER REFERENCES wallets(id); ALTER TABLE recurring_transactions ADD COLUMN IF NOT EXISTS status VARCHAR(20) DEFAULT 'ACTIVE'; ALTER TABLE recurring_transactions ADD COLUMN IF NOT EXISTS end_date DATE; ALTER TABLE recurring_transactions ALTER COLUMN category_id DROP NOT NULL; CREATE TABLE IF NOT EXISTS wallet_invitations ( id SERIAL PRIMARY KEY, wallet_id INTEGER REFERENCES wallets(id), inviter_id INTEGER REFERENCES users(id), invitee_email VARCHAR(255) NOT NULL, status VARCHAR(20) DEFAULT 'PENDING', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );