Skip to main content

Filament Admin Panel

Mounted at /systemadmin and implemented entirely in backend/app/Filament/.

Panel provider

app/Providers/Filament/SystemadminPanelProvider.php wires the panel:

$panel
->id('systemadmin')
->path('systemadmin')
->authGuard('systemadmin')
->spa()
->colors(['primary' => Color::Amber])
->discoverResources(in: app_path('Filament/Resources'),
for: 'App\\Filament\\Resources')
->discoverPages(in: app_path('Filament/Pages'),
for: 'App\\Filament\\Pages')
->discoverWidgets(in: app_path('Filament/Widgets'),
for: 'App\\Filament\\Widgets')
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
])
->authMiddleware([Authenticate::class]);

Resources

Each resource is a CRUD unit. The convention is:

Filament/Resources/<Plural>/
├── <Singular>Resource.php # entry point (getModel(), pages())
├── Schemas/<Singular>Form.php # form definition
├── Tables/<Plural>Table.php # list-view columns + filters
└── Pages/
├── List<Plural>.php
├── Create<Singular>.php
└── Edit<Singular>.php

SystemAdmins

Manage platform operators.

  • Form fields: name, email, phone, password (hashed on save).
  • Table columns: name, email, phone, created_at.

Tenants

Manage clinics.

  • Form fields: name, slug, email, phone, address, subscription_plan, status.
  • Table columns: name, slug, email, plan badge, status badge.
  • Overview widget: TenantOverview — aggregates subscribed plans and active count.

Users

Clinic staff and owners (both live in the same table, filterable by account_type).

  • Form fields: name, email, phone, account_type, current_tenant_id.
  • Table columns: name, email, account_type, current tenant.

Clients

Pet owners as seen by clinics.

  • Form fields: tenant, linked owner user (optional), full_name, email, phone, address, status.
  • Table columns: full_name, tenant.name, email, phone, status.

Pets

  • Form fields: tenant, client, name, species, breed, sex, date_of_birth, weight_kg, color_markings, allergies, medical_flags, status.
  • Table columns: name, species, breed, client.full_name, status.

Appointments

  • Form fields: tenant, pet, client, veterinarian (user), appointment_type, status, booking_source, scheduled_start, scheduled_end, reason, notes.
  • Table columns: scheduled_start, pet.name, client.full_name, status, veterinarian.name.
  • Filters: status, booking_source, date range.

Invoices

  • Form fields: tenant, client, pet, invoice_number, invoice_type, status, totals (subtotal, tax_total, discount_total, grand_total, balance_due), currency, issued_at, due_at, notes.
  • Table columns: invoice_number, client.full_name, grand_total (currency-formatted), status badge.

Payments

  • Form fields: tenant, invoice, amount, payment_method, status, reference_number, paid_at.
  • Table columns: invoice.invoice_number, amount, payment_method, status, paid_at.

Reminders

  • Form fields: tenant, client, pet, title, reminder_type, channel, due_at, status, payload (JSON).
  • Table columns: title, reminder_type, channel, due_at, status.
  • Custom action: "Mark as sent" — bulk action to flip status.

Widgets

Filament/Widgets/OverviewDashboard.php renders the platform-level overview on the Filament dashboard:

  • Total tenants, active tenants, suspended tenants.
  • Users count split by account_type.
  • Pets/appointments totals across all tenants.

Authentication

The Filament panel logs in through the systemadmin guard, which points at the SystemAdmin model and the system_admins provider defined in config/auth.php. It uses session auth — no bearer tokens — so every write request includes the standard Laravel CSRF token.

Adding a new Filament resource

php artisan make:filament-resource Foo --generate

This creates the FooResource.php, pages, schema and table stubs inside app/Filament/Resources/Foo/. Edit the form/table definitions, then visit /systemadmin/foo to use it.