Set Up brad-headless
Prepare the sales platform's database, secrets, payments, mail, runtime, and office access.
brad-headless is a persistent Next.js application with a MySQL/MariaDB database. It is separate from brad-cms, which uses PostgreSQL. This guide assumes access to the authorized platform source and its deployment environment.
Install and configure
From the brad-headless project directory:
bun installCreate a protected .env using .env.example as the field reference. Replace every placeholder, including the example bootstrap login. The runtime and Prisma CLI use DATABASE_URL as the database connection source.
Required configuration by capability
| Variable | Purpose |
|---|---|
DATABASE_URL | MySQL/MariaDB connection URL, for example mysql://portal_user:URL_ENCODED_PASSWORD@db.example.com:3306/brad_headless |
NEXT_PUBLIC_APP_URL | Canonical public origin for portal links and callbacks |
SESSION_SECRET | Customer session protection; at least 32 characters |
OFFICE_SESSION_SECRET | Separate office session protection; set explicitly to a strong unique secret |
CHALLENGE_HMAC_SECRET | Required for signup challenge issuance and verification |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Browser-side Stripe key for checkout |
STRIPE_SECRET_KEY | Server-side Stripe key for the same payment environment |
STRIPE_WEBHOOK_SECRET | Verifies payment events at /api/webhooks/stripe |
LICENSE_SIGNING_PRIVATE_KEY | Ed25519 private key, base64-encoded PKCS8 DER, matching the public key baked into deployed CMS clients |
LICENSE_SIGNING_SECRET | HMAC secret for short-lived download URLs; separate from Ed25519 response signing |
TOTP_ENCRYPTION_KEY | Base64 value decoding to exactly 32 bytes, required for portal two-factor enrollment and access |
SENDGRID_API_KEY | Required to actually send portal transactional mail |
SENDGRID_WEBHOOK_VERIFICATION_KEY | Verifies SendGrid delivery-event signatures where configured |
CLOUD_SECRETS_KEY | Base64 value decoding to exactly 32 bytes, required for encrypted cloud credentials and secrets when operating BRAD Cloud |
Keep private values server-side. NEXT_PUBLIC_* values are intended to be visible to the browser. Protect the signing and encryption keys in backups, and avoid changing them casually.
A newly generated license signing key cannot verify against the public key already baked into deployed CMS releases. Existing installs require the matching issuer private key. Key rotation needs a coordinated CMS release; it is not an environment-only change.
Apply schema and start locally
bun run db:generate
bun run db:deploy
bun devDevelopment listens on port 3001. Use a separate development database and Stripe test environment. The scheduler is off by default in development; enable it intentionally only when testing scheduled behavior.
Use committed migrations for production. db:migrate is the development migration-authoring command; db:push is not the production deployment workflow.
Create the first office administrator
To promote an existing client from the project directory:
bun run scripts/create-admin.ts owner@example.comTo create a new administrator, the script also accepts a password and optional role:
bun run scripts/create-admin.ts <email> <password> superadminA command-line password can remain in shell history. Prefer promoting an existing account or use the supported bootstrap office login supplied through protected environment settings, then create a database-backed administrator in System → Admins.
BOOTSTRAP_ADMIN_EMAIL and BOOTSTRAP_ADMIN_PASSWORD provide a synthetic emergency superadmin outside the database. Remove them or rotate their password after establishing normal staff access.
Configure payments and mail
Configure Stripe to send the events handled by this application to /api/webhooks/stripe: payment_intent.succeeded, payment_intent.payment_failed, and charge.refunded. Use the endpoint's signing secret in this environment and test successful delivery.
A missing webhook secret causes payment webhook requests to return an unavailable response; payment settlement and downstream fulfillment cannot be assumed from the browser result alone.
Set sender identity in System → Settings and send a test email. Without a SendGrid API key, the portal records dry-run email previews rather than delivering mail. That is unsuitable for production registration or recovery.
Build and run production
bun build
bun startThe start script applies committed database migrations before launching Next.js. Set the production port explicitly in your service environment; the development command's port 3001 is not a production port guarantee.
Run behind HTTPS with a service manager and persistent access to the database and storage/downloads. This is not a static export: checkout, office access, licensing, and the in-process scheduler require a running server.
Complete catalog and infrastructure setup before opening checkout.