Last updated 2026-04-26

Launch checklist

A live tally of what's done, what's pending, and what needs you (the SaaS owner) to act. Designed to be read top-to-bottom; ship when everything's checked.

Status legend

  • ✅ done
  • ⚠️ partial / needs attention
  • ❌ not started / blocker

1. Billing + payments

  • ✅ Stripe Python lib installed (stripe>=10.0)
  • ✅ Stripe secret key + price ID + webhook secret stored in app_config (via /ops/integrations)
  • ✅ Stripe webhook endpoint registered for checkout.session.completed + customer.subscription.deleted
  • ✅ Stripe Customer Portal route at /admin/billing/portal (subscribers can manage card / cancel)
  • ⚠️ Stripe Customer Portal must be activated in Stripe Dashboard → Settings → Billing → Customer portal → Activate (one-time, before any subscriber tries to use the Manage button)
  • ⚠️ Currently in test mode (sk_test_…). Switch to live mode before charging real money: replace all three Stripe values at /ops/integrations with their _live_ equivalents.
  • End-to-end test checkout — trigger one from /admin/billing with test card 4242 4242 4242 4242 to validate the round-trip + webhook signature. Verify company.stripe_subscription_id lands in DB after success.

2. Analytics

  • ✅ Google Analytics 4 wired (GA4_MEASUREMENT_ID in app_config, snippet renders on landing + every authed page)
  • ✅ First-party pageview tracking (/ops/analytics) — pageviews, sessions, top pages, referrers, UTM, signup funnel, MRR
  • ✅ Engagement beacon (time-on-page + scroll depth) — captured per pageview, surfaced on /ops/analytics top-pages table
  • ⚠️ Google Search Console site verified — need to wire the GSC API into /ops/analytics for organic-keyword data (next round; needs you to create a GCP service account JSON)
  • ❌ AI source detection — track when traffic comes from ChatGPT / Perplexity / Claude / Gemini

3. SEO + GEO

  • /sitemap.xml auto-generated (10 marketing pages + every help article + every blog post)
  • /robots.txt with explicit AI crawler Allow block (GPTBot, PerplexityBot, ClaudeBot, anthropic-ai, Google-Extended, CCBot)
  • /llms.txt for AI assistants (curated map per llmstxt.org)
  • ✅ Landing page: canonical, OpenGraph, Twitter Card, JSON-LD (Organization + WebSite + SoftwareApplication)
  • ✅ Pricing page: canonical, OG, Twitter, JSON-LD (Product + FAQPage)
  • ⚠️ /signup page: needs OG + JSON-LD treatment
  • ⚠️ Blog post template: needs BlogPosting JSON-LD per post
  • ❌ Per-page SEO audit panel on /ops/analytics (title length, meta-desc, H1 count, word count flags)
  • ❌ Real social card image — currently using /static/icon-192.png (square logo). Should be 1200×630 with branded layout for richer LinkedIn/Twitter previews. Manual creation needed.

4. Public pages

  • ✅ Landing (/)
  • ✅ Pricing (/pricing)
  • ✅ Signup (/signup)
  • ✅ Login (/login)
  • ✅ Privacy (/privacy)
  • ✅ Terms (/terms)
  • ✅ Trust & security (/trust)
  • ✅ Help (/help) + per-feature articles
  • ✅ Blog (/blog)
  • ✅ Roadmap (/roadmap)
  • ⚠️ Privacy + Terms need a real lawyer review before charging real customers — current versions are launch-grade boilerplate, not bulletproof

5. Authentication + access

  • ✅ Email + password signup with UTM attribution capture
  • ✅ Forgot password (/forgot-password)
  • ✅ Per-employee invite emails (with 7-day token)
  • ✅ 3 roles (employee / manager / admin) + 3 module flags (Finance / HR / Legal) — see Roles
  • /ops/* strictly limited to product owner (allowlist via OPS_ACCESS_EMAILS env)
  • ✅ Multi-tenant isolation: every query scopes by company_id; defense-in-depth on cross-tenant joins

6. Email

  • ✅ SMTP configured (IONOS) — invite emails, password reset, manual delivery, weekly digest, flag-change notifications all working
  • ⚠️ Reputation warm-up: send volume should ramp gradually for the first ~30 days post-launch to avoid spam folder. Avoid sending 100s on day 1 from a never-used domain.

7. Multi-tenant data

  • ✅ Per-tenant SQLite isolation enforced via WHERE clauses
  • ✅ M365 OAuth (per-employee, per-tenant)
  • ✅ QuickBooks Online (per-entity, per-tenant)
  • ✅ Multi-entity rollups (US / India / Switzerland / Ukraine, etc.) with FX rates
  • ✅ AR/AP dashboard (live + per-entity + consolidated)

8. Reliability + monitoring

  • ✅ systemd-managed gunicorn (/etc/systemd/system/timeopt.service)
  • ✅ Audit log (every important action recorded with actor + timestamp)
  • Error tracking — no Sentry / Rollbar / Honeybadger. Production 500s only show in journalctl. Wire one before launch so user-facing errors surface.
  • Backups — instance/timeopt.db is on a single VPS. No off-site backup. At minimum: nightly cron that gzips + uploads to S3 / R2 / IONOS object storage.
  • Uptime monitor — no external pingdom/UptimeRobot. Add one so you find out about downtime before customers.

9. Customer-facing UX

  • ✅ Onboarding flow (signup → first project → first time entry)
  • ✅ Per-role manual at /help/manual (auto-extends with module flags — manager-with-Finance-flag sees both manager + Finance docs)
  • ✅ Help docs comprehensive: every shipped feature has a doc
  • ⚠️ Empty state polish: new tenants land in many pages with zero data. The empty states exist but vary in quality.
  • Onboarding checklist for new admin — first-login walkthrough ("invite your team, set hourly rates, install desktop client, …"). Drives activation.

10. Compliance + GDPR

  • ✅ IP hashing in pageview log
  • ✅ DSR / GDPR module in Legal (track + auto-set 30-day SLA on incoming requests)
  • Self-service GDPR data export/api/me/export for any logged-in user to dump their own data as JSON
  • Cookie banner — minimal cookie use today (session, theme), but EU visitors expect a banner. Required if you want to advertise to EU markets.

11. Content

  • ✅ At least one blog post live → check /blog
  • ⚠️ Pricing comparison content — landing + pricing make claims; pages contrasting OtiumWork vs Clockify / Toggl / Harvest would draw bottom-funnel SEO
  • ⚠️ Case study or screenshot gallery — "show, don't tell". Even one annotated screenshot reduces hesitation
  • ⚠️ Demo video — 60-second screen recording of the core loop (capture → review → bill). Closes deals.

12. Domain + infra

  • ✅ TLS (otiumwork.com)
  • ✅ Reasonable DNS (A record to IONOS VPS)
  • ⚠️ MX records pointing to IONOS for info@otiumwork.com
  • DKIM + SPF + DMARC — verify all three for outbound email (invite, reset, digest) so your messages don't land in spam

Quick "ready to launch" sanity test

  1. Open https://otiumwork.com in incognito → loads in <1s, no console errors
  2. Click Pricing → understand the price + click Start free trial
  3. Sign up with a fresh email → end up logged in within 30 seconds
  4. Add 1 employee → see invite email arrive
  5. As admin → /admin/billing → click Subscribe → complete Stripe Checkout (test card) → return to billing page → see Subscribed status
  6. Click Manage subscription → land in Stripe Customer Portal → cancel → return → see status change
  7. Check /ops/analytics 10 minutes later → see your visit in pageview count, your signup in funnel

If all 7 work end-to-end without you intervening, you're launch-ready.


Owner-only items (this doc surfaces them; you handle the actual setup)

  • Stripe live-mode keys
  • Sentry account + DSN
  • Backup destination (S3/R2 bucket + access key)
  • Uptime monitor account
  • DKIM/SPF/DMARC DNS records (via IONOS DNS panel)
  • Real lawyer review of Privacy + Terms
  • Demo video creation

See something wrong or outdated in this article? Report it →