Phase 9 — Enterprise / White Label
Agency management, client impersonation, custom branding, and the franchise hierarchy — for businesses that manage multiple clients or operate multiple locations under one brand.
What It Does
Agencies (marketing agencies, consultants, MSPs) can add client tenants to their dashboard and manage them centrally. They can impersonate clients to configure their account, view their stats, and take actions — all without knowing the client's password. Custom branding allows tenants to replace KaiVox's logo and colors with their own. The franchise hierarchy supports parent/child tenant relationships.
Key Routes
| URL | Description |
|---|---|
GET /agency | Agency dashboard — multi-client overview |
POST /agency/invite | Invite a client by email |
DELETE /agency/invite/{id} | Cancel a pending invite |
DELETE /agency/clients/{id} | Remove an accepted client |
POST /agency/clients/{id}/impersonate | Start impersonating a client |
GET /agency/impersonate/exit | Exit impersonation, return to agency |
POST /agency/invites/{token}/accept | Client accepts invite |
POST /agency/invites/{token}/decline | Client declines invite |
POST /agency/leave/{agencyId} | Client leaves an agency |
GET /settings/branding | Custom branding editor |
POST /settings/branding | Save branding (logo, colors, tagline) |
DELETE /settings/branding/logo | Remove uploaded logo |
Key Files
| Type | Path |
|---|---|
| Service | app/Services/AgencyService.php — invite → accept → reject → leave flow |
| Controller | app/Http/Controllers/AgencyController.php |
| Controller | app/Http/Controllers/BrandingController.php |
| Model | app/Models/AgencyClient.php — pivot: agency_tenant_id, client_tenant_id, status |
| Table | agency_clients — status ENUM (pending/accepted/rejected), responded_at |
| Column | tenants.account_type — ENUM: business / agency / franchise_parent / franchise_child |
| Column | tenants.parent_tenant_id — FK for franchise hierarchy |
| Columns | tenants.brand_logo, brand_color, brand_tagline |
| View | resources/views/agency/ |
| View | resources/views/settings/branding.blade.php |
Tenant Account Types
| Type | Description | isAgency() |
|---|---|---|
business | Standard tenant — default for all registrations | false |
agency | Can manage multiple client tenants, has agency dashboard | true |
franchise_parent | Parent brand that controls child locations | false |
franchise_child | Branch location under a franchise parent | false |
Super Admin sets the account type per tenant at Super Admin → Tenants → [Tenant] → Account Type.
Client Impersonation Flow
Agency clicks "Manage →" on a client in the agency dashboard
↓
AgencyController::impersonate() — verifies AgencyClient lookup (accepted only)
↓
Session stores: original_tenant_id, impersonating_tenant_id
↓
Auth context switches to client tenant
↓
Orange banner shown: "Managing [Client Name] on behalf of [Agency Name]"
↓
All dashboard actions now scoped to client tenant
↓
Agency clicks "Exit to My Agency"
↓
Session restored to agency tenant, redirect to /agency
What's Complete
- Agency dashboard with multi-client overview (calls/bookings/wallet per client)
- Invite clients by email with notes (status = pending, NOT instant access)
- Client-side: pending invite banner on dashboard (Accept/Decline)
- Client-side: "Agencies I'm Part Of" card with Leave Agency button
- Agency: cancel outgoing pending invite
- Agency: remove accepted client at any time
- AgencyService: full invite → accept → reject → leave flow
- AgencyClient pivot model with status ENUM
- Client impersonation — agency manages client with orange banner + exit button
- Custom branding: logo upload, brand color picker, tagline, live preview
- Franchise hierarchy DB (account_type + parent_tenant_id FK)
- Tenant model helpers: isAgency(), isFranchiseParent(), isFranchiseChild()
- Super Admin: set account type per tenant
What's Deferred
- Agency Client Detail Page (per-client drill-down with full stats + quick actions)
- Bulk Client Actions (bulk message, bulk export, bulk suspend)
- Full White Label Mode (hide "KaiVox" name, show agency brand everywhere)
- Custom Domain Routing (agency.com → KaiVox via CNAME + middleware)
- Reseller Pricing Control (agency markup over KaiVox base rate)
- Client Billing Passthrough (agency tops up client wallet from agency wallet)
- Agency Invoice Generator (PDF invoices per client with agency branding)
- Franchise Parent Dashboard (all child locations in one view)
- Franchise Child Restrictions (parent locks settings for children)
- Cross-Location Reporting
- Role-Based Access for Agency Staff
- Client Health Score
- Agency Activity Feed