Add Battl Builders Beta — Go-Live & Invite Playbook
@@ -0,0 +1,165 @@
|
|||||||
|
# 🚀 Battl Builders Beta — Go-Live & Invite Playbook
|
||||||
|
|
||||||
|
This document describes how the Battl Builders beta signup system works in **capture-only mode**, and exactly what needs to be flipped when we are ready to invite users.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Current State — Capture-Only Mode
|
||||||
|
|
||||||
|
**Goal:**
|
||||||
|
Collect beta signups publicly without sending emails or granting access.
|
||||||
|
|
||||||
|
### What happens on signup
|
||||||
|
- A user record is created (or updated) in `users`
|
||||||
|
- User is stored as:
|
||||||
|
- `role = BETA`
|
||||||
|
- `is_active = false`
|
||||||
|
- No auth tokens are created
|
||||||
|
- No emails are sent
|
||||||
|
|
||||||
|
This allows us to:
|
||||||
|
- Share the signup link publicly
|
||||||
|
- Collect interest safely
|
||||||
|
- Avoid accidental early access
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Environment Variables (Docker)
|
||||||
|
|
||||||
|
### Capture-only flag
|
||||||
|
Controls whether beta signup only stores users or also generates tokens and emails.
|
||||||
|
|
||||||
|
APP_BETA_CAPTUREONLY=true
|
||||||
|
|
||||||
|
### Email kill-switch (recommended)
|
||||||
|
Global safeguard to disable outbound email.
|
||||||
|
|
||||||
|
APP_EMAIL_OUTBOUND_ENABLED=false
|
||||||
|
|
||||||
|
Even if APP_BETA_CAPTUREONLY is false, this flag will still prevent emails.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Docker Compose Example
|
||||||
|
|
||||||
|
services:
|
||||||
|
battl-builder-api:
|
||||||
|
image: battl-builder-api:latest
|
||||||
|
environment:
|
||||||
|
- SPRING_PROFILES_ACTIVE=prod
|
||||||
|
- APP_BETA_CAPTUREONLY=true
|
||||||
|
- APP_EMAIL_OUTBOUND_ENABLED=false
|
||||||
|
- APP_PUBLICBASEURL=https://battl.builders
|
||||||
|
|
||||||
|
Restart containers after changing environment variables.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Cloudflare DNS Notes
|
||||||
|
|
||||||
|
Cloudflare is used for DNS only.
|
||||||
|
|
||||||
|
Ensure:
|
||||||
|
- battl.builders → frontend (Next.js)
|
||||||
|
- api.battl.builders → Spring API (or same domain if proxied)
|
||||||
|
|
||||||
|
The public base URL must match the frontend domain:
|
||||||
|
|
||||||
|
APP_PUBLICBASEURL=https://battl.builders
|
||||||
|
|
||||||
|
This value is used when generating magic login links.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Go-Live Checklist (Invite Day)
|
||||||
|
|
||||||
|
### Step 1 — Disable capture-only mode
|
||||||
|
Allows token creation and email sending.
|
||||||
|
|
||||||
|
APP_BETA_CAPTUREONLY=false
|
||||||
|
|
||||||
|
### Step 2 — Enable outbound email
|
||||||
|
|
||||||
|
APP_EMAIL_OUTBOUND_ENABLED=true
|
||||||
|
|
||||||
|
Restart the API container after changing environment variables.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Inviting Existing Beta Users (CLI)
|
||||||
|
|
||||||
|
Eligible beta users:
|
||||||
|
- role = BETA
|
||||||
|
- is_active = false
|
||||||
|
|
||||||
|
### Dry Run (recommended)
|
||||||
|
Creates tokens and logs output but does not send emails.
|
||||||
|
|
||||||
|
./mvnw spring-boot:run -Dspring-boot.run.arguments="--app.beta.invite.run=true --app.beta.invite.dryRun=true --app.beta.invite.limit=25 --app.beta.invite.tokenMinutes=60"
|
||||||
|
|
||||||
|
### Send Real Invites
|
||||||
|
|
||||||
|
./mvnw spring-boot:run -Dspring-boot.run.arguments="--app.beta.invite.run=true --app.beta.invite.dryRun=false --app.beta.invite.limit=0 --app.beta.invite.tokenMinutes=60"
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- limit=0 invites all eligible beta users
|
||||||
|
- tokenMinutes controls magic link expiration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. What Happens After Invite
|
||||||
|
|
||||||
|
When a user clicks their magic link:
|
||||||
|
- Token is validated and consumed
|
||||||
|
- User is promoted from BETA to USER
|
||||||
|
- User becomes active
|
||||||
|
- JWT is issued
|
||||||
|
- User is logged in immediately
|
||||||
|
- last_login_at and login_count are updated
|
||||||
|
|
||||||
|
No manual cleanup required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Post-Invite Operating Modes
|
||||||
|
|
||||||
|
### Option A — Manual invite waves (recommended)
|
||||||
|
Continue collecting beta signups without auto-emailing.
|
||||||
|
|
||||||
|
APP_BETA_CAPTUREONLY=true
|
||||||
|
APP_EMAIL_OUTBOUND_ENABLED=true
|
||||||
|
|
||||||
|
### Option B — Continuous auto-invites
|
||||||
|
Every new signup receives a magic link immediately.
|
||||||
|
|
||||||
|
APP_BETA_CAPTUREONLY=false
|
||||||
|
APP_EMAIL_OUTBOUND_ENABLED=true
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Useful Admin Queries
|
||||||
|
|
||||||
|
View waiting beta users:
|
||||||
|
|
||||||
|
select id, email, created_at
|
||||||
|
from users
|
||||||
|
where role = 'BETA'
|
||||||
|
and is_active = false
|
||||||
|
order by created_at asc;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Summary
|
||||||
|
|
||||||
|
Capture-Only Mode:
|
||||||
|
- Public signup enabled
|
||||||
|
- Users stored as inactive BETA
|
||||||
|
- No emails
|
||||||
|
- No tokens
|
||||||
|
|
||||||
|
Invite Mode:
|
||||||
|
- Flip 2 environment variables
|
||||||
|
- Run 1 CLI command
|
||||||
|
- Users self-promote on first login
|
||||||
|
|
||||||
|
This setup is intentional, safe, and production-ready.
|
||||||
Reference in New Issue
Block a user