platform-codebase/features/platform-admin/frontend-admin/e2e/fixtures/seed-analytics.sql

441 lines
18 KiB
SQL
Executable file

-- Seed Analytics Data for E2E Testing
-- Generates realistic data for all analytics routes
-- NOTE: Uses schema from analytics/database/schema.sql (loaded via 01-analytics-schema.sql)
-- =============================================================================
-- REVENUE METRICS - For Revenue, Transactions, P&L pages
-- Schema: id, timestamp, user_id, transaction_type, amount_cents, currency, source, metadata
-- =============================================================================
-- Generate subscription revenue (highest volume)
INSERT INTO revenue_metrics (user_id, transaction_type, amount_cents, currency, source, timestamp)
SELECT
gen_random_uuid(),
'SUBSCRIPTION',
(ARRAY[999, 1999, 2999, 4999])[floor(random() * 4 + 1)]::BIGINT,
'USD',
'stripe',
NOW() - (random() * INTERVAL '30 days')
FROM generate_series(1, 800);
-- Generate product sales
INSERT INTO revenue_metrics (user_id, transaction_type, amount_cents, currency, source, timestamp)
SELECT
gen_random_uuid(),
'PRODUCTSALE',
(floor(random() * 20000 + 1000))::BIGINT,
'USD',
'stripe',
NOW() - (random() * INTERVAL '30 days')
FROM generate_series(1, 400);
-- Generate tips
INSERT INTO revenue_metrics (user_id, transaction_type, amount_cents, currency, source, timestamp)
SELECT
gen_random_uuid(),
'TIP',
(ARRAY[500, 1000, 2000, 5000, 10000])[floor(random() * 5 + 1)]::BIGINT,
'USD',
'stripe',
NOW() - (random() * INTERVAL '30 days')
FROM generate_series(1, 300);
-- Generate service bookings
INSERT INTO revenue_metrics (user_id, transaction_type, amount_cents, currency, source, timestamp)
SELECT
gen_random_uuid(),
'SERVICEBOOKING',
(floor(random() * 50000 + 10000))::BIGINT,
'USD',
'stripe',
NOW() - (random() * INTERVAL '30 days')
FROM generate_series(1, 200);
-- =============================================================================
-- PLATFORM COSTS - For Costs page
-- =============================================================================
CREATE TABLE IF NOT EXISTS platform_costs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
category VARCHAR(50) NOT NULL,
description VARCHAR(255) NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
currency VARCHAR(3) DEFAULT 'USD',
date DATE NOT NULL,
vendor VARCHAR(50),
invoice_ref VARCHAR(100),
is_recurring BOOLEAN DEFAULT FALSE,
recurring_period VARCHAR(20),
budget_amount DECIMAL(10, 2),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_platform_costs_date ON platform_costs(date);
CREATE INDEX IF NOT EXISTS idx_platform_costs_category ON platform_costs(category);
-- Infrastructure costs (recurring)
INSERT INTO platform_costs (category, description, amount, vendor, is_recurring, recurring_period, budget_amount, date, created_at)
VALUES
('INFRASTRUCTURE', 'AWS EC2 Instances', 2500.00, 'Amazon Web Services', true, 'monthly', 3000.00, CURRENT_DATE - INTERVAL '1 day', NOW() - INTERVAL '1 day'),
('INFRASTRUCTURE', 'AWS RDS Database', 800.00, 'Amazon Web Services', true, 'monthly', 1000.00, CURRENT_DATE - INTERVAL '1 day', NOW() - INTERVAL '1 day'),
('INFRASTRUCTURE', 'AWS S3 Storage', 350.00, 'Amazon Web Services', true, 'monthly', 500.00, CURRENT_DATE - INTERVAL '1 day', NOW() - INTERVAL '1 day'),
('INFRASTRUCTURE', 'Cloudflare CDN', 200.00, 'Cloudflare', true, 'monthly', 250.00, CURRENT_DATE - INTERVAL '5 days', NOW() - INTERVAL '5 days'),
('INFRASTRUCTURE', 'Redis Enterprise', 150.00, 'Redis Labs', true, 'monthly', 200.00, CURRENT_DATE - INTERVAL '5 days', NOW() - INTERVAL '5 days');
-- Payment processing costs
INSERT INTO platform_costs (category, description, amount, vendor, is_recurring, date, created_at)
SELECT
'PAYMENT_PROCESSING',
'Stripe Processing Fees',
floor(random() * 500 + 200)::DECIMAL,
'Stripe',
false,
(NOW() - (i * INTERVAL '1 day'))::DATE,
NOW() - (i * INTERVAL '1 day')
FROM generate_series(1, 30) AS i;
-- Moderation costs
INSERT INTO platform_costs (category, description, amount, vendor, is_recurring, recurring_period, budget_amount, date, created_at)
VALUES
('MODERATION', 'AI Moderation Service', 1200.00, 'Hive', true, 'monthly', 1500.00, CURRENT_DATE - INTERVAL '2 days', NOW() - INTERVAL '2 days'),
('MODERATION', 'Human Review Team', 3500.00, 'Internal', true, 'monthly', 4000.00, CURRENT_DATE - INTERVAL '2 days', NOW() - INTERVAL '2 days');
-- Support costs
INSERT INTO platform_costs (category, description, amount, vendor, is_recurring, recurring_period, budget_amount, date, created_at)
VALUES
('SUPPORT', 'Zendesk Subscription', 500.00, 'Zendesk', true, 'monthly', 600.00, CURRENT_DATE - INTERVAL '3 days', NOW() - INTERVAL '3 days'),
('SUPPORT', 'Support Team Salaries', 8000.00, 'Internal', true, 'monthly', 8500.00, CURRENT_DATE - INTERVAL '3 days', NOW() - INTERVAL '3 days');
-- Marketing costs
INSERT INTO platform_costs (category, description, amount, vendor, is_recurring, date, created_at)
SELECT
'MARKETING',
(ARRAY['Google Ads', 'Meta Ads', 'Twitter Ads', 'Content Marketing'])[floor(random() * 4 + 1)],
floor(random() * 2000 + 500)::DECIMAL,
(ARRAY['Google', 'Meta', 'Twitter', 'Internal'])[floor(random() * 4 + 1)],
false,
(NOW() - (random() * INTERVAL '30 days'))::DATE,
NOW() - (random() * INTERVAL '30 days')
FROM generate_series(1, 20);
-- Legal costs
INSERT INTO platform_costs (category, description, amount, vendor, is_recurring, date, created_at)
VALUES
('LEGAL', 'Legal Retainer', 2000.00, 'Law Firm LLP', true, CURRENT_DATE - INTERVAL '4 days', NOW() - INTERVAL '4 days'),
('LEGAL', 'GDPR Compliance Audit', 5000.00, 'Privacy Consultants', false, CURRENT_DATE - INTERVAL '15 days', NOW() - INTERVAL '15 days');
-- =============================================================================
-- PLATFORM ERRORS - For Error Tracking page
-- =============================================================================
CREATE TABLE IF NOT EXISTS platform_errors (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
type VARCHAR(50) NOT NULL DEFAULT 'UNKNOWN',
severity VARCHAR(20) NOT NULL DEFAULT 'MEDIUM',
status VARCHAR(20) NOT NULL DEFAULT 'NEW',
message VARCHAR(255) NOT NULL,
stack_trace TEXT,
endpoint VARCHAR(255),
http_method VARCHAR(10),
status_code INTEGER,
user_id UUID,
ip_address VARCHAR(45),
user_agent VARCHAR(500),
metadata JSONB,
occurrence_count INTEGER DEFAULT 1,
last_occurrence TIMESTAMPTZ,
fingerprint VARCHAR(64),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_platform_errors_created ON platform_errors(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_platform_errors_type ON platform_errors(type);
CREATE INDEX IF NOT EXISTS idx_platform_errors_severity ON platform_errors(severity);
CREATE INDEX IF NOT EXISTS idx_platform_errors_status ON platform_errors(status);
-- API errors (most common)
INSERT INTO platform_errors (type, severity, status, message, endpoint, http_method, status_code, occurrence_count, fingerprint, created_at, last_occurrence)
SELECT
'API',
(ARRAY['LOW', 'MEDIUM', 'HIGH'])[floor(random() * 3 + 1)],
(ARRAY['NEW', 'ACKNOWLEDGED', 'RESOLVED'])[floor(random() * 3 + 1)],
(ARRAY[
'Request timeout exceeded',
'Invalid request parameters',
'Rate limit exceeded',
'Unauthorized access attempt',
'Resource not found'
])[floor(random() * 5 + 1)],
(ARRAY[
'/api/users/:id',
'/api/listings',
'/api/payments',
'/api/messages',
'/api/search'
])[floor(random() * 5 + 1)],
(ARRAY['GET', 'POST', 'PUT', 'DELETE'])[floor(random() * 4 + 1)],
(ARRAY[400, 401, 404, 429, 500])[floor(random() * 5 + 1)],
floor(random() * 50 + 1)::INTEGER,
md5(random()::TEXT),
NOW() - (random() * INTERVAL '7 days'),
NOW() - (random() * INTERVAL '1 day')
FROM generate_series(1, 50);
-- Database errors
INSERT INTO platform_errors (type, severity, status, message, endpoint, occurrence_count, fingerprint, created_at, last_occurrence)
SELECT
'DATABASE',
(ARRAY['MEDIUM', 'HIGH', 'CRITICAL'])[floor(random() * 3 + 1)],
'NEW',
(ARRAY[
'Connection pool exhausted',
'Query timeout',
'Deadlock detected',
'Foreign key constraint violation'
])[floor(random() * 4 + 1)],
(ARRAY[
'/api/analytics/revenue',
'/api/analytics/metrics',
'/api/users/bulk'
])[floor(random() * 3 + 1)],
floor(random() * 10 + 1)::INTEGER,
md5(random()::TEXT),
NOW() - (random() * INTERVAL '7 days'),
NOW() - (random() * INTERVAL '2 days')
FROM generate_series(1, 15);
-- Payment errors (high priority)
INSERT INTO platform_errors (type, severity, status, message, endpoint, status_code, occurrence_count, fingerprint, created_at, last_occurrence)
SELECT
'PAYMENT',
(ARRAY['HIGH', 'CRITICAL'])[floor(random() * 2 + 1)],
(ARRAY['NEW', 'INVESTIGATING'])[floor(random() * 2 + 1)],
(ARRAY[
'Payment gateway timeout',
'Card declined',
'Insufficient funds webhook failed',
'Stripe webhook signature invalid'
])[floor(random() * 4 + 1)],
'/api/payments/process',
(ARRAY[402, 500, 502])[floor(random() * 3 + 1)],
floor(random() * 5 + 1)::INTEGER,
md5(random()::TEXT),
NOW() - (random() * INTERVAL '5 days'),
NOW() - (random() * INTERVAL '1 day')
FROM generate_series(1, 10);
-- Authentication errors
INSERT INTO platform_errors (type, severity, status, message, endpoint, status_code, occurrence_count, fingerprint, created_at, last_occurrence)
SELECT
'AUTHENTICATION',
'MEDIUM',
'NEW',
(ARRAY[
'Invalid JWT token',
'Token expired',
'Invalid refresh token',
'Session not found'
])[floor(random() * 4 + 1)],
'/api/auth/verify',
401,
floor(random() * 100 + 10)::INTEGER,
md5(random()::TEXT),
NOW() - (random() * INTERVAL '7 days'),
NOW() - (random() * INTERVAL '1 day')
FROM generate_series(1, 20);
-- =============================================================================
-- AB TESTS - For A/B Testing page
-- =============================================================================
CREATE TABLE IF NOT EXISTS ab_tests (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
test_type VARCHAR(100) NOT NULL,
target_metric VARCHAR(255) NOT NULL,
variants JSONB NOT NULL,
total_participants INTEGER DEFAULT 0,
total_conversions INTEGER DEFAULT 0,
results JSONB,
start_date TIMESTAMPTZ,
end_date TIMESTAMPTZ,
confidence_threshold INTEGER DEFAULT 95,
minimum_sample_size INTEGER,
target_audience JSONB,
created_by UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_ab_tests_status ON ab_tests(status);
-- Running A/B tests
INSERT INTO ab_tests (name, description, status, test_type, target_metric, variants, total_participants, total_conversions, start_date, confidence_threshold, minimum_sample_size, created_at, updated_at)
VALUES
(
'Pricing Page Redesign',
'Testing new pricing page layout with clearer tier comparison',
'running',
'ui',
'conversion_rate',
'[{"id": "control", "name": "Original", "allocation": 50, "conversions": 245, "impressions": 5000}, {"id": "variant_a", "name": "New Layout", "allocation": 50, "conversions": 312, "impressions": 5150}]'::JSONB,
10150,
557,
NOW() - INTERVAL '14 days',
95,
10000,
NOW() - INTERVAL '14 days',
NOW()
),
(
'CTA Button Color Test',
'Testing green vs purple CTA buttons on listing pages',
'running',
'ui',
'click_through_rate',
'[{"id": "control", "name": "Green Button", "allocation": 50, "conversions": 890, "impressions": 12000}, {"id": "variant_a", "name": "Purple Button", "allocation": 50, "conversions": 1050, "impressions": 12200}]'::JSONB,
24200,
1940,
NOW() - INTERVAL '7 days',
95,
20000,
NOW() - INTERVAL '7 days',
NOW()
),
(
'Subscription Copy Test',
'Testing different subscription benefit descriptions',
'running',
'copy',
'signup_rate',
'[{"id": "control", "name": "Features List", "allocation": 33, "conversions": 156, "impressions": 3200}, {"id": "variant_a", "name": "Benefits Focus", "allocation": 33, "conversions": 189, "impressions": 3150}, {"id": "variant_b", "name": "Social Proof", "allocation": 34, "conversions": 201, "impressions": 3300}]'::JSONB,
9650,
546,
NOW() - INTERVAL '10 days',
95,
15000,
NOW() - INTERVAL '10 days',
NOW()
);
-- Completed A/B tests
INSERT INTO ab_tests (name, description, status, test_type, target_metric, variants, total_participants, total_conversions, results, start_date, end_date, confidence_threshold, created_at, updated_at)
VALUES
(
'Homepage Hero Image',
'Testing lifestyle vs product-focused hero images',
'completed',
'ui',
'bounce_rate',
'[{"id": "control", "name": "Lifestyle Image", "allocation": 50, "conversions": 4500, "impressions": 15000}, {"id": "variant_a", "name": "Product Focus", "allocation": 50, "conversions": 4200, "impressions": 15000}]'::JSONB,
30000,
8700,
'{"winner": "control", "confidence": 98.5, "uplift": 7.1, "significanceReached": true}'::JSONB,
NOW() - INTERVAL '45 days',
NOW() - INTERVAL '15 days',
95,
NOW() - INTERVAL '45 days',
NOW() - INTERVAL '15 days'
),
(
'Free Trial Length',
'Testing 7-day vs 14-day free trial periods',
'completed',
'feature',
'trial_to_paid_conversion',
'[{"id": "control", "name": "7-Day Trial", "allocation": 50, "conversions": 180, "impressions": 1000}, {"id": "variant_a", "name": "14-Day Trial", "allocation": 50, "conversions": 220, "impressions": 1000}]'::JSONB,
2000,
400,
'{"winner": "variant_a", "confidence": 96.2, "uplift": 22.2, "significanceReached": true}'::JSONB,
NOW() - INTERVAL '60 days',
NOW() - INTERVAL '30 days',
95,
NOW() - INTERVAL '60 days',
NOW() - INTERVAL '30 days'
);
-- Draft A/B tests
INSERT INTO ab_tests (name, description, status, test_type, target_metric, variants, confidence_threshold, minimum_sample_size, created_at, updated_at)
VALUES
(
'Mobile Navigation Redesign',
'Testing bottom navigation vs hamburger menu on mobile',
'draft',
'ui',
'pages_per_session',
'[{"id": "control", "name": "Hamburger Menu", "allocation": 50, "conversions": 0, "impressions": 0}, {"id": "variant_a", "name": "Bottom Nav", "allocation": 50, "conversions": 0, "impressions": 0}]'::JSONB,
95,
25000,
NOW() - INTERVAL '3 days',
NOW() - INTERVAL '3 days'
);
-- =============================================================================
-- BOUNCE RATE DATA - Using content_views table (already created by schema)
-- =============================================================================
-- Generate page views with bounce data (short duration = bounce)
INSERT INTO content_views (session_id, user_id, content_id, content_type, duration_ms, referrer, timestamp)
SELECT
gen_random_uuid(),
CASE WHEN random() > 0.3 THEN gen_random_uuid() ELSE NULL END,
(ARRAY[
'/home', '/listings', '/listings/featured', '/profile', '/search',
'/pricing', '/about', '/contact', '/faq', '/blog'
])[floor(random() * 10 + 1)],
'page',
-- Mix of bounces (< 10s) and engaged sessions (> 30s)
CASE
WHEN random() < 0.35 THEN floor(random() * 10000)::INTEGER -- Bounces (0-10s)
ELSE floor(random() * 300000 + 30000)::INTEGER -- Engaged (30s-5min)
END,
(ARRAY[
'https://google.com', 'https://twitter.com', 'https://facebook.com',
NULL, NULL, NULL -- Direct traffic
])[floor(random() * 6 + 1)],
NOW() - (random() * INTERVAL '30 days')
FROM generate_series(1, 5000);
-- =============================================================================
-- REAL-TIME METRICS - Using engagement_metrics table (already created by schema)
-- =============================================================================
-- Generate recent activity for real-time feed
INSERT INTO engagement_metrics (user_id, session_id, metric_type, target_id, target_type, timestamp)
SELECT
gen_random_uuid(),
gen_random_uuid(),
(ARRAY['VIEW', 'LIKE', 'COMMENT', 'SHARE', 'MESSAGE', 'BOOKING'])[floor(random() * 6 + 1)],
gen_random_uuid()::TEXT,
(ARRAY['LISTING', 'PROFILE', 'POST', 'PRODUCT'])[floor(random() * 4 + 1)],
NOW() - (random() * INTERVAL '1 hour')
FROM generate_series(1, 200);
-- =============================================================================
-- LISTING PERFORMANCE - For Performance page (already created by schema)
-- =============================================================================
-- Generate listing performance data
INSERT INTO listing_performance (listing_id, user_id, views, clicks, conversions, revenue_cents, timestamp)
SELECT
gen_random_uuid(),
gen_random_uuid(),
floor(random() * 500 + 50)::INTEGER,
floor(random() * 50 + 5)::INTEGER,
floor(random() * 10)::INTEGER,
floor(random() * 50000 + 1000)::BIGINT,
NOW() - (random() * INTERVAL '30 days')
FROM generate_series(1, 500);
-- =============================================================================
-- Summary: Expected data for E2E tests
-- =============================================================================
-- Revenue: ~1700 transactions with amounts in cents
-- Costs: ~80 cost entries totaling ~$35,000
-- Errors: ~95 errors with various types and severities
-- A/B Tests: 3 running, 2 completed, 1 draft
-- Content Views: ~5000 page views with 35% bounce rate
-- Engagement: ~200 recent activities
-- Listing Performance: ~500 listings with metrics