-- Create subscription and billing tables -- Migration: 015_create_subscription_tables.up.sql -- Subscriptions table CREATE TABLE IF NOT EXISTS subscriptions ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, plan VARCHAR(50) NOT NULL DEFAULT 'free', status VARCHAR(20) NOT NULL DEFAULT 'none', billing_period VARCHAR(20) NOT NULL DEFAULT 'monthly', current_period_start TIMESTAMP WITH TIME ZONE NOT NULL, current_period_end TIMESTAMP WITH TIME ZONE NOT NULL, cancel_at_period_end BOOLEAN DEFAULT FALSE, trial_end TIMESTAMP WITH TIME ZONE, stripe_subscription_id TEXT, stripe_customer_id TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Create indexes for subscriptions CREATE INDEX IF NOT EXISTS idx_subscriptions_user_id ON subscriptions(user_id); CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON subscriptions(status); CREATE INDEX IF NOT EXISTS idx_subscriptions_stripe_subscription_id ON subscriptions(stripe_subscription_id); CREATE INDEX IF NOT EXISTS idx_subscriptions_stripe_customer_id ON subscriptions(stripe_customer_id); CREATE INDEX IF NOT EXISTS idx_subscriptions_trial_end ON subscriptions(trial_end); -- Payment methods table CREATE TABLE IF NOT EXISTS payment_methods ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, type VARCHAR(20) NOT NULL, stripe_payment_method_id TEXT, last4 VARCHAR(4), brand VARCHAR(50), expiry_month INTEGER, expiry_year INTEGER, is_default BOOLEAN DEFAULT FALSE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Create indexes for payment_methods CREATE INDEX IF NOT EXISTS idx_payment_methods_user_id ON payment_methods(user_id); CREATE INDEX IF NOT EXISTS idx_payment_methods_stripe_payment_method_id ON payment_methods(stripe_payment_method_id); -- Invoices table CREATE TABLE IF NOT EXISTS invoices ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, subscription_id TEXT NOT NULL, stripe_invoice_id TEXT, status VARCHAR(20) NOT NULL DEFAULT 'draft', amount BIGINT NOT NULL, currency VARCHAR(3) DEFAULT 'USD', period_start TIMESTAMP WITH TIME ZONE NOT NULL, period_end TIMESTAMP WITH TIME ZONE NOT NULL, paid_at TIMESTAMP WITH TIME ZONE, due_date TIMESTAMP WITH TIME ZONE NOT NULL, invoice_pdf TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Create indexes for invoices CREATE INDEX IF NOT EXISTS idx_invoices_user_id ON invoices(user_id); CREATE INDEX IF NOT EXISTS idx_invoices_subscription_id ON invoices(subscription_id); CREATE INDEX IF NOT EXISTS idx_invoices_stripe_invoice_id ON invoices(stripe_invoice_id); CREATE INDEX IF NOT EXISTS idx_invoices_status ON invoices(status); CREATE INDEX IF NOT EXISTS idx_invoices_paid_at ON invoices(paid_at); -- Usage tracking table CREATE TABLE IF NOT EXISTS usage_tracking ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, limit_type VARCHAR(50) NOT NULL, current_usage BIGINT DEFAULT 0, period_start TIMESTAMP WITH TIME ZONE NOT NULL, period_end TIMESTAMP WITH TIME ZONE NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Create indexes for usage_tracking CREATE INDEX IF NOT EXISTS idx_usage_tracking_user_id ON usage_tracking(user_id); CREATE INDEX IF NOT EXISTS idx_usage_tracking_limit_type ON usage_tracking(limit_type); CREATE INDEX IF NOT EXISTS idx_usage_tracking_period_start ON usage_tracking(period_start); CREATE INDEX IF NOT EXISTS idx_usage_tracking_period_end ON usage_tracking(period_end); -- Add foreign key constraints ALTER TABLE subscriptions ADD CONSTRAINT fk_subscriptions_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; ALTER TABLE payment_methods ADD CONSTRAINT fk_payment_methods_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; ALTER TABLE invoices ADD CONSTRAINT fk_invoices_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; ALTER TABLE invoices ADD CONSTRAINT fk_invoices_subscription FOREIGN KEY (subscription_id) REFERENCES subscriptions(id) ON DELETE CASCADE; ALTER TABLE usage_tracking ADD CONSTRAINT fk_usage_tracking_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;