# Database (MySQL 8.0 — migrated from PostgreSQL in Phase 7, see # docs/phase-7-summary.md; the production host only supports MySQL). DATABASE_HOST="localhost" DATABASE_PORT="3306" DATABASE_NAME="nextchair" DATABASE_USER="user" DATABASE_PASSWORD="password" # Optional: cap the connection pool (see src/lib/db/prisma.ts). Lower this # for a hosting provider with a small max-connections limit. DATABASE_CONNECTION_LIMIT="5" # Auth.js (NextAuth v5). Generate with: npx auth secret AUTH_SECRET="replace-me-with-a-32-byte-random-string" # Google OAuth — https://console.cloud.google.com/apis/credentials AUTH_GOOGLE_ID="" AUTH_GOOGLE_SECRET="" # Base URL of the app (used for callback URLs, email links, etc.) NEXT_PUBLIC_APP_URL="http://localhost:3000" # Media Manager (Phase 9) — max upload size in bytes. Defaults to # 5,000,000 (5MB) if unset. See src/lib/media/media-storage.ts. MEDIA_MAX_UPLOAD_BYTES="5000000" # Google Reviews (Phase 9) — from https://console.cloud.google.com/apis/credentials, # needs the Places API enabled. Leave unset to keep review sync disabled # (Home shows clearly-labelled demo reviews instead). See # src/services/reviews/review-sync.service.ts and /owner/settings/reviews. GOOGLE_PLACES_API_KEY="" # Email (Phase 7) — see src/services/notifications/providers. # "console" logs would-be emails to the server console instead of sending # (safe default — never send real email from an unconfigured environment). # "brevo" sends for real over SMTP via nodemailer (see brevo-email- # provider.ts — it's genuinely generic SMTP, not Brevo-API-specific, # despite the name). On a multi-business deployment these are normally # managed centrally by the Manager's Settings > Email page and pushed into # every business's .env automatically — you don't need to fill these in # by hand there. This single-business template still needs them set. EMAIL_PROVIDER="console" EMAIL_SMTP_HOST="smtp-relay.brevo.com" EMAIL_SMTP_PORT="587" EMAIL_SMTP_USERNAME="" EMAIL_SMTP_PASSWORD="" # "none" | "starttls" | "tls" — unset infers from port (465 = tls, else # starttls) for backward compatibility; set explicitly to represent "none". EMAIL_SMTP_ENCRYPTION="starttls" EMAIL_FROM_ADDRESS="" # EMAIL_FROM_NAME is optional and is only used when no business name can # be resolved. Normal business emails use the installed business name # automatically (see docs/phase-8-email-sender-summary.md) — you do not # need to set or keep this in sync with Business Settings. EMAIL_FROM_NAME="" # Optional — a distinct reply-to address, separate from the verified sender address. EMAIL_REPLY_TO="" # Web Push — generate with: npx web-push generate-vapid-keys # On a multi-business deployment these are normally managed centrally by # the Manager's Settings > Push Notifications page and pushed into every # business's .env automatically — you don't need to fill these in by hand # there. This single-business template still needs them set. The public # key reaches the browser via GET /api/push/vapid-public-key at runtime, # not a NEXT_PUBLIC_* build-time variable — see that route's own header # for why (every business shares one prebuilt image). # PUSH_PROVIDER="web-push" to actually send; defaults to "console" (logs only). PUSH_PROVIDER="console" VAPID_PUBLIC_KEY="" VAPID_PRIVATE_KEY="" VAPID_SUBJECT="mailto:owner@example.com" # Background notification processing (Phase 7) — shared secret an external # scheduler presents as `Authorization: Bearer ` to # /api/cron/process-notifications. Generate with: openssl rand -hex 32 CRON_SECRET="" # First-run installation wizard (Phase 8) — required before /install will # create the first business/administrator. Generate with: # openssl rand -hex 32 INSTALLATION_TOKEN="" # Super Administrator (Phase 9) — platform-level account with every Owner # permission, provisioned from these env vars rather than the installation # wizard (see scripts/ensure-super-admin.ts, run on every container start). # No password — signs in the same OTP way as everyone else, via a # one-time code emailed to SUPER_ADMIN_EMAIL. Has no StaffProfile by # design: never appears in Team, the customer-facing barber picker, or # staff totals, and can never receive an appointment. All three optional # — leave SUPER_ADMIN_EMAIL unset to skip provisioning one entirely. SUPER_ADMIN_EMAIL="" SUPER_ADMIN_FIRST_NAME="" SUPER_ADMIN_LAST_NAME="" # Staff Google Calendar sync (Phase 8) — separate OAuth client from # AUTH_GOOGLE_ID/SECRET above (different scopes; see # src/services/calendar/google-calendar.provider.ts). Leave unset to keep # calendar sync disabled — Settings shows a "not configured" state rather # than crashing. GOOGLE_CALENDAR_CLIENT_ID="" GOOGLE_CALENDAR_CLIENT_SECRET="" GOOGLE_CALENDAR_REDIRECT_URI="http://localhost:3000/api/staff/calendar/google/callback" # Encrypts stored refresh tokens at rest. Generate with: openssl rand -hex 32 CALENDAR_TOKEN_ENCRYPTION_KEY=""