Initial commit - Black Canyon Tickets whitelabel platform

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-08 12:31:31 -06:00
commit 997c129383
139 changed files with 60476 additions and 0 deletions

View File

@@ -0,0 +1,246 @@
-- Standardize BCT platform fees across all organizations
-- Organizations can only customize HOW fees are applied, not the fee amounts
-- Remove fee amount columns from organizations table since fees are now standard
-- Keep only the fee application model (how fees are presented to customers)
ALTER TABLE organizations
DROP COLUMN IF EXISTS platform_fee_type,
DROP COLUMN IF EXISTS platform_fee_percentage,
DROP COLUMN IF EXISTS platform_fee_fixed;
-- Rename fee model column for clarity
ALTER TABLE organizations
RENAME COLUMN platform_fee_model TO fee_display_model;
-- Add comment for clarity
COMMENT ON COLUMN organizations.fee_display_model IS 'How fees are displayed to customers: customer_pays (separate line) or absorbed_in_price (included)';
COMMENT ON COLUMN organizations.absorb_fee_in_price IS 'Whether to include BCT fee in displayed ticket price (true) or show separately (false)';
-- Create platform_settings table for system-wide configuration
CREATE TABLE platform_settings (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
setting_key TEXT UNIQUE NOT NULL,
setting_value JSONB NOT NULL,
description TEXT,
is_public BOOLEAN DEFAULT false, -- Whether this setting can be viewed by organizers
updated_by UUID REFERENCES users(id),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Insert standard BCT fee structure
INSERT INTO platform_settings (setting_key, setting_value, description, is_public) VALUES
('bct_platform_fee_percentage', '0.025', 'BCT platform fee percentage (2.5%)', true),
('bct_platform_fee_fixed', '150', 'BCT platform fee fixed amount in cents ($1.50)', true),
('stripe_fee_percentage', '0.0299', 'Stripe processing fee percentage (2.99%)', true),
('stripe_fee_fixed', '30', 'Stripe processing fee fixed amount in cents ($0.30)', true),
('platform_name', '"Black Canyon Tickets"', 'Platform display name', true),
('platform_email', '"support@blackcanyontickets.com"', 'Platform support email', true),
('max_events_per_organization', '100', 'Maximum events per organization', false);
-- Update all existing organizations to use standard fee display model
UPDATE organizations
SET
fee_display_model = COALESCE(fee_display_model, 'customer_pays'),
absorb_fee_in_price = COALESCE(absorb_fee_in_price, false);
-- Set default fee display model for new organizations
ALTER TABLE organizations
ALTER COLUMN fee_display_model SET DEFAULT 'customer_pays',
ALTER COLUMN absorb_fee_in_price SET DEFAULT false;
-- Create function to get current BCT platform fees
CREATE OR REPLACE FUNCTION get_bct_platform_fees()
RETURNS TABLE(
fee_percentage DECIMAL,
fee_fixed INTEGER
) AS $$
BEGIN
RETURN QUERY
SELECT
(SELECT (setting_value#>>'{}')::DECIMAL FROM platform_settings WHERE setting_key = 'bct_platform_fee_percentage'),
(SELECT (setting_value#>>'{}')::INTEGER FROM platform_settings WHERE setting_key = 'bct_platform_fee_fixed');
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Create function to get current Stripe fees
CREATE OR REPLACE FUNCTION get_stripe_fees()
RETURNS TABLE(
fee_percentage DECIMAL,
fee_fixed INTEGER
) AS $$
BEGIN
RETURN QUERY
SELECT
(SELECT (setting_value#>>'{}')::DECIMAL FROM platform_settings WHERE setting_key = 'stripe_fee_percentage'),
(SELECT (setting_value#>>'{}')::INTEGER FROM platform_settings WHERE setting_key = 'stripe_fee_fixed');
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Update the display price calculation function to use standard fees
CREATE OR REPLACE FUNCTION calculate_display_price_standard(
base_price DECIMAL,
fee_display_model VARCHAR DEFAULT 'customer_pays'
) RETURNS DECIMAL AS $$
DECLARE
bct_fee_percentage DECIMAL;
bct_fee_fixed INTEGER;
platform_fee DECIMAL;
display_price DECIMAL;
BEGIN
-- Get current BCT platform fees
SELECT fee_percentage, fee_fixed INTO bct_fee_percentage, bct_fee_fixed
FROM get_bct_platform_fees();
-- Calculate BCT platform fee
platform_fee := (base_price * bct_fee_percentage) + (bct_fee_fixed / 100.0);
-- Calculate display price based on fee model
CASE fee_display_model
WHEN 'customer_pays' THEN
-- Customer pays base price + platform fee separately
display_price := base_price;
WHEN 'absorbed_in_price' THEN
-- Platform fee is absorbed into the display price
display_price := base_price + platform_fee;
ELSE
display_price := base_price;
END CASE;
RETURN ROUND(display_price, 2);
END;
$$ LANGUAGE plpgsql;
-- Update the customer total calculation function to use standard fees
CREATE OR REPLACE FUNCTION calculate_customer_total_standard(
base_price DECIMAL,
fee_display_model VARCHAR DEFAULT 'customer_pays'
) RETURNS DECIMAL AS $$
DECLARE
bct_fee_percentage DECIMAL;
bct_fee_fixed INTEGER;
platform_fee DECIMAL;
customer_total DECIMAL;
BEGIN
-- Get current BCT platform fees
SELECT fee_percentage, fee_fixed INTO bct_fee_percentage, bct_fee_fixed
FROM get_bct_platform_fees();
-- Calculate BCT platform fee
platform_fee := (base_price * bct_fee_percentage) + (bct_fee_fixed / 100.0);
-- Calculate total amount customer pays
CASE fee_display_model
WHEN 'customer_pays' THEN
-- Customer pays base price + platform fee separately
customer_total := base_price + platform_fee;
WHEN 'absorbed_in_price' THEN
-- Customer pays only the display price (fee is included)
customer_total := base_price;
ELSE
customer_total := base_price + platform_fee;
END CASE;
RETURN ROUND(customer_total, 2);
END;
$$ LANGUAGE plpgsql;
-- Update the organizer net calculation function to use standard fees
CREATE OR REPLACE FUNCTION calculate_organizer_net_standard(
base_price DECIMAL
) RETURNS DECIMAL AS $$
DECLARE
bct_fee_percentage DECIMAL;
bct_fee_fixed INTEGER;
platform_fee DECIMAL;
organizer_net DECIMAL;
BEGIN
-- Get current BCT platform fees
SELECT fee_percentage, fee_fixed INTO bct_fee_percentage, bct_fee_fixed
FROM get_bct_platform_fees();
-- Calculate BCT platform fee
platform_fee := (base_price * bct_fee_percentage) + (bct_fee_fixed / 100.0);
-- Calculate organizer net (what they receive before Stripe fees)
organizer_net := base_price - platform_fee;
-- Ensure organizer net is never negative
IF organizer_net < 0 THEN
organizer_net := 0;
END IF;
RETURN ROUND(organizer_net, 2);
END;
$$ LANGUAGE plpgsql;
-- Enable RLS on platform_settings
ALTER TABLE platform_settings ENABLE ROW LEVEL SECURITY;
-- Public settings can be viewed by authenticated users
CREATE POLICY "Authenticated users can view public platform settings" ON platform_settings
FOR SELECT USING (is_public = true AND auth.role() = 'authenticated');
-- Only admins can manage platform settings
CREATE POLICY "Admins can manage platform settings" ON platform_settings
FOR ALL USING (auth.uid() IN (SELECT id FROM users WHERE role = 'admin'));
-- Add indexes for performance
CREATE INDEX idx_platform_settings_key ON platform_settings(setting_key);
CREATE INDEX idx_platform_settings_public ON platform_settings(is_public);
CREATE INDEX idx_organizations_fee_display_model ON organizations(fee_display_model);
-- Add check constraint to ensure valid fee display models
ALTER TABLE organizations
DROP CONSTRAINT IF EXISTS check_platform_fee_model,
ADD CONSTRAINT check_fee_display_model
CHECK (fee_display_model IN ('customer_pays', 'absorbed_in_price'));
-- Update fee_structures table to remove custom fee amounts (since fees are now standard)
-- Keep only for reference and templates
ALTER TABLE fee_structures
ADD COLUMN is_deprecated BOOLEAN DEFAULT false;
-- Mark old custom fee structures as deprecated
UPDATE fee_structures
SET is_deprecated = true
WHERE is_template = false;
-- Clean up old fee structure templates and add new standard ones
DELETE FROM fee_structures WHERE is_template = true;
INSERT INTO fee_structures (name, description, fee_type, fee_percentage, fee_fixed, fee_model, absorb_fee_in_price, is_template) VALUES
('BCT Standard - Customer Pays', 'Customer pays BCT fee (2.5% + $1.50) as separate line item', 'percentage_plus_fixed', 0.025, 150, 'customer_pays', false, true),
('BCT Standard - All Inclusive', 'BCT fee (2.5% + $1.50) included in ticket price', 'percentage_plus_fixed', 0.025, 150, 'absorbed_in_price', true, true),
('Stripe Processing Fee', 'Stripe credit card processing: 2.99% + $0.30', 'percentage_plus_fixed', 0.0299, 30, 'customer_pays', false, true);
-- Add audit logging for platform settings changes
CREATE OR REPLACE FUNCTION log_platform_settings_change()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'UPDATE' THEN
INSERT INTO audit_logs (user_id, action, resource_type, resource_id, old_values, new_values)
VALUES (
auth.uid(),
'update',
'platform_settings',
NEW.id,
row_to_json(OLD),
row_to_json(NEW)
);
ELSIF TG_OP = 'INSERT' THEN
INSERT INTO audit_logs (user_id, action, resource_type, resource_id, new_values)
VALUES (
auth.uid(),
'create',
'platform_settings',
NEW.id,
row_to_json(NEW)
);
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER platform_settings_audit_trigger
AFTER INSERT OR UPDATE ON platform_settings
FOR EACH ROW EXECUTE FUNCTION log_platform_settings_change();