Founder SaaS MVP Template - Chronological Implementation TODO Plan (Template repo: ai-eng-template-founder-saas-mvp) ============================================================================== INTENT ============================================================================== This template repository is the studio's default starting point for a founder MVP: a small, opinionated, production-ready Next.js + Firebase web application with authentication, a multi-tenant data model, a dashboard, a billing surface, and an admin shell. The repo is meant to be forked once per customer and customized according to a per-customer customization handbook (Phase 11). It must also drop cleanly into the public `/showcase` module on the studio's marketing website (Phase 12) so that prospects can see the actual template that powers their MVP. OUT OF SCOPE: heavy enterprise features (SSO, SCIM provisioning, audit retention beyond 90 days), large analytics warehouses, complex B2B procurement flows, and anything the studio explicitly does not sell on its public site. High-level summary - Goal: a forkable, opinionated SaaS MVP starter that ships with auth, a small data model, a dashboard, and a Stripe-backed subscription paywall, ready to be customized per founder in 1-3 sprints. - Experience target: a clean, fast, mobile-first SaaS shell with a public marketing surface, an authenticated `/app` shell with sidebar navigation, and an `/admin` shell scoped to platform operators. - Platform target: Next.js App Router (Node runtime), Firebase Auth + Firestore + Cloud Functions + Cloud Storage + App Check, Stripe for billing, Tailwind + design tokens for styling. - Backend mechanics: Firestore is the system of record. Cloud Functions own every privileged mutation (workspace creation, subscription state, role grants). - Performance/security target: Core Web Vitals green, App Check enforced on all callables, Firestore Security Rules enforced, secrets only in Cloud Functions config or Secret Manager. - Rough delivery estimate: 4-10 weeks per customer customization, depending on the breadth of feature work beyond the template defaults. Phase 0 - Scope freeze, product definitions, and delivery guardrails (Effort: Medium) Dependencies: studio positioning, founder discovery workshop output. [ ] Freeze template scope: - [ ] confirm the template ships with: marketing landing, sign-up/sign-in, email verification, password reset, workspace creation, invite flow, role-based access (owner/admin/member), a "Hello, world" feature page, a settings area, a Stripe-backed subscription paywall, and an admin shell. - [ ] confirm explicit OUT-OF-SCOPE: SSO, SCIM, audit log dashboards beyond the last 90 days, complex billing models (metered, usage-based), and customer-facing analytics. - [ ] document the supported customization axes in `docs/customization.md` (brand, primary feature, additional roles, integrations, paywall strategy, regional preferences). [ ] Define delivery guardrails: - [ ] every feature has Firestore Security Rules and at least one Cloud Function test. - [ ] every form is keyboard-accessible and screen-reader-friendly. - [ ] every privileged mutation is App Check-gated. Potential gotchas: - [ ] founders frequently ask for "just one more screen" that bypasses the data model; treat any unscoped screen as a separate sprint. Phase 1 - Repository skeleton, tooling, and CI (Effort: Medium) Dependencies: scope freeze. [ ] Repository: - [ ] create `ai-eng-template-founder-saas-mvp` on GitHub (private by default). - [ ] license: dual-licensed - MIT for the template scaffolding, separate per-customer license for the customer fork. - [ ] root `README.md` with: "What this is", "What this is NOT", "How to fork", "How to customize", and a link to the relevant template plan. [ ] Tooling: - [ ] Node 20 LTS, pnpm 9, Next.js 15, TypeScript 5.x, ESLint, Prettier, Vitest, Playwright. - [ ] Tailwind CSS with a `design-tokens.css` file mirroring the studio token system. - [ ] Firebase CLI, Firebase emulators, `firebase.json` covering Auth, Firestore, Functions, Storage, and Hosting emulators. - [ ] `.env.example` documenting every required environment variable; never commit `.env`. [ ] CI (GitHub Actions): - [ ] `ci.yml` runs lint, typecheck, unit tests, Playwright smoke (1 happy path), and `firebase emulators:exec` for Functions tests. - [ ] `preview.yml` builds and deploys a Firebase Hosting preview channel on every PR. - [ ] `release.yml` deploys to staging on `main`, requires a manual approval step for production. Potential gotchas: - [ ] Firebase emulator data must NOT be committed; add `firebase/.emulator-data/**` to `.gitignore`. Phase 2 - Design system and token foundation (Effort: Small) Dependencies: Phase 1. [ ] Design tokens: - [ ] mirror the studio token vocabulary (`--color-bg`, `--color-surface`, `--color-text`, `--color-accent`, spacing scale, type scale). - [ ] expose tokens in `src/app/design-tokens.css` and via Tailwind theme extension. [ ] Component primitives in `src/components/ui/`: - [ ] Button, Input, Label, Textarea, Select, Checkbox, Radio, Switch. - [ ] Card, Surface, Stack, Cluster, Container. - [ ] Toast, Dialog, Drawer, Tooltip. - [ ] all primitives must be keyboard-accessible and have a Vitest test for ARIA wiring. Potential gotchas: - [ ] customers will request brand color overrides; expose every brand color as a CSS variable in a single file so a fork can rebrand with one edit. Phase 3 - Public marketing surface (Effort: Small) Dependencies: Phase 2. [ ] Public routes: - [ ] `/` landing page with hero, features grid, pricing teaser, FAQ, footer. - [ ] `/pricing`, `/features`, `/contact`, `/privacy`, `/terms`, `/imprint`. - [ ] `/changelog` (MDX-powered) and `/blog` (MDX-powered, optional). [ ] SEO and performance: - [ ] App Router metadata API for every public route. - [ ] OpenGraph image at `/og`. - [ ] `sitemap.ts` and `robots.ts` covering the public surface. - [ ] LCP target < 1.5s on a cold load over 4G. Potential gotchas: - [ ] customers replace marketing copy late; keep all marketing copy in a single `src/content/marketing.ts` so a copy edit is one file. Phase 4 - Authentication and authorization (Effort: Large) Dependencies: Phase 1. [ ] Firebase Auth: - [ ] enable email/password, Google, and Apple sign-in providers. - [ ] enforce email verification before workspace access. - [ ] password reset and email-change flows. [ ] Custom claims: - [ ] `role` claim per workspace (`owner` | `admin` | `member`). - [ ] `platformRole` claim for studio operator (`platformAdmin`). - [ ] custom-claim refresh after role changes through a Cloud Function. [ ] Workspace model: - [ ] `workspaces/{workspaceId}` document with `ownerUid`, `displayName`, `createdAt`, `plan`. - [ ] `workspaceMembers/{workspaceId}/members/{uid}` documents. - [ ] invite flow: `inviteMember` callable creates a one-time signed link, rate-limited per workspace. Potential gotchas: - [ ] never store a role on the user document alone; rely on custom claims plus a members subcollection or you will fight a stale-claim bug. Phase 5 - Data model and persistence (Effort: Large) Dependencies: Phase 4. [ ] Firestore collections (defaults; customers extend): - [ ] `workspaces/{workspaceId}`. - [ ] `workspaceMembers/{workspaceId}/members/{uid}`. - [ ] `items/{itemId}` (the placeholder "Hello, world" entity). - [ ] `subscriptions/{workspaceId}` (Stripe-backed). - [ ] `auditLogs/{logId}`. [ ] Indexes: - [ ] `firestore.indexes.json` covers every collection-scoped composite query the template uses; document each index inline. [ ] Security rules: - [ ] every collection has explicit rules. - [ ] tests in `firebase/tests/firestore.rules.spec.ts` cover happy path and at least three deny cases per collection. Potential gotchas: - [ ] Firestore charges per read; never paginate in a server component without a limit clause. Phase 6 - Authenticated `/app` shell (Effort: Large) Dependencies: Phases 4-5. [ ] Route group `(app)`: - [ ] `/app` dashboard with a "Welcome", quick-stats cards, and a list of the last 10 items. - [ ] `/app/items` list view with filtering, sorting, and pagination. - [ ] `/app/items/new`, `/app/items/[id]`, `/app/items/[id]/edit`. - [ ] `/app/settings/profile`, `/app/settings/workspace`, `/app/settings/members`, `/app/settings/billing`. [ ] Layout: - [ ] sidebar with the current workspace, item count badge, and a workspace switcher. - [ ] header with user menu, sign-out, and a "Help" link. - [ ] mobile drawer fallback. [ ] Server actions: - [ ] every mutation goes through a Cloud Function callable, NOT a client Firestore write. Potential gotchas: - [ ] guard every `/app/*` route at the layout level with a server-side session check; client-only guards leak content on first paint. Phase 7 - Stripe-backed billing (Effort: Large) Dependencies: Phase 6. [ ] Stripe setup: - [ ] document `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, and price IDs in `.env.example`. - [ ] use the official `stripe` Node SDK; never call Stripe from the browser. [ ] Cloud Functions: - [ ] `createCheckoutSession` callable (gated by App Check and workspace membership). - [ ] `createPortalSession` callable. - [ ] `stripeWebhook` HTTP function with signature verification and an idempotency key per Stripe event ID. [ ] Plans: - [ ] `free`, `pro` (default monthly), and `enterprise` (contact-sales) plans baked into a `plans.ts` file the customer can rewrite. - [ ] feature gating by plan via a `requirePlan` helper. Potential gotchas: - [ ] webhook handlers MUST be idempotent; Stripe will retry. Persist `eventId` in `stripeWebhookEvents/{eventId}` and short-circuit duplicates. Phase 8 - Admin shell (Effort: Medium) Dependencies: Phase 6. [ ] Route group `(admin)`: - [ ] `/admin` overview restricted to `platformAdmin` custom claim. - [ ] `/admin/workspaces`, `/admin/users`, `/admin/audit`, `/admin/feature-flags`. [ ] Cloud Functions: - [ ] `setPlatformAdmin` callable bootstrap (only first user can self-promote when no admin exists; afterwards requires an existing admin). Potential gotchas: - [ ] never expose `/admin` routes through the public sitemap; mark them as `robots: { index: false, follow: false }`. Phase 9 - Observability, security, accessibility (Effort: Medium) Dependencies: Phases 6-7. [ ] Observability: - [ ] Firebase Analytics, Performance Monitoring, Crashlytics (web) wired up. - [ ] Cloud Logging structured logs with a `requestId` per HTTP function call. [ ] Security: - [ ] App Check enforced on every callable and HTTP function. - [ ] Content-Security-Policy header configured for the Next.js app. - [ ] Strict-Transport-Security, X-Frame-Options, Referrer-Policy headers. [ ] Accessibility: - [ ] Lighthouse a11y score >= 95 on every public and authenticated route. - [ ] axe-core Playwright check on the top 5 routes. Potential gotchas: - [ ] adding `unsafe-inline` to CSP defeats the point; use nonces for any inline script. Phase 10 - Testing strategy (Effort: Medium) Dependencies: Phases 4-9. [ ] Unit tests (Vitest): - [ ] every utility, every Cloud Function handler, every Firestore rule case. [ ] Integration tests: - [ ] `firebase emulators:exec` driven test that boots Auth + Firestore + Functions and exercises the sign-up -> create-workspace -> create-item happy path. [ ] E2E tests (Playwright): - [ ] one happy-path smoke per release: sign in, see dashboard, create item, sign out. Potential gotchas: - [ ] Playwright against the live Firebase project is flaky; always run against emulators in CI. Phase 11 - Customization handbook (Effort: Small per customer) Dependencies: Phases 0-10. [ ] `docs/customization.md` is filled in during the discovery workshop and captures, for the current customer fork: - [ ] brand name, logo, primary/secondary colors, and typography. - [ ] domain name and DNS plan. - [ ] the customer's actual primary entity (replacing `items`). - [ ] role names if they differ from owner/admin/member. - [ ] which integrations are enabled (Stripe yes/no, email provider, analytics provider). - [ ] the paywall strategy (free trial length, plan names, grandfather rules). - [ ] regional/locale preferences (date format, currency, language packs). [ ] Each section in this document has a corresponding "rebrand checklist" in the template README, so the operator can verify nothing was missed before launch. Potential gotchas: - [ ] customers often ask for changes that conflict with the template's data model; document any deviation explicitly in `docs/deviations.md` so future template upgrades remain safe. Phase 12 - Public showcase integration (Effort: Small) Dependencies: this template plan, ecosystem Phase 26. [ ] Showcase metadata: - [ ] this template is registered in `apps/web/src/lib/showcase.ts` with id `founder-saas-mvp`, a hero, a feature list, a tech-stack list, a "what you get" list, and a CTA into the estimator. - [ ] the showcase entry links to a redacted, public README in the template repository. [ ] Live preview: - [ ] a public staging instance of the unmodified template is deployed under a stable Firebase Hosting URL (e.g. `showcase-saas.ai-engineering.dev`) and embedded as a sandboxed iframe on `/showcase/founder-saas-mvp`. - [ ] iframe sandbox: `allow-scripts allow-same-origin allow-forms`. - [ ] the embedded site shows a permanent "Template preview" banner. [ ] Source visibility: - [ ] the template repository's public README, an architecture diagram, and the customization handbook table of contents are surfaced on the detail page. - [ ] no secrets, no customer names, no production data ever appear in the showcase preview. Potential gotchas: - [ ] do NOT proxy the live preview through the marketing site origin; it must be a separate origin so a misconfigured preview cannot read marketing cookies.