Provisioning a New Instance
The runbook for bootstrapping a fresh FlexPoint Portal instance with the flexpoint:provision command.
A fresh FlexPoint Portal instance (Forge staging / candidate / production) is bootstrapped with a single command:
php artisan flexpoint:provision --with-admin --forceThis seeds the foundational relational data and dispatches the MeridianLink (MLM) identity imports onto their priority queues.
It does not run migrations
Provisioning intentionally does not run migrations — the deploy
hook owns php artisan migrate --force. Provisioning guarantees the
dependency-ordered seed data is in place before any MLM import can
reference it.
What it does, in order
App\Console\Commands\ProvisionInstanceCommand
- Permissions + system roles (+ role→permission pivots) — seeded
synchronously via
IdentitySeeder. - Notification templates + workflows — seeded synchronously via
NotificationSeeder. - Bootstrap Super Admin (
ADMIN_EMAIL/test@example.com) — seeded synchronously viaAdminUserSeeder, only when--with-adminis passed. - Originating-company sync → dispatched to queue
mlm-companies. - Internal-user sync → dispatched to queue
identity.
Roles must be seeded synchronously first: both MLM user-sync jobs assign portal
roles by key lookup (Role::where('key', …)->value('id')), which silently no-ops
if the role rows do not yet exist. Seeding inline before dispatch removes that
race. The originating-company job then fans out staggered ImportExternalUsers
jobs (queue mlm-users) for every company it discovers.
Flags
| Flag | Effect |
|---|---|
--with-admin | Seed the bootstrap Super Admin account (ADMIN_EMAIL, default test@example.com). |
--skip-mlm | Seed identity + notifications only; do not dispatch MLM import jobs. |
--force | Run without the production confirmation prompt (required in CI / non-interactive deploys). |
All seeders are idempotent and faker-free, so the command is safe to re-run on every deploy.
Queues
| Sync | Queue |
|---|---|
| Originating-company sync | mlm-companies |
| Internal-user sync | identity |
| External-user imports (fanned out) | mlm-users |
A Horizon daemon drains these queues in priority order.
Forge setup
Deploy hook (Site → Deployments):
cd $FORGE_SITE_PATH/apps/flex-hub-api
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
php artisan migrate --force
php artisan config:cache && php artisan route:cache && php artisan event:cache
php artisan horizon:terminateForge daemon (Server → Daemons) — drains all priority queues:
php artisan horizonOne-time, on a brand-new instance (after the first deploy):
php artisan flexpoint:provision --with-adminFallback worker if Redis/Horizon is unavailable (database driver):
php artisan queue:work --queue=identity,mlm-companies,mlm-users,defaultNull driver
If the MLM identity driver is null (MERIDIANLINK_AUTH_DRIVER
unset), imports are still queued but pull no real data — useful for a dry run.
Loan Product Advisor (LPA)
How the portal runs Freddie Mac's Loan Product Advisor through MeridianLink's asynchronous SubmitToLpa flow, imports the findings, and serves the findings PDF.
Realtime (Laravel Reverb) Deployment
How to deploy and configure the Laravel Reverb WebSocket server on Forge and wire the Vercel-hosted Next.js frontend to it.