Zodiac Tech CRM Docs

Architecture overview

How the platform is put together — Laravel 13 + Filament v4, three panels, the services layer, observers, jobs and the request lifecycle.

developer Medium ⏱ 10 min Updated 2026-10-05

Architecture overview

The platform is a single Laravel application that serves four surfaces — three Filament panels, a REST/mobile API, and the public marketing + docs site — over one MySQL database with tenant isolation at the model layer. This page is the map; the detailed pages are linked at the bottom.

Who this is for

Developers and hosting admins who will maintain, extend or debug the install.

Difficulty: Medium · Time: about 10 minutes · Prerequisites: familiarity with Laravel and a checkout of the repository.

The stack

Concern Choice
Framework Laravel 13 (PHP 8.4+)
Admin UI Filament v4 (Livewire under the hood)
Database MySQL (leadhub locally; any MySQL 8-compatible server in production)
Queue sync locally; database + worker in production — see Queues, jobs & scheduler
Scheduler Laravel's scheduler driven by one cron entry (php artisan schedule:run every minute)
Deployment target Shared cPanel/Apache hosting (subdomain install), not Docker

Surfaces and panel providers

Surface Path Provider / entry
Tenant CRM /admin App\Providers\Filament\AdminPanelProvider (panel id admin)
Super Admin /super-admin App\Providers\Filament\SuperAdminPanelProvider (id super-admin)
Agency (Meta Ops) /agency App\Providers\Filament\AgencyPanelProvider (id agency)
REST API /api/v1 API-key authenticated controllers (routes/api.php)
Mobile API /api/v1/mobile Device-token authenticated controllers (routes/api.php)
Marketing + docs /, /pricing, /docs Blade controllers/views
OpenAPI viewer /api/docs Api\ApiDocsController

Request lifecycle

flowchart LR
    A[HTTP request] --> B[bootstrap/app.php middleware]
    B --> C{Surface}
    C -->|/admin /super-admin /agency| D[Filament panel provider]
    C -->|/api/v1| E[REST controller + api.key middleware]
    C -->|/api/v1/mobile| F[Mobile controller + DeviceAuthenticate]
    D --> G[Service layer app/Services]
    E --> G
    F --> G
    G --> H[Eloquent models + BelongsToTenant global scope]
    H --> I[(MySQL)]

bootstrap/app.php is the single wiring point: middleware groups, alias list (tenant.scope, api.key, portal.auth, login.lockout, sa.ip.allowlist, Spatie role/permission), CSRF exceptions for token-authenticated inbound endpoints, and the API/mobile error-envelope renderers.

Key middleware on every web request

  • App\Http\Middleware\TrustProxies — trusts nothing by default; opt in via TRUSTED_PROXIES.
  • App\Http\Middleware\ResolveTenant — resolves and binds the workspace for web requests.
  • App\Http\Middleware\TrackUserSession, SetLocale, SecurityHeaders.

API and mobile requests bind their tenant from the credential instead — see Authentication.

The services layer

Business logic lives in app/Services/ and is called by controllers, jobs and Filament actions — controllers stay thin.

Representative services:

Area Services
Lead capture Services\LeadSources\*, ConnectorRegistry, MetaConnector, MetaLeadFormService
Messaging Services\WhatsApp\* (MetaCloudWhatsAppProvider, template/message/media services)
Billing Services\CommercialBilling\*, TenantSubscriptionState, EntitlementService
Onboarding guided-onboarding services backing business_onboarding + steps
Mobile MobileApp\MobileAppConfig, push via PushService
AI Services\Ai\AiChatClient (provider openai/deepseek)

Model observers

Registered observers in app/Observers/ keep cross-cutting behavior out of controllers:

  • LeadObserver — lead lifecycle side effects.
  • LeadAuditObserver — audit trail for lead changes.
  • LeadWebhookObserver — outbound webhook triggers.
  • MeetingBookingObserver — appointment/booking side effects.
  • TenantCacheFlushObserver — clears tenant-keyed caches when a tenant changes.
  • TenantProvisioningObserver — provisions a new workspace's defaults.

Jobs and scheduler

Background work is queued (app/Jobs/) and driven by routes/console.php — inbound webhook processing (ProcessInboundWebhook), push delivery (SendPushToUser), email sequences, AI SDR, Meta ops, billing lifecycle, retention/erasure, backups. The full, exact schedule is documented in Queues, jobs & scheduler.

Tenancy, auth and RBAC in one line each

Conventions to follow when extending

  1. New tenant-owned table → add tenant_id, use the BelongsToTenant trait on the model, and a composite unique index (tenant_id + natural key).
  2. New Filament resource → set protected static string $permissionPrefix = '…' and use HasRolePermissions.
  3. New background task → add the job class and one Schedule:: line in routes/console.php with ->withoutOverlapping(10) and ->onFailure($logFailure('…')).
  4. New inbound webhook → token/signature verified, CSRF-exempt path registered in bootstrap/app.php, idempotency key enforced, failure recorded — see Webhooks (inbound).
  5. Docs: every nav slug in App\Support\DocsNav must have a matching file under resources/docs/ — the nav tree is the single source of truth for the information architecture.

Was this page helpful?