mirror of
https://github.com/hanzoai/computer.git
synced 2026-09-30 20:55:46 +00:00
Complete Production Features (1-7): ==================================== 1. STRIPE PAYMENT INTEGRATION ✅ - Full checkout flow with Stripe Elements - Payment intent creation for one-time purchases - Subscription creation for monthly GPU leasing - Success page with order confirmation - Serverless functions: create-payment-intent, create-subscription - PCI-compliant card input with glass-morphism styling - Error handling and loading states - Test mode ready with Stripe test keys 2. EMAIL NOTIFICATION SYSTEM ✅ - SendGrid integration with professional templates - Quote emails with validity period - Order confirmations with invoice details - Subscription activation emails - RFQ confirmations (customer + admin) - Cluster request notifications - HTML + plain text versions - Responsive email design with Hanzo branding - API endpoints: send-quote, send-order, send-subscription, send-rfq 3. PDF INVOICE GENERATION ✅ - @react-pdf/renderer integration - Professional invoice templates with Hanzo branding - Automatic generation on order payment - Download from customer dashboard - Supabase storage integration - Admin invoice management - Regenerate capability - Email invoice attachments ready 4. USAGE ANALYTICS DASHBOARD ✅ - Comprehensive customer analytics at /analytics - Interactive charts: Line, Bar, Pie, Area charts - Metrics: compute hours, costs, GPU utilization - Date range selector (7/30/90 days, all time) - CSV export functionality - Usage tracking with Recharts - Real-time data from Supabase - Sample data generator for demo 5. API RATE LIMITING ✅ - Upstash Redis-based rate limiting - Role-based limits: anonymous (10/min), auth (100/min), admin (1000/min) - Endpoint-specific limits for sensitive operations - 429 Too Many Requests responses - Rate limit headers (X-RateLimit-*) - Frontend retry with exponential backoff - Admin dashboard for monitoring - Clear rate limits endpoint for admins - Database logging and violation tracking 6. STRIPE WEBHOOK HANDLERS ✅ - Webhook endpoint: /api/webhooks/stripe - Event handlers: payment success/failure, subscriptions, invoices, refunds - Signature verification for security - Idempotency handling (prevent duplicates) - Automatic order creation on payment - Subscription lifecycle management - Email triggers on events - Admin retry capability - Comprehensive event logging - Database schema for webhook tracking 7. ADMIN ANALYTICS & CHARTS ✅ - Enhanced Admin Dashboard with Analytics tab - Revenue charts: time series, by GPU type, cumulative - Conversion funnel: RFQ → Quote → Order - Customer growth metrics - Operational metrics: response times, quote performance - Top customers table - Interactive Recharts visualizations - Date range filtering - Auto-refresh every 5 minutes - CSV export for reports - Key metrics cards with % change indicators Technical Implementation: ======================== New Dependencies: - @stripe/stripe-js, @stripe/react-stripe-js, stripe - @sendgrid/mail - @react-pdf/renderer - recharts, date-fns - @upstash/ratelimit, @upstash/redis - micro (webhook body parsing) New Files Created (50+): - API routes: /api/webhooks/, /api/admin/, /api/create-*, /api/send-* - Libraries: stripe.ts, email.ts, invoices.ts, analytics.ts, rateLimit.ts - Components: Invoice, WebhookEventLog, RateLimitDashboard, DashboardInvoices - Pages: Analytics, CheckoutSuccess, admin/RateLimitDashboard - Documentation: EMAIL_NOTIFICATIONS.md, STRIPE_WEBHOOKS.md, RATE_LIMITING.md - Database: Supabase migrations for webhooks, analytics, rate limiting Environment Variables Required: - STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET - VITE_STRIPE_PUBLISHABLE_KEY - SENDGRID_API_KEY, EMAIL_FROM, ADMIN_EMAIL - UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN - ADMIN_API_KEY Build Status: ============= ✓ Production build: 807KB gzipped ✓ 3480 modules transformed ✓ Build time: 5.20s ✓ All TypeScript validated ✓ Zero compilation errors Ready for Launch: ================= ✅ Complete payment processing ✅ Professional email communications ✅ Automated invoicing ✅ Customer analytics ✅ API protection ✅ Webhook automation ✅ Business intelligence dashboard The platform is now enterprise-ready for production deployment!
180 lines
6.0 KiB
PL/PgSQL
180 lines
6.0 KiB
PL/PgSQL
-- Rate Limiting Log Table
|
|
CREATE TABLE IF NOT EXISTS rate_limit_log (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
endpoint TEXT NOT NULL,
|
|
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
ip_address INET,
|
|
success BOOLEAN DEFAULT true,
|
|
response_time_ms INTEGER,
|
|
user_agent TEXT,
|
|
method TEXT,
|
|
status_code INTEGER
|
|
);
|
|
|
|
-- Index for faster queries
|
|
CREATE INDEX idx_rate_limit_user_timestamp ON rate_limit_log(user_id, timestamp DESC);
|
|
CREATE INDEX idx_rate_limit_endpoint_timestamp ON rate_limit_log(endpoint, timestamp DESC);
|
|
CREATE INDEX idx_rate_limit_ip_timestamp ON rate_limit_log(ip_address, timestamp DESC);
|
|
CREATE INDEX idx_rate_limit_timestamp ON rate_limit_log(timestamp DESC);
|
|
|
|
-- Rate Limit Rules Table (for custom limits per user/endpoint)
|
|
CREATE TABLE IF NOT EXISTS rate_limit_rules (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
endpoint TEXT,
|
|
requests_per_minute INTEGER DEFAULT 100,
|
|
requests_per_hour INTEGER DEFAULT 1000,
|
|
requests_per_day INTEGER DEFAULT 10000,
|
|
enabled BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
UNIQUE(user_id, endpoint)
|
|
);
|
|
|
|
-- Rate Limit Violations Table (for tracking abuse)
|
|
CREATE TABLE IF NOT EXISTS rate_limit_violations (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
ip_address INET,
|
|
endpoint TEXT NOT NULL,
|
|
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
requests_attempted INTEGER,
|
|
limit_exceeded INTEGER,
|
|
blocked_until TIMESTAMP WITH TIME ZONE
|
|
);
|
|
|
|
-- Function to check rate limits
|
|
CREATE OR REPLACE FUNCTION check_rate_limit(
|
|
p_user_id UUID,
|
|
p_endpoint TEXT,
|
|
p_ip_address INET
|
|
) RETURNS TABLE(
|
|
allowed BOOLEAN,
|
|
remaining_requests INTEGER,
|
|
reset_at TIMESTAMP WITH TIME ZONE
|
|
) AS $$
|
|
DECLARE
|
|
v_requests_per_minute INTEGER;
|
|
v_requests_count INTEGER;
|
|
v_custom_limit INTEGER;
|
|
BEGIN
|
|
-- Check if user has custom limits
|
|
SELECT requests_per_minute INTO v_custom_limit
|
|
FROM rate_limit_rules
|
|
WHERE user_id = p_user_id
|
|
AND (endpoint = p_endpoint OR endpoint IS NULL)
|
|
AND enabled = true
|
|
ORDER BY endpoint DESC NULLS LAST
|
|
LIMIT 1;
|
|
|
|
-- Use custom limit or default
|
|
v_requests_per_minute := COALESCE(v_custom_limit, 100);
|
|
|
|
-- Count recent requests
|
|
SELECT COUNT(*) INTO v_requests_count
|
|
FROM rate_limit_log
|
|
WHERE (user_id = p_user_id OR (user_id IS NULL AND ip_address = p_ip_address))
|
|
AND endpoint = p_endpoint
|
|
AND timestamp > NOW() - INTERVAL '1 minute';
|
|
|
|
-- Log this request
|
|
INSERT INTO rate_limit_log (user_id, endpoint, ip_address, timestamp, success)
|
|
VALUES (p_user_id, p_endpoint, p_ip_address, NOW(), v_requests_count < v_requests_per_minute);
|
|
|
|
-- Return result
|
|
RETURN QUERY
|
|
SELECT
|
|
v_requests_count < v_requests_per_minute AS allowed,
|
|
GREATEST(0, v_requests_per_minute - v_requests_count)::INTEGER AS remaining_requests,
|
|
NOW() + INTERVAL '1 minute' AS reset_at;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Function to clean old logs (run daily)
|
|
CREATE OR REPLACE FUNCTION clean_old_rate_limit_logs() RETURNS void AS $$
|
|
BEGIN
|
|
-- Delete logs older than 7 days
|
|
DELETE FROM rate_limit_log
|
|
WHERE timestamp < NOW() - INTERVAL '7 days';
|
|
|
|
-- Delete violations older than 30 days
|
|
DELETE FROM rate_limit_violations
|
|
WHERE timestamp < NOW() - INTERVAL '30 days';
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Create a scheduled job to clean old logs (requires pg_cron extension)
|
|
-- Run this if pg_cron is available:
|
|
-- SELECT cron.schedule('clean-rate-limit-logs', '0 2 * * *', 'SELECT clean_old_rate_limit_logs()');
|
|
|
|
-- Row Level Security Policies
|
|
ALTER TABLE rate_limit_log ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE rate_limit_rules ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE rate_limit_violations ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Admin users can view all logs
|
|
CREATE POLICY "Admin users can view all rate limit logs" ON rate_limit_log
|
|
FOR ALL USING (
|
|
EXISTS (
|
|
SELECT 1 FROM auth.users
|
|
WHERE auth.uid() = id
|
|
AND raw_user_meta_data->>'role' = 'admin'
|
|
)
|
|
);
|
|
|
|
-- Users can view their own logs
|
|
CREATE POLICY "Users can view own rate limit logs" ON rate_limit_log
|
|
FOR SELECT USING (auth.uid() = user_id);
|
|
|
|
-- Admin users can manage rate limit rules
|
|
CREATE POLICY "Admin users can manage rate limit rules" ON rate_limit_rules
|
|
FOR ALL USING (
|
|
EXISTS (
|
|
SELECT 1 FROM auth.users
|
|
WHERE auth.uid() = id
|
|
AND raw_user_meta_data->>'role' = 'admin'
|
|
)
|
|
);
|
|
|
|
-- Admin users can view violations
|
|
CREATE POLICY "Admin users can view rate limit violations" ON rate_limit_violations
|
|
FOR ALL USING (
|
|
EXISTS (
|
|
SELECT 1 FROM auth.users
|
|
WHERE auth.uid() = id
|
|
AND raw_user_meta_data->>'role' = 'admin'
|
|
)
|
|
);
|
|
|
|
-- Create views for easier monitoring
|
|
CREATE OR REPLACE VIEW rate_limit_stats AS
|
|
SELECT
|
|
endpoint,
|
|
COUNT(*) as total_requests,
|
|
COUNT(CASE WHEN success THEN 1 END) as successful_requests,
|
|
COUNT(CASE WHEN NOT success THEN 1 END) as blocked_requests,
|
|
AVG(response_time_ms) as avg_response_time,
|
|
DATE_TRUNC('hour', timestamp) as hour
|
|
FROM rate_limit_log
|
|
WHERE timestamp > NOW() - INTERVAL '24 hours'
|
|
GROUP BY endpoint, DATE_TRUNC('hour', timestamp)
|
|
ORDER BY hour DESC, total_requests DESC;
|
|
|
|
CREATE OR REPLACE VIEW rate_limit_user_stats AS
|
|
SELECT
|
|
u.email,
|
|
u.id as user_id,
|
|
COUNT(r.*) as total_requests,
|
|
COUNT(CASE WHEN r.success THEN 1 END) as successful_requests,
|
|
COUNT(CASE WHEN NOT r.success THEN 1 END) as blocked_requests,
|
|
MAX(r.timestamp) as last_request
|
|
FROM auth.users u
|
|
LEFT JOIN rate_limit_log r ON u.id = r.user_id
|
|
WHERE r.timestamp > NOW() - INTERVAL '24 hours'
|
|
GROUP BY u.id, u.email
|
|
ORDER BY total_requests DESC;
|
|
|
|
-- Grant necessary permissions
|
|
GRANT SELECT ON rate_limit_stats TO authenticated;
|
|
GRANT SELECT ON rate_limit_user_stats TO authenticated; |