new-site/api/migrations/008_bundles.sql
justin f8cd37ac8c Initial commit — Performance West telecom compliance platform
Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 06:54:22 -05:00

125 lines
4.5 KiB
PL/PgSQL

-- 008_bundles.sql
-- Service bundles — 20% off when purchasing all services in a category
-- or mix-and-match across categories.
BEGIN;
CREATE TABLE IF NOT EXISTS service_bundles (
id SERIAL PRIMARY KEY,
slug TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
description TEXT,
-- Which services are included (array of service slugs)
services TEXT[] NOT NULL,
-- Pricing
discount_pct INTEGER NOT NULL DEFAULT 20, -- 20% off
-- Category: 'employment', 'privacy', 'tcpa', 'telecom', 'corporate', 'multi'
category TEXT NOT NULL,
-- Display
active BOOLEAN DEFAULT TRUE,
display_order INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Category bundles (all services in one category)
INSERT INTO service_bundles (slug, name, description, services, discount_pct, category, display_order) VALUES
(
'employment-complete',
'Employment Compliance Bundle',
'Complete employment compliance coverage: FLSA audit, contractor classification (up to 5 workers), employee handbook review, and workplace policy development.',
ARRAY['flsa-audit', 'contractor-classification', 'handbook-review', 'policy-development'],
20,
'employment',
1
),
(
'privacy-complete',
'Data Privacy Bundle',
'Full privacy compliance: CCPA/CPRA audit, privacy policy generation, data mapping & inventory, and breach response planning.',
ARRAY['ccpa-audit', 'privacy-policy', 'data-mapping', 'breach-response'],
20,
'privacy',
2
),
(
'tcpa-complete',
'TCPA Compliance Bundle',
'Complete TCPA/marketing compliance: SMS/call consent audit, DNC list compliance review, and marketing campaign review.',
ARRAY['consent-audit', 'dnc-compliance', 'campaign-review'],
20,
'tcpa',
3
),
(
'telecom-complete',
'Telecom Compliance Bundle',
'Full telecom regulatory compliance: FCC 499A filing, STIR/SHAKEN implementation, IPES & ISP registrations, telecom database management, and state PUC/PSC filings.',
ARRAY['fcc-499a', 'stir-shaken', 'ipes-isp', 'database-management', 'state-puc'],
20,
'telecom',
4
),
(
'corporate-complete',
'Corporate Services Bundle',
'Complete business setup: business formation, state registration, annual report filing, and registered agent service.',
ARRAY['formation', 'state-registration', 'annual-reports', 'registered-agent'],
20,
'corporate',
5
),
-- Cross-category bundles
(
'startup-essentials',
'Startup Essentials Bundle',
'Everything a new business needs: business formation + contractor classification (up to 3 workers) + privacy policy + employee handbook review.',
ARRAY['formation', 'contractor-classification', 'privacy-policy', 'handbook-review'],
20,
'multi',
10
),
(
'compliance-360',
'Compliance 360 Bundle',
'Comprehensive multi-domain compliance: FLSA audit + contractor classification (up to 10 workers) + handbook review + CCPA audit + consent audit. The most complete compliance package available.',
ARRAY['flsa-audit', 'contractor-classification', 'handbook-review', 'ccpa-audit', 'consent-audit'],
20,
'multi',
11
)
ON CONFLICT (slug) DO NOTHING;
-- Track bundle orders
CREATE TABLE IF NOT EXISTS bundle_orders (
id SERIAL PRIMARY KEY,
bundle_slug TEXT NOT NULL REFERENCES service_bundles(slug),
order_number TEXT UNIQUE NOT NULL,
customer_name TEXT NOT NULL,
customer_email TEXT NOT NULL,
customer_phone TEXT,
customer_company TEXT,
-- Pricing
original_total_cents INTEGER NOT NULL, -- sum of individual service prices
discount_pct INTEGER NOT NULL,
discount_cents INTEGER NOT NULL,
final_total_cents INTEGER NOT NULL,
-- Add-ons
attorney_review BOOLEAN DEFAULT FALSE,
attorney_review_fee_cents INTEGER DEFAULT 0,
discount_code TEXT,
discount_code_cents INTEGER DEFAULT 0,
-- Status
status TEXT DEFAULT 'received' CHECK (status IN (
'received', 'processing', 'review', 'delivered', 'cancelled'
)),
-- Individual service order IDs (populated as each service is fulfilled)
service_order_ids INTEGER[],
notes TEXT,
created_at TIMESTAMPTZ DEFAULT now(),
delivered_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_bundle_orders_status ON bundle_orders(status);
CREATE INDEX IF NOT EXISTS idx_bundle_orders_email ON bundle_orders(customer_email);
COMMIT;