A founder metrics dashboard for small SaaS teams: MRR, active customers, revenue churn, and ARPU computed live from the database, with a 12-month revenue chart, a sortable customer table, and a working add-customer flow.
Built on the Moonshift SaaS starter: Next.js (App Router), Drizzle ORM + libsql, Better Auth, Tailwind, and shadcn-style UI primitives.
bun install
bun run devThat is it. On the first request the app creates every table (auth + domain) and seeds 22 realistic demo customers plus a trailing 12 months of revenue. No migration step, no manual seeding.
To warm the database ahead of time (CI, demos):
bun run db:seed- Data layer:
lib/db/domain.tsdefines thecustomersandrevenue_monthstables.lib/db/bootstrap.tscreates tables idempotently and seeds when empty; every server query path awaits it. - Queries:
lib/pulseboard/queries.tsholds all reads. KPIs are aggregated in SQL, not in JS over fetched rows. - Charts: hand-rolled inline SVG in
components/pulseboard/revenue-chart.tsx. Zero chart dependencies, server-rendered, theme-aware via CSS tokens. - Mutations:
app/(dashboard)/customers/actions.tsis a server action with zod validation and per-field error reporting. - Seed data:
lib/db/seed-data.tsgenerates dates relative to now, so the dashboard always shows a current-looking trailing year. The newest revenue month reconciles exactly with the paying customers' MRR sum.
Copy .env.example to .env if you want to point at a hosted libsql/Turso database or set a real BETTER_AUTH_SECRET. The defaults run fully local against file:./app.db.
