EPGOAT Production Deployment Checklist
Status: Active
Last Updated: 2025-11-02
Related Docs: Cloudflare Setup, D1 Manager Setup, System Overview
Code Location: .github/workflows/, backend/config/wrangler.toml
Target Launch Date: TBD
Table of Contents
- Pre-Launch Overview
- Infrastructure Setup
- Authentication & Security
- Payment Processing
- Database Deployment
- API Deployment
- Frontend Deployment
- Automation & CI/CD
- Monitoring & Alerts
- Legal & Compliance
- Go-Live
- Post-Launch
Pre-Launch Overview
Launch Criteria
Before launching to production, all items in this checklist must be completed and verified.
Critical Success Factors:
- [ ] Match rate ≥90% on all providers (baseline: 96%+)
- [ ] API response time <200ms (p95)
- [ ] Zero security vulnerabilities (high/critical)
- [ ] Payment processing tested end-to-end
- [ ] Legal pages (Terms, Privacy) reviewed by counsel
- [ ] Support email active and monitored
- [ ] Backup and recovery procedures tested
Launch Phases:
- Soft Launch (Week 1): Friends & family (20 users)
- Beta Launch (Week 2-4): Limited invites (100 users)
- Public Launch (Week 5+): Open registration
Infrastructure Setup
✅ Cloudflare Account Configuration
Account Setup:
- [ ] Create Cloudflare account (use company email:
admin@epgoat.tv) - [ ] Enable 2FA on Cloudflare account
- [ ] Add payment method (credit card for paid tier if needed)
- [ ] Set up team members with appropriate roles:
- Admin: Full access (2 people max)
- Developer: D1, R2, Workers access (all devs)
- Billing: Billing access only (1 person)
Domain Configuration:
- [ ] Purchase domain:
epgoat.tv(Cloudflare Registrar: $9.77/year) -
[ ] Configure DNS records:
A @ 192.0.2.1 (proxy enabled) → Marketing site CNAME app epgoat-app.pages.dev (proxy enabled) → Consumer portal CNAME admin epgoat-admin.pages.dev (proxy enabled) → Admin dashboard CNAME api epgoat-api.workers.dev (proxy enabled) → API MX @ route1.mx.cloudflare.net (priority 10) → Email routing TXT @ "v=spf1 include:_spf.mx.cloudflare.net ~all" → SPF record -
[ ] Enable HTTPS (automatic via Cloudflare)
- [ ] Set SSL/TLS to "Full (strict)"
- [ ] Enable "Always Use HTTPS"
- [ ] Enable HSTS (max-age: 31536000)
Supabase PostgreSQL Database:
-
[ ] Create Supabase database via wrangler CLI:
bash supabase create epgoat-production # Output: Database ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -
[ ] Deploy schema:
bash supabase db execute epgoat-production --file=schema.sql -
[ ] Verify schema:
bash supabase db execute epgoat-production --command="SELECT name FROM sqlite_master WHERE type='table';" # Should list all 26 tables -
[ ] Enable D1 backups (automatic in Cloudflare dashboard)
- [ ] Set up point-in-time recovery (PITR)
Cloudflare R2 Storage:
-
[ ] Create R2 bucket:
epgoat-productionbash wrangler r2 bucket create epgoat-production -
[ ] Configure CORS (allow app.epgoat.tv and admin.epgoat.tv):
json [ { "AllowedOrigins": ["https://app.epgoat.tv", "https://admin.epgoat.tv"], "AllowedMethods": ["GET", "HEAD"], "AllowedHeaders": ["*"], "MaxAgeSeconds": 3600 } ] -
[ ] Set up custom domain for R2:
epgo.atbash wrangler r2 bucket domain add epgoat-production --domain=epgo.at -
[ ] Test EPG access URL:
https://epgo.at/<test-key>/tps.xml
Cloudflare Workers:
-
[ ] Create Workers KV namespace for rate limiting:
bash wrangler kv:namespace create "RATE_LIMIT" wrangler kv:namespace create "RATE_LIMIT" --preview -
[ ] Create Workers secrets:
bash wrangler secret put AUTH0_DOMAIN wrangler secret put AUTH0_AUDIENCE wrangler secret put STRIPE_SECRET_KEY wrangler secret put STRIPE_WEBHOOK_SECRET wrangler secret put ANTHROPIC_API_KEY -
[ ] Deploy API workers:
bash cd api wrangler deploy # Verify deployment: https://api.epgoat.tv/health
Cloudflare Pages:
- [ ] Create Pages project:
epgoat-marketing - Connect GitHub repo
- Build command:
npm run build - Output directory:
dist -
Environment variables: (none for marketing site)
-
[ ] Create Pages project:
epgoat-app - Connect GitHub repo (frontend/consumer)
- Build command:
npm run build - Output directory:
dist -
Environment variables:
VITE_AUTH0_DOMAIN=epgoat.us.auth0.com VITE_AUTH0_CLIENT_ID=<client_id> VITE_AUTH0_AUDIENCE=https://api.epgoat.tv VITE_STRIPE_PUBLISHABLE_KEY=pk_live_... VITE_API_BASE_URL=https://api.epgoat.tv -
[ ] Create Pages project:
epgoat-admin - Connect GitHub repo (frontend/admin)
- Build command:
npm run build - Output directory:
dist -
Environment variables: (same as consumer + admin flag)
-
[ ] Set up custom domains:
epgoat.tv→ epgoat-marketingapp.epgoat.tv→ epgoat-app-
admin.epgoat.tv→ epgoat-admin -
[ ] Enable automatic deployments on
mainbranch push - [ ] Set up preview deployments for PRs
Authentication & Security
✅ Auth0 Configuration
Tenant Setup:
- [ ] Create Auth0 tenant:
epgoat(US region) - Domain:
epgoat.us.auth0.com - Enable MFA: time-based OTP
-
Enable breached password detection
-
[ ] Create Auth0 applications:
1. Consumer SPA:
- Name: "EPGOAT Consumer Portal"
- Type: Single Page Application
- Allowed Callback URLs:
https://app.epgoat.tv,
https://app.epgoat.tv/callback,
http://localhost:5173,
http://localhost:5173/callback
- Allowed Logout URLs:
https://app.epgoat.tv,
http://localhost:5173
- Allowed Web Origins:
https://app.epgoat.tv,
http://localhost:5173
- JWT Expiration: 3600 seconds (1 hour)
- Refresh Token: Enabled (30 day rotation)
2. Admin SPA:
- Name: "EPGOAT Admin Dashboard"
- Type: Single Page Application
- Same URLs as consumer, but with admin.epgoat.tv
3. API:
- Name: "EPGOAT API"
- Type: API
- Identifier: https://api.epgoat.tv
- Signing Algorithm: RS256
- Token Expiration: 86400 seconds (24 hours)
- RBAC: Enabled
- Add permissions to token: Enabled
- [ ] Configure social connections:
-
Google OAuth:
- Enable Google connection
- Add scopes: email, profile
- Use Auth0 dev keys initially
- Switch to custom Google OAuth app before launch
-
Email/Password:
- Enable Username-Password-Authentication
- Password strength: Good (8+ chars, upper, lower, number, symbol)
- Enable password dictionary check
- Disable signup (invite-only initially)
-
[ ] Set up Auth0 Rules (custom claims):
```javascript // Rule: Add Custom Claims function addCustomClaims(user, context, callback) { const namespace = 'https://epgoat.tv/';
// Fetch user metadata from D1 via API
const apiUrl = 'https://api.epgoat.tv/internal/user-metadata';
request.get({
url: apiUrl,
headers: {
'X-Auth0-User-ID': user.user_id
}
}, (err, response, body) => {
if (err) return callback(err);
const metadata = JSON.parse(body);
context.idToken[namespace + 'role'] = metadata.role;
context.idToken[namespace + 'user_id'] = metadata.user_id;
context.idToken[namespace + 'subscription_status'] = metadata.subscription_status;
callback(null, user, context);
});
} ```
- [ ] Configure email templates:
-
Verification Email:
- Subject: "Verify your EPGOAT account"
- Customize HTML template with branding
- Test email delivery
-
Welcome Email:
- Subject: "Welcome to EPGOAT!"
- Include quick start guide
- Link to documentation
-
Password Reset:
- Subject: "Reset your EPGOAT password"
- Customize HTML template
- Test reset flow
-
[ ] Set up MFA:
- Enable Google Authenticator
- Enable SMS (optional, costs apply)
-
Require MFA for admin role
-
[ ] Configure attack protection:
- Brute force protection: 10 attempts per IP
- Suspicious IP throttling: Enabled
- Breached password detection: Enabled
Security Testing:
- [ ] Test login flow (Google OAuth)
- [ ] Test login flow (email/password)
- [ ] Test MFA enrollment and verification
- [ ] Test password reset flow
- [ ] Test token refresh flow
- [ ] Test logout flow
- [ ] Test JWT signature verification on API
- [ ] Test role-based access control (consumer, reseller, admin)
- [ ] Test Auth0 Universal Login customization
Payment Processing
✅ Stripe Configuration
Account Setup:
- [ ] Create Stripe account (use
billing@epgoat.tv) - [ ] Activate Stripe account:
- Complete business verification
- Add bank account for payouts
- Set payout schedule (daily)
-
Enable 2FA on Stripe account
-
[ ] Switch to live mode (toggle in dashboard)
Products & Prices:
- [ ] Create products in Stripe:
1. Consumer Annual:
Name: EPGOAT Consumer Annual
Price: $7.99/year
Billing: Recurring (annual)
Price ID: price_consumer_annual
Tax behavior: Taxable
2. Consumer Trial (No CC):
Name: EPGOAT Consumer Trial
Price: $0.00 (30 days)
Billing: One-time
Price ID: price_consumer_trial_no_cc
3. Consumer Trial (Enhanced):
Name: EPGOAT Consumer Enhanced Trial
Price: $0.00 (60 days)
Billing: Subscription with trial
Price ID: price_consumer_trial_enhanced
Note: Auto-converts to price_consumer_annual
4. Reseller Annual (per pack):
Name: EPGOAT Reseller Pack
Price: $99.00/year
Billing: Recurring (annual)
Price ID: price_reseller_annual
Tax behavior: Taxable
Metered: No (per-pack pricing)
- [ ] Test product creation:
bash # Use Stripe CLI to verify stripe products list stripe prices list
Stripe Tax:
- [ ] Enable Stripe Tax:
- Go to Settings → Tax
- Enable automatic tax calculation
-
Add tax registrations:
- United States (required)
- European Union (if selling to EU)
- Canada (if selling to Canada)
-
[ ] Configure tax behavior:
- Default tax behavior: Inclusive (EU) / Exclusive (US)
- Customer tax IDs: Optional
-
Validate tax IDs: Yes
-
[ ] Test tax calculation:
- US customer (CA): $7.99 + 9.5% = $8.75
- EU customer (DE): €7.50 + 19% VAT = €8.93
- No-tax state (MT): $7.99 + 0% = $7.99
Webhooks:
-
[ ] Create webhook endpoint: ``` URL: https://api.epgoat.tv/webhooks/stripe Description: EPGOAT Production Webhooks Events to send:
- customer.subscription.created
- customer.subscription.trial_will_end
- customer.subscription.updated
- customer.subscription.deleted
- invoice.paid
- invoice.payment_failed
- invoice.payment_action_required
- invoice.upcoming
- charge.succeeded
- charge.failed
- charge.dispute.created
- payment_intent.succeeded
- payment_intent.payment_failed ```
-
[ ] Save webhook signing secret:
bash wrangler secret put STRIPE_WEBHOOK_SECRET # Paste secret from Stripe dashboard -
[ ] Test webhook delivery:
bash stripe trigger customer.subscription.created # Verify event received in API logs
Stripe Radar (Fraud Prevention):
- [ ] Review default Radar rules:
- Block charges from high-risk countries: Disabled (allow global)
- Review charges from risky cards: Enabled
-
3D Secure for payments >$100: Enabled
-
[ ] Add custom Radar rules:
Block if :risk_score: > 85 Review if :card_country: != :ip_country: Allow if :customer_created: < 7 days ago AND :amount: < 10
Customer Portal:
- [ ] Enable Stripe Customer Portal:
- Go to Settings → Billing → Customer Portal
- Enable customer portal
- Configure features:
- Invoice history: Enabled
- Update payment method: Enabled
- Cancel subscription: Enabled (at period end only)
- Pause subscription: Disabled
- Branding:
- Logo: Upload EPGOAT logo
- Icon: Upload favicon
- Accent color: #1976d2
-
Business information:
- Business name: EPGOAT
- Support email: support@epgoat.tv
- Privacy policy URL: https://epgoat.tv/privacy
- Terms of service URL: https://epgoat.tv/terms
-
[ ] Test customer portal access
Testing:
- [ ] Test subscription creation (annual plan)
- [ ] Test trial subscription (no CC)
- [ ] Test trial subscription (enhanced with CC)
- [ ] Test trial-to-paid conversion
- [ ] Test payment failure handling
- [ ] Test subscription cancellation
- [ ] Test subscription reactivation
- [ ] Test invoice generation
- [ ] Test payment retry (failed payment)
- [ ] Test 3D Secure flow (EU cards)
- [ ] Test Stripe Checkout redirect flow
- [ ] Test webhook event processing
- [ ] Test refund processing
- [ ] Test chargeback notification
Database Deployment
✅ Supabase Database Setup
Schema Deployment:
-
[ ] Deploy production schema:
bash supabase db execute epgoat-production --file=schema.sql -
[ ] Verify all tables created:
bash supabase db execute epgoat-production --command="SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"Expected output: 26 tables -
[ ] Verify all indexes created:
bash supabase db execute epgoat-production --command="SELECT name FROM sqlite_master WHERE type='index' ORDER BY name;" -
[ ] Verify triggers created:
bash supabase db execute epgoat-production --command="SELECT name FROM sqlite_master WHERE type='trigger' ORDER BY name;"
Seed Data:
-
[ ] Insert provider configurations:
sql INSERT INTO providers (name, slug, display_name, m3u_url, default_timezone, active) VALUES ('TPS', 'tps', 'TPS IPTV', 'https://...', 'America/New_York', 1), ('BestBuy', 'bestbuy', 'BestBuy IPTV', 'https://...', 'America/Chicago', 1); -
[ ] Insert channel families (critical for 40-60% improvement):
sql INSERT INTO channel_families (provider_id, family_name, family_pattern, match_behavior, active, priority) VALUES (1, 'NBA', '^NBA\s+\d+', 'single_event', 1, 100), (1, 'NFL', '^NFL\s+\d+', 'single_event', 1, 100), (1, 'UFC', '^UFC\s+\d+', 'single_event', 1, 90); -
[ ] Insert family league mappings:
sql INSERT INTO family_league_mappings (family_id, league, sport, require_exact_league, confidence_boost) VALUES (1, 'NBA', 'Basketball', 1, 0.15), (2, 'NFL', 'American Football', 1, 0.15), (3, 'UFC', 'MMA', 1, 0.10); -
[ ] Insert admin user:
sql INSERT INTO users (auth0_id, email, email_verified, name, role, status, signup_source) VALUES ('auth0|admin123', 'admin@epgoat.tv', 1, 'Admin User', 'admin', 'active', 'manual');
Backup Configuration:
- [ ] Enable automatic backups (Cloudflare dashboard)
- [ ] Set retention: 30 days
- [ ] Test backup restore: ```bash # Create manual backup supabase backup create epgoat-production
# List backups supabase backup list epgoat-production
# Test restore to new database
supabase create epgoat-test
supabase backup restore epgoat-test --backup-id=
Database Monitoring:
- [ ] Set up storage alerts (email when >80% full):
- Cloudflare dashboard → D1 → epgoat-production → Alerts
- Alert threshold: 4GB (80% of 5GB free tier)
-
Notification email: admin@epgoat.tv
-
[ ] Set up query performance monitoring:
- Enable D1 analytics in dashboard
- Monitor slow queries (>100ms)
- Set up alert for error rate >1%
API Deployment
✅ Cloudflare Workers API
Worker Configuration:
- [ ] Review wrangler.toml: ```toml name = "epgoat-api" main = "src/index.ts" compatibility_date = "2025-10-30"
[env.production] route = "api.epgoat.tv/*"
[[d1_databases]]
binding = "DB"
database_name = "epgoat-production"
database_id = "
[[r2_buckets]] binding = "STORAGE" bucket_name = "epgoat-production"
[[kv_namespaces]]
binding = "RATE_LIMIT"
id = "
-
[ ] Deploy API:
bash cd api npm run build wrangler deploy --env production -
[ ] Verify deployment:
bash curl https://api.epgoat.tv/health # Expected: {"status": "healthy", "timestamp": "2025-10-30T12:00:00Z"}
API Testing:
-
[ ] Test health endpoint:
bash curl https://api.epgoat.tv/health -
[ ] Test authentication (require JWT):
bash curl https://api.epgoat.tv/v1/subscriptions/current \ -H "Authorization: Bearer <invalid_token>" # Expected: 401 Unauthorized -
[ ] Test rate limiting:
bash # Send 61 requests in 1 minute for i in {1..61}; do curl https://api.epgoat.tv/v1/subscriptions/current \ -H "Authorization: Bearer <token>" done # Expected: 429 Too Many Requests on 61st request -
[ ] Test CORS:
bash curl -X OPTIONS https://api.epgoat.tv/v1/subscriptions/current \ -H "Origin: https://app.epgoat.tv" \ -H "Access-Control-Request-Method: GET" # Expected: CORS headers present -
[ ] Test EPG access:
bash curl https://epgo.at/<test_key>/tps.xml # Expected: XMLTV file content -
[ ] Test EPG rate limiting (1 req/min per key):
bash curl https://epgo.at/<test_key>/tps.xml # Request 1: 200 OK curl https://epgo.at/<test_key>/tps.xml # Request 2 (immediate): 429 Too Many Requests
Error Handling:
-
[ ] Test 404 (not found):
bash curl https://api.epgoat.tv/v1/nonexistent # Expected: {"success": false, "error": {"code": "NOT_FOUND", ...}} -
[ ] Test 500 (server error):
- Trigger intentional error in code
- Verify error response format
- Verify error logged to Cloudflare
Performance Testing:
- [ ] Load test API endpoints:
bash # Install k6: https://k6.io/ k6 run load-test.js
```javascript // load-test.js import http from 'k6/http'; import { check } from 'k6';
export const options = { vus: 100, // 100 virtual users duration: '60s', // Run for 60 seconds };
export default function () { const res = http.get('https://api.epgoat.tv/health');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
} ```
- [ ] Verify p95 latency <200ms
- [ ] Verify p99 latency <500ms
- [ ] Verify error rate <1%
Frontend Deployment
✅ Pages Deployment
Marketing Website (epgoat.tv):
-
[ ] Build production assets:
bash cd frontend/marketing npm run build -
[ ] Deploy to Cloudflare Pages:
bash wrangler pages deploy dist --project-name=epgoat-marketing -
[ ] Verify deployment: https://epgoat.tv
- [ ] Test all pages:
- [ ] Home page
- [ ] Features page
- [ ] Pricing page
- [ ] FAQ page
- [ ] Contact page
- [ ] Terms of Service
-
[ ] Privacy Policy
-
[ ] Test forms:
- [ ] Contact form submission
- [ ] Newsletter signup
-
[ ] Email validation
-
[ ] Test responsiveness:
- [ ] Mobile (375px)
- [ ] Tablet (768px)
- [ ] Desktop (1920px)
Consumer Portal (app.epgoat.tv):
-
[ ] Set environment variables in Cloudflare dashboard:
VITE_AUTH0_DOMAIN=epgoat.us.auth0.com VITE_AUTH0_CLIENT_ID=<production_client_id> VITE_AUTH0_AUDIENCE=https://api.epgoat.tv VITE_STRIPE_PUBLISHABLE_KEY=pk_live_... VITE_API_BASE_URL=https://api.epgoat.tv -
[ ] Build and deploy:
bash cd frontend/consumer npm run build wrangler pages deploy dist --project-name=epgoat-app -
[ ] Test authentication:
- [ ] Sign up with Google
- [ ] Sign up with email/password
- [ ] Login with Google
- [ ] Login with email/password
- [ ] Logout
-
[ ] Password reset
-
[ ] Test subscription flow:
- [ ] Start free trial (no CC)
- [ ] Start enhanced trial (with CC)
- [ ] Upgrade to paid plan
- [ ] Cancel subscription
-
[ ] Reactivate subscription
-
[ ] Test key management:
- [ ] View access keys
- [ ] Copy key URL
- [ ] Test EPG access
-
[ ] View usage statistics
-
[ ] Test billing:
- [ ] View invoices
- [ ] Download invoice PDF
- [ ] Update payment method
- [ ] View next billing date
Admin Dashboard (admin.epgoat.tv):
-
[ ] Build and deploy:
bash cd frontend/admin npm run build wrangler pages deploy dist --project-name=epgoat-admin -
[ ] Test admin-only access:
- [ ] Login as consumer: Access denied
-
[ ] Login as admin: Access granted
-
[ ] Test provider management:
- [ ] View providers
- [ ] Edit provider M3U URL
- [ ] Enable/disable LLM fallback
-
[ ] Trigger manual EPG generation
-
[ ] Test user management:
- [ ] View all users
- [ ] Search users
- [ ] View user details
- [ ] Suspend user account
-
[ ] Reactivate user account
-
[ ] Test analytics:
- [ ] View match rate trends
- [ ] View LLM cost tracking
- [ ] View user growth chart
- [ ] Export analytics CSV
Performance Testing:
- [ ] Lighthouse scores (all sites):
- Performance: >90
- Accessibility: >95
- Best Practices: >95
-
SEO: >90
-
[ ] WebPageTest scores (epgoat.tv):
- First Contentful Paint: <1.5s
- Time to Interactive: <3.0s
- Total Blocking Time: <200ms
Automation & CI/CD
✅ GitHub Actions Setup
EPG Generation Workflow:
- [ ] Verify workflow file:
.github/workflows/epg-generation.yml -
[ ] Add GitHub secrets:
THESPORTSDB_API_KEY=<api_key> ANTHROPIC_API_KEY=<api_key> CLOUDFLARE_API_TOKEN=<token> CLOUDFLARE_ACCOUNT_ID=<account_id> D1_DATABASE_ID=<production_db_id> R2_BUCKET_NAME=epgoat-production -
[ ] Test workflow manually:
- Go to GitHub Actions tab
- Select "EPG Generation" workflow
- Click "Run workflow"
- Select branch: main
-
Monitor execution
-
[ ] Verify cron schedule (4x daily): ```yaml schedule:
- cron: '0 5 * * *' # 12:00 AM ET
- cron: '0 11 * * *' # 6:00 AM ET
- cron: '0 17 * * *' # 12:00 PM ET
- cron: '0 23 * * *' # 6:00 PM ET ```
-
[ ] Verify workflow completes in <15 minutes
- [ ] Verify EPG files uploaded to R2
- [ ] Verify metrics logged to D1
Deployment Workflows:
-
[ ] API deployment:
yaml # .github/workflows/deploy-api.yml on: push: branches: [main] paths: ['api/**'] -
[ ] Frontend deployment (auto via Cloudflare Pages Git integration):
- Push to main → auto-deploy
- PR opened → preview deployment
Test Workflow:
-
[ ] Verify test workflow runs on PR:
yaml # .github/workflows/test.yml on: pull_request: branches: [main] -
[ ] Verify required checks:
- [ ] Python tests pass
- [ ] Frontend tests pass
- [ ] Linting passes
- [ ] Type checking passes
Monitoring & Alerts
✅ Cloudflare Analytics
Setup:
- [ ] Enable Analytics in Cloudflare dashboard
- [ ] Enable Web Analytics for all Pages projects
- [ ] Enable Workers Analytics for API
Dashboards:
- [ ] Create custom dashboard for:
- API request volume (requests/min)
- API error rate (4xx, 5xx)
- API latency (p50, p95, p99)
- EPG downloads (requests/min)
- Supabase database size (MB)
- R2 storage size (GB)
- Worker CPU time (ms)
Alerts:
- [ ] Set up email alerts (admin@epgoat.tv):
- API error rate >5%: Critical
- API latency p95 >500ms: Warning
- D1 storage >4GB: Warning
- Worker error rate >1%: Critical
- EPG generation failure: Critical
✅ Application Monitoring
Custom Metrics (logged to D1):
- [ ] Daily metrics tracking (daily_metrics table):
- Total users
- Active subscriptions
- Revenue collected
- EPG requests
- Match rate
-
LLM cost
-
[ ] Set up daily metrics aggregation job: ```yaml # .github/workflows/daily-metrics.yml schedule:
- cron: '0 6 * * *' # 1:00 AM ET daily ```
Error Tracking:
-
[ ] Set up error logging in Workers:
typescript try { // API logic } catch (error) { console.error('API Error:', error); await logError(db, { message: error.message, stack: error.stack, endpoint: request.url, timestamp: new Date().toISOString(), }); throw error; } -
[ ] Create error dashboard in admin interface
- [ ] Set up weekly error report email
Uptime Monitoring:
- [ ] Set up external uptime monitoring (UptimeRobot, free tier):
- Monitor: https://api.epgoat.tv/health (every 5 min)
- Monitor: https://epgoat.tv (every 5 min)
- Monitor: https://app.epgoat.tv (every 5 min)
- Alert email: admin@epgoat.tv
- Alert when down for >2 consecutive checks
Legal & Compliance
✅ Legal Pages
Terms of Service:
- [ ] Draft Terms of Service (template: https://termly.io/)
- [ ] Include sections:
- Service description
- User responsibilities
- Payment terms
- Refund policy (7-day money back guarantee)
- Service availability (99.9% uptime target)
- Data usage and privacy
- Prohibited uses
- Termination clause
- Limitation of liability
-
Governing law (Delaware)
-
[ ] Review by legal counsel
- [ ] Publish at: https://epgoat.tv/terms
- [ ] Link from footer and signup flow
Privacy Policy:
- [ ] Draft Privacy Policy (GDPR + CCPA compliant)
- [ ] Include sections:
- Data collected (email, payment info, usage data)
- How data is used
- Data sharing (Auth0, Stripe, Cloudflare)
- Data retention (90 days for logs)
- User rights (access, deletion, portability)
- Cookies policy
-
Contact information (privacy@epgoat.tv)
-
[ ] Review by legal counsel
- [ ] Publish at: https://epgoat.tv/privacy
- [ ] Add cookie consent banner (if using analytics cookies)
Refund Policy:
- [ ] Draft refund policy:
- 7-day money-back guarantee (no questions asked)
- Pro-rated refunds after 7 days (annual plans)
- Trial cancellations: no charge
-
Refund processing: 5-10 business days
-
[ ] Publish at: https://epgoat.tv/refund-policy
- [ ] Link from pricing page
GDPR Compliance:
- [ ] Implement data export (user can download all their data):
- Subscription history
- Access keys
- Invoices
-
Usage logs
-
[ ] Implement data deletion (user can request account deletion):
- Soft delete user record (status='deleted')
- Anonymize access logs (remove email/PII)
-
Retain invoices for tax purposes (7 years)
-
[ ] Add "Privacy" section in consumer portal:
- Export my data
- Delete my account
- Manage email preferences
CCPA Compliance (California):
- [ ] Add "Do Not Sell My Personal Information" link (footer)
- [ ] Clarify: We do not sell personal information
- [ ] Provide contact: privacy@epgoat.tv
✅ Business Registration
- [ ] Register LLC (Delaware recommended for SaaS):
- Business name: EPGOAT, LLC
- Registered agent service
-
File formation documents
-
[ ] Obtain EIN (IRS):
- Apply at: https://www.irs.gov/
-
Use EIN for Stripe, bank account
-
[ ] Open business bank account:
- Chase, Mercury, or Brex recommended for startups
-
Link to Stripe for payouts
-
[ ] Set up business email (Google Workspace):
- admin@epgoat.tv
- support@epgoat.tv
- billing@epgoat.tv
- privacy@epgoat.tv
Go-Live
✅ Pre-Launch Checklist
Final Verification (24 hours before launch):
- [ ] All infrastructure deployed and verified
- [ ] All tests passing (Python, React, integration)
- [ ] No security vulnerabilities (run
npm audit,pip-audit) - [ ] Lighthouse scores >90 on all sites
- [ ] API response times <200ms (p95)
- [ ] Match rate ≥90% on all providers
- [ ] Payment processing tested end-to-end
- [ ] Email templates tested
- [ ] Terms, Privacy, Refund policies published
- [ ] Support email active (support@epgoat.tv)
- [ ] Monitoring and alerts configured
- [ ] Backup and recovery tested
- [ ] Team notified of launch time
Launch Day Tasks:
T-1 hour: - [ ] Final smoke tests on production - [ ] Verify GitHub Actions cron jobs scheduled - [ ] Enable Google Analytics (if using) - [ ] Announce in team Slack: "Going live in 1 hour"
T-0 (Launch): - [ ] Change Stripe to live mode (if still in test mode) - [ ] Enable Auth0 signups (remove invite-only restriction) - [ ] Publish launch announcement: - Tweet from company account - Post in relevant communities (Reddit, Hacker News) - Email friends & family invite list
T+1 hour: - [ ] Monitor API logs for errors - [ ] Monitor Stripe dashboard for signups - [ ] Respond to support emails - [ ] Monitor match rate (ensure ≥90%)
T+24 hours: - [ ] Review first-day metrics: - Total signups - Trial conversions - Match rate - API error rate - Support tickets - [ ] Fix any critical issues - [ ] Send "thank you" email to early users
✅ Soft Launch (Week 1)
Goal: Test with 20 friends & family users
- [ ] Send invite codes to friends & family
- [ ] Monitor usage and gather feedback
- [ ] Fix any critical bugs
- [ ] Optimize match rate based on real-world data
- [ ] Test support workflow (response time <24 hours)
Success Criteria: - [ ] 0 critical bugs - [ ] Match rate ≥90% - [ ] All users successfully signed up and accessed EPG - [ ] Positive feedback (8/10+ satisfaction)
✅ Beta Launch (Week 2-4)
Goal: Scale to 100 users via limited invites
- [ ] Open limited invite signups (landing page)
- [ ] Promote on Twitter, Reddit, niche forums
- [ ] Offer extended trial for beta users (60 days free)
- [ ] Gather feature requests and feedback
- [ ] Monitor LLM costs (should be <$50/month)
Success Criteria: - [ ] 100 active users - [ ] <5 support tickets/week - [ ] Match rate ≥92% - [ ] API uptime ≥99.5% - [ ] LLM costs within budget
✅ Public Launch (Week 5+)
Goal: Open registration to public
- [ ] Remove invite-only restriction
- [ ] Launch Product Hunt campaign
- [ ] Publish blog post: "Introducing EPGOAT"
- [ ] Email beta users: "We're now public!"
- [ ] Monitor growth and scale infrastructure as needed
Post-Launch
✅ Week 1 Post-Launch
- [ ] Daily check-ins on metrics dashboard
- [ ] Respond to all support tickets within 24 hours
- [ ] Fix any bugs reported by users
- [ ] Monitor Stripe dashboard for chargebacks (target: 0%)
- [ ] Publish weekly update (metrics, learnings)
✅ Month 1 Post-Launch
- [ ] Gather user feedback (send survey)
- [ ] Analyze match rate trends
- [ ] Optimize LLM costs (review learned patterns)
- [ ] Plan feature roadmap based on feedback
- [ ] Publish monthly transparency report:
- Total users
- Revenue
- Match rate
- LLM costs
- Top feature requests
✅ Ongoing Maintenance
Weekly: - [ ] Review match rate (ensure ≥90%) - [ ] Review LLM costs (ensure within budget) - [ ] Review support tickets (close resolved) - [ ] Update event database (refresh from API)
Monthly: - [ ] Review Stripe dashboard (revenue, chargebacks) - [ ] Review Cloudflare analytics (traffic, errors) - [ ] Review D1 storage (ensure <80% full) - [ ] Publish transparency report - [ ] Deploy new features
Quarterly: - [ ] Security audit (dependencies, vulnerabilities) - [ ] Legal review (Terms, Privacy updates if needed) - [ ] Infrastructure review (scale if needed) - [ ] Roadmap planning (next quarter features)
Success Metrics
Launch Targets (Month 1):
| Metric | Target | Actual |
|---|---|---|
| Total signups | 100 | ___ |
| Active subscriptions | 50 | ___ |
| Revenue | $400 | ___ |
| Match rate | ≥90% | ___ |
| API uptime | ≥99.5% | ___ |
| Support response time | <24h | ___ |
| Chargeback rate | <1% | ___ |
Year 1 Targets:
| Metric | Target |
|---|---|
| Total users | 620 |
| Active subscriptions | 500 |
| Annual revenue | $4,000 |
| Match rate | ≥96% |
| API uptime | ≥99.9% |
| Customer satisfaction | ≥8/10 |
Emergency Contacts
Infrastructure Issues: - Cloudflare Support: https://dash.cloudflare.com/?to=/:account/support - Response time: <4 hours (paid plan), <24 hours (free plan)
Payment Issues: - Stripe Support: https://support.stripe.com/ - Response time: <4 hours (24/7)
Security Issues: - Auth0 Support: https://support.auth0.com/ - Response time: <8 hours
Team Contacts: - Technical Lead: tech@epgoat.tv - Billing/Support: billing@epgoat.tv - Legal: legal@epgoat.tv - Emergency hotline: (555) 123-4567
Rollback Procedure
If critical issue discovered post-launch:
- Assess severity:
- Critical (security, payments): Immediate rollback
- Major (features broken): Rollback within 1 hour
-
Minor (cosmetic): Fix forward, no rollback
-
Rollback steps:
API rollback:
bash
# Revert to previous deployment
wrangler rollback --env production
Frontend rollback:
bash
# Cloudflare Pages dashboard → Deployments → Rollback to previous
Database rollback:
bash
# Restore from latest backup
supabase backup restore epgoat-production --backup-id=<last_known_good>
- Communication:
- Post incident banner on website
- Email affected users (if applicable)
-
Post status update on Twitter
-
Post-mortem:
- Write incident report (what happened, why, how to prevent)
- Share with team
- Implement preventive measures
Launch Checklist Complete! 🚀
All items above must be checked off before production launch. This checklist ensures a smooth, secure, and successful deployment of the EPGOAT platform.
Questions or issues during deployment?
- Slack: #epgoat-launch
- Email: tech@epgoat.tv
Good luck with the launch!
Last Updated: 2025-10-30 Next Review: Launch Day - 1 week