Skip to content

wpmoo-org/core

Repository files navigation

wpmoo core

wpmoo core is a domain-free, single-tenant SaaS skeleton. It provides the boring foundation a product usually needs before domain logic exists: authentication, guarded settings, an empty admin dashboard shell, email, S3-compatible storage, one-time Stripe payments, pg-boss jobs, i18n, GDPR-oriented privacy controls, tests, CI, and deployment notes.

This repository is intentionally not an event, project, mentor, jury, PDF, subscription, or multi-tenant app.

What Is Included

  • apps/playground: Next.js playground app with public pages, auth pages, guarded dashboard/settings, i18n, payment/privacy API routes, and a necessary-cookie banner.
  • apps/worker: long-running pg-boss worker for welcome emails and data export emails.
  • packages/db: Drizzle schema and database ownership for auth, RBAC, files, payments, and supporting tables.
  • packages/auth: Better Auth wrapper for email/password, magic link, and two-factor authentication.
  • packages/ui: Base UI-backed shared component foundation and empty admin shell.
  • packages/email: SMTP/Mailpit and Brevo email providers plus auth templates.
  • packages/storage: S3-compatible storage service with DB-backed ownership checks.
  • packages/payment: one-time Stripe Checkout and webhook handling; subscription mode is interface-only.
  • packages/i18n: EN/DE routing and locale config through next-intl.
  • packages/jobs: pg-boss service wrapper, registry, enqueue helpers, and core job payloads.
  • packages/privacy: redacted data export snapshots, account anonymization, and cookie-consent helpers.

Tenancy Boundary

This is a single-tenant skeleton. It does not include organizations, workspaces, tenant-scoped membership, tenant billing, or per-tenant RBAC.

If a downstream product needs multi-tenancy, add it deliberately in that product or in a future scoped package. Do not reuse the current generic RBAC tables as an implicit tenant model.

Auth.js To Better Auth Merge Note

The auth stack is Better Auth, not Auth.js/NextAuth. When merging this skeleton into an app that already uses Auth.js:

  • Treat packages/auth and packages/db/src/schema/user.ts as the target auth boundary.
  • Migrate session, account, verification, and two-factor data intentionally; do not assume Auth.js tables are drop-in compatible.
  • Do not run Better Auth CLI migrations. @wpmoo/db owns every table and Drizzle migrations are the single schema source.
  • Keep auth route handlers under /api/auth/*; i18n middleware excludes API routes, webhooks, and callbacks.

Demo Role Warning

The dashboard and RBAC schema are scaffold-only. No product roles, demo admin role, tenant role, or domain permission set should be treated as production-ready.

Before shipping a product, define the real role/permission model, seed it explicitly, and re-guard every sensitive server operation. Client-side navigation or hidden buttons are not security boundaries.

Local Development

Use Node 20 or newer and pnpm@10.34.1 through Corepack.

corepack enable
pnpm install --frozen-lockfile
cp .env.example .env
docker compose up -d postgres minio minio-init mailpit
pnpm db:push   # create/sync the dev database tables (confirm when prompted)
pnpm dev

Local dev and db:* scripts read environment from the repo-root .env via dotenv-cli, so the values you set there are what the app and Drizzle use. The RBAC seed script (pnpm db:seed:roles) also reads the repo-root .env. (CI and production inject env directly; build/start are not wrapped.)

To exercise RBAC locally, set WPMOO_ADMIN_EMAILS (or WPMOO_SETUP_TOKEN) in .env, register that email, verify it via Mailpit, then claim the first admin at /setup/admin.

Upgrading an existing install after the permission system was added: if you bootstrapped a first-admin before seedDemoRoles started seeding permissions and rolePermission rows, your admin has roles but no permissions and will be blocked by requirePermission guards. Run pnpm --filter @wpmoo/rbac seed:roles once to backfill the permission rows (idempotent; safe to re-run).

Useful local URLs:

  • Playground: http://localhost:3000
  • Mailpit: http://localhost:8025
  • MinIO console: http://localhost:9001

Database

All Drizzle tables live in packages/db. Better Auth uses that schema; it does not own migrations.

pnpm db:generate
pnpm db:migrate
pnpm db:studio

Run migration commands only when you intend to change or apply the Drizzle schema.

Quality Gates

pnpm lint
pnpm typecheck
pnpm test
pnpm test:e2e
pnpm build

CI runs install, lint, typecheck, unit tests, Playwright Chromium smoke tests, and build. The e2e smoke runs against a production-backed Next server and covers public rendering, auth-page rendering, localized privacy routing, cookie acknowledgement, and the absence of /datenschutz.

Deployment

Deployment notes live in docs/deploy:

The web app and worker are separate processes. Both need the same Postgres database because jobs use pg-boss in Postgres. Do not add Redis for the current job queue.

Production Checklist

  • Replace /privacy, /terms, and /imprint placeholder copy.
  • Set real auth, email, storage, Stripe, and job environment variables.
  • Run @wpmoo/db migrations against the production database.
  • Start the worker as a long-running process.
  • Configure the Stripe webhook at /api/payment/webhook.
  • Replace scaffold RBAC/demo assumptions with product-specific authorization.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages