BaselineNext New App Setup Guide

The BaselineNext repository is intended to be copied, renamed, and governed into a real SaaS product. This guide starts after you have duplicated the repository in GitHub and want to configure BaselineNext.

This baseline supports your hosting choice of Postgres database, Upstash for Redis/caching, Stripe for billing and Resend for outbound email. Other providers can be integrated but need to be added on top of this baseline repository.

The repository includes the implementation described here, Vitest unit tests with enforced coverage thresholds, integration tests, and end-to-end functional tests through Playwright. The governance framework allows you to extend this repository with the same rules that guided its creation and with deployment checks enforced through CI.

How to setup TL;DR

Create the infrastructure accounts, fill .env.local, apply the checked-in database migrations, create the first admin through /setup/first-admin, bootstrap scheduled jobs, prepare the optional E2E support tables, then let your development agent work inside the governance framework.

Full Guide

1. Create Your Repository Copy

  1. Duplicate the BaselineNext repository in GitHub.
  2. Rename the repository for your product.
  3. Clone your copy locally:
git clone git@github.com:<your-org>/<your-repo>.git
cd <your-repo>
  1. Open the folder in VS Code:
code .
  1. Install dependencies:
npm install

2. Provision Local Development Services

Create separate development resources before filling the environment file.

Postgres

Use any Postgres provider that gives you:

  • a runtime connection URL for the app pool
  • a direct or unpooled connection URL for Drizzle migrations and schema verification

Neon, Supabase, Railway, Render, RDS, and local Docker Postgres all work as long as both connection modes are available. Put the pooled URL in DATABASE_URL and the direct URL in DATABASE_URL_UNPOOLED.

Redis

Create an Upstash Redis database for shared runtime state. Local development can run without Upstash because the cache layer falls back to an in-memory implementation, but Redis is required for preview, staging, and production environments.

Use a unique APP_ID and, when you intentionally share Redis between multiple local/test processes, set REDIS_KEYSPACE.

Stripe

Create or reuse a Stripe test-mode account. You need:

  • STRIPE_SECRET_KEY
  • NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
  • STRIPE_WEBHOOK_SECRET from stripe listen or a configured webhook endpoint

Billing can stay disabled with BILLING_ENABLED=false while you are adapting the starter. Turn it on only after test-mode Stripe keys, products, prices, tax settings, and webhook handling are ready.

Email

Create a Resend API key for deployed environments. Local APP_ENV=dev can use the development email bypass, but preview, staging, and production should have RESEND_API_KEY, EMAIL_FROM, OPS_ALERT_EMAIL, and SUPPORT_EMAIL.

3. Fill .env.local

Copy the example file:

cp .env.example .env.local

Set at least these local values:

  • APP_ID: machine-safe namespace, for example myapp
  • NEXT_PUBLIC_APP_NAME: the display name shown in UI and email
  • DATABASE_URL: app runtime Postgres URL
  • DATABASE_URL_UNPOOLED: direct migration Postgres URL
  • AUTH_SECRET: cryptographically random secret generated with openssl rand -base64 32 or openssl rand -hex 32. Preview, staging, and production require hex, Base64, or Base64URL encoding of at least 32 bytes. Rotating this value invalidates existing sessions and authentication tokens; validate deployed values before rollout and do not rotate them automatically.
  • ADMIN_SECRET: long random secret for admin-only bearer endpoints
  • FIRST_ADMIN_SETUP_TOKEN: long random one-time setup secret for creating the first admin account
  • INTERNAL_CONTROL_SECRET: long random secret for local E2E/internal controls
  • DEV_PORT: local dev server port
  • APP_URL: usually http://localhost:<DEV_PORT>
  • NEXT_PUBLIC_SITE_URL: usually http://localhost:<DEV_PORT>

For local billing or E2E, also set:

  • TEST_SERVER_PORT: separate from the dev port so you can run a compiled local test server for Playwright and webhook tests
  • STRIPE_SECRET_KEY: Stripe test-mode secret key, beginning with sk_test_
  • STRIPE_WEBHOOK_SECRET: Stripe webhook signing secret, usually from stripe listen locally or the configured test webhook endpoint
  • NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: Stripe test-mode publishable key used by browser checkout flows
  • E2E_APP_ADMIN_LOGIN: app admin email/username used by Playwright admin flows
  • E2E_ADMIN_PASSWORD: app admin password used by Playwright admin flows

Keep NODE_ENV=development and APP_ENV=dev for normal local development.

4. Apply the Database Schema

The BaselineNext repository uses Drizzle migrations. The unpooled database user URL is used for schema work because migration tools should not run through a transaction pooler.

npm run db:generate:local
npm run db:migrate:local
npm run db:verify:local

This will create the empty baseline schema in the database as a starting point for your app.

For any further changes generation should not create surprising SQL. Migrate applies the checked-in migrations, and verify compares the live database to db/schema.ts.

The governance rules include instructions on how your agent evolves and changes the schema. Do not use drizzle-kit push, npm run db:push, or npm run db:push:force manually.

5. Start the App

Run the local development server:

npm run dev

Open:

http://localhost:<DEV_PORT>

The repo-local launcher reads .env.local, so you do not need to globally export database URLs.

6. Create the First Admin

Before staring, ensure you have set a FIRST_ADMIN_SETUP_TOKEN env variable / secret in your environment so that first time admin user setup can be authenticated.

  1. Visit /setup/first-admin.
  2. Enter FIRST_ADMIN_SETUP_TOKEN.
  3. Enter the email, display name, and password for the first admin account.
  4. Submit the form, then continue to /admin/login.

This setup page is available only while no admin account exists and FIRST_ADMIN_SETUP_TOKEN is configured. Once the first admin exists, the page returns 404.

If an account already exists with the submitted email and no admin exists yet, the setup flow promotes that account, updates its display name and password, and revokes any existing sessions.

Direct SQL promotion is an emergency local fallback only:

update accounts
set is_admin = true
where email = '<your-admin-email>';

Prefer the setup page for local, preview, and serverless deployments because it uses the same app-owned password hashing, lifecycle, and audit paths as the rest of the application.

7. Bootstrap Scheduled Jobs

After admin login:

  1. Open /admin/jobs/scheduled.
  2. Click Bootstrap.
  3. Confirm scheduled jobs are listed.

This creates the recurring job rows declared by the app. The operation is idempotent.

8. Prepare E2E Support Tables

The Playwright billing simulations use guarded E2E-only support tables for Stripe Test Clock customer overrides and runtime flags. Create them only in development or test-like databases:

npm run test:e2e:setup-stripe-test-clock-overrides

The setup script refuses to run when APP_ENV is staging or prod.

If you plan to run browser E2E tests locally, also install browser binaries if your machine does not already have them:

npx playwright install

10. Run Verification

Use the normal baseline checks before making the copy your working foundation:

npm run typecheck
npm run test:run
npm run test:integration
npm run lint
npm run validate:openapi
npm run db:verify:local

Playwright is available but intentionally not automatic. Run it when you are ready for full browser coverage. e.g.:

npm run test:e2e:playwright:smoke

For local Playwright against the compiled test server, build/start the test target according to the current E2E workflow, then run with PLAYWRIGHT_BASE_URL=http://localhost:<TEST_SERVER_PORT> when needed.

Review the e2e testing readme at e2e/README.md.

11. Connect Your Development Agent

Open the repository in VS Code and attach your coding agent to that workspace. Before asking the agent to change code, direct it to follow the repository governance:

Before planning, reviewing, or editing code, read governance/baseline.md and governance/project.md. Treat them as authoritative. Use the BaselineNext governed-slice workflow for implementation. Keep changes scoped. If an allowlist is supplied, do not edit outside it. Include the governance checklist before finishing.

When you ask for a feature, give the agent a controlled slice:

Implement <feature>. Allowed files: <list files or folders>. Preserve the route -> module -> db boundary. Add focused tests. Do not create architecture exceptions unless you report the required exception first.

The governance framework is the product discipline. It keeps route handlers at the transport boundary, business workflows in modules, persistence in the owning module, environment access behind helpers, Redis keys centralized, and tests matched to risk.

12. Start Product Adaptation

After the baseline is running:

  1. Update app branding through NEXT_PUBLIC_APP_NAME, public assets, and UI copy.
  2. Add project-specific rules to governance/project.md.
  3. Replace starter marketing content with your positioning.
  4. Define your first domain slice and implement it through the governed workflow.
  5. Keep reusable baseline rules in governance/baseline.md; keep product-specific rules in governance/project.md.

At this point the repository is ready for normal development and testing.