|
|
||
|---|---|---|
| .github/workflows | ||
| .w4c | ||
| app | ||
| docker | ||
| prisma | ||
| public | ||
| server | ||
| shared | ||
| tests | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| eslint.config.mjs | ||
| nuxt.config.ts | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
SaaS / Web App — Nuxt 3 (templates2)
A ready-to-run multi-tenant app forked from templates2.Base.Nuxt: organizations, roles, a
dashboard, a subscription (mock billing) and server-enforced usage limits. Feature-parity with
templates2.Saas.Next.
Quickstart
npm ci
cp .env.example .env # SQLite + mock providers by default — no keys needed
npm run db:setup # prisma db push + seed (demo org "Acme Inc")
npm run dev # http://localhost:3000
Demo accounts (seeded, all members of "Acme Inc"): owner@example.com (owner),
admin@example.com (admin), member@example.com (member) — password password.
Flow
Sign up → create an organization (/onboarding) → /dashboard (members, plan, usage) →
/members (add members, change roles; seat limit enforced) → /billing (mock upgrade/downgrade,
invoices) → /reports (Pro-gated, enforced server-side with 402).
What this case adds over the base
- Data model —
Organization,Membership(owner/admin/member),OrgSubscription,Invoice. - Roles —
shared/org.tsis the pure authority (canManageMembers,canManageBilling,withinSeats,canUseFeature); every/api/orgs/[id]/*route callsgetMembershipfirst, so an organization's data never leaks to another tenant. - Subscription — plan selection with the mock provider (no keys) creates a subscription and an invoice; Stripe activates from env.
- Usage limits — the free plan allows 2 seats; a third member is rejected until the org upgrades.
Marketing site & artwork
The public pages are a bespoke design, not a generic starter: a hero with a real-DOM app preview
(app/components/AppPreview.vue), an asymmetric feature bento, a materials/engineering section, a
metrics band, testimonials, a team band and a dark CTA — on a small design system (--canvas,
--accent-ink, --warn-ink, .panel, .glass, .bg-grid, gradient text) defined in
app/assets/css/main.css, in both light and dark themes.
The imagery is a cohesive set of generated 3D renders and one editorial photo in public/art/
(hero, materials, security, integrations, mesh and CTA bands, team, OG), used across the marketing
pages and as the OG image. Prompts live in ../tools/art/saas.json; regenerate them with
node ../tools/generate-images.mjs ../tools/art/saas.json --out /tmp/saas-art (needs
OPENROUTER_API_KEY), then convert to WebP into public/art/.
Tests
- Unit:
tests/unit/org.test.ts— role ranks, permissions, seat caps, feature gates. - E2E smoke:
tests/e2e/smoke.mjs— sign-up → create org → member/seat rules → mock subscribe → feature unlock → tenant isolation (403 on a foreign org).
Quality
node templates2/qa.mjs Saas.Nuxt
See ../CONTRACT.md for the Definition of Done.