Filament Panels
Three Filament panels are registered, each mapping to one user type and one URL prefix.
Registration
// bootstrap/providers.php
return [
App\Providers\Filament\AdminPanelProvider::class,
App\Providers\Filament\ClientPanelProvider::class,
App\Providers\Filament\PartnerPanelProvider::class,
];
Admin Panel (/admin)
// app/Providers/Filament/AdminPanelProvider.php
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->id('admin')
->path('admin')
->tenant(LawFirm::class, slugAttribute: 'slug')
->tenantMiddleware([ApplyTenantScopes::class], isPersistent: true)
->login()
->passwordReset()
->emailVerification()
->authGuard('web')
->discoverResources(in: app_path('Filament/Admin/Resources'))
->discoverPages(in: app_path('Filament/Admin/Pages'))
->discoverWidgets(in: app_path('Filament/Admin/Widgets'));
}
}
Who can access: Users with an active FirmUserProfile for the resolved firm.
Client Portal (/portal)
// app/Providers/Filament/ClientPanelProvider.php
->id('client')
->path('portal')
->authGuard('client')
// No tenant() — client portal scopes by CLIENT_USERS.user_id, not URL slug
->login()
->passwordReset()
->discoverResources(in: app_path('Filament/Client/Resources'))
Who can access: Users with an active ClientUser record.
Scoping: No firm slug in URL. All queries scoped by ClientUser → ClientContact → Client.law_firm_id.
Partner Portal (/partner)
// app/Providers/Filament/PartnerPanelProvider.php
->id('partner')
->path('partner')
->authGuard('partner')
->login()
->passwordReset()
->discoverResources(in: app_path('Filament/Partner/Resources'))
Who can access: Users with an active PartnerAttorneyUser record.
Scoping: All queries scoped by PartnerAttorneyUser → PartnerAttorney → assigned matters.