Skip to content

Backend Architecture

Overview

The backend is built on Laravel 13 running on FrankenPHP with Octane for long-lived worker processes. The application boots once and handles many requests within the same process.

Octane Considerations

  • Never store request-specific state in singletons or static properties — it leaks across requests
  • Prefer scoped bindings ($this->app->scoped()) over singletons for per-request services
  • Use config('octane.server') to detect the active driver (frankenphp, roadrunner, swoole)

Folder Structure

app/
├── Console/Commands/        # Artisan commands
├── Enums/
│   ├── Setup/               # Step enum for setup wizard
│   └── .../                 # Domain-specific enums
├── Exceptions/              # Custom exception classes
├── Filament/                # Filament admin panel (see Filament Architecture)
├── Http/
│   ├── Controllers/
│   │   ├── Api/             # JSON API controllers
│   │   ├── Landing/         # Public Inertia page controllers
│   │   └── ...
│   ├── Middleware/
│   │   ├── Setup/           # SetupMiddleware, MaintenanceMiddleware
│   │   ├── Inertia/         # HandleInertiaRequests
│   │   ├── Locale/          # SetLocale
│   │   └── Security/        # SecurityHeaders
│   ├── Requests/            # Form request validation
│   └── Resources/           # Eloquent API Resources
├── Models/
│   ├── Academic/            # Academic domain models
│   ├── Recruitment/         # Recruitment domain models
│   ├── Platform/            # Shared platform models (User, Asset, Setting, etc.)
│   └── .../                 # Other domains
├── Observers/               # Eloquent model observers
├── Providers/
│   ├── Filament/            # Panel service providers
│   └── .../                 # App service providers
├── Services/
│   ├── Asset/               # File upload + ImageKit CDN
│   ├── Codegen/             # Barcode + QR Code generation
│   ├── Common/              # IdentifierAppService (setup/state checks)
│   ├── Otp/                 # OTP generation + verification
│   ├── Platform/Pipeline/   # Pipeline orchestration
│   └── .../                 # Other services
└── Traits/
    ├── Common/
    │   ├── HasLocalization.php   # Localized JSON column resolution
    │   ├── HasContact.php        # Contact attachment via master table
    │   ├── HasLog.php            # Automatic activity logging
    │   └── HasAsset.php          # Dynamic asset relationships
    └── ...

Service Layer Pattern

Services live in app/Services/ and follow these conventions:

PatternExampleDescription
{Domain}/{Action}.phpOtp/Generate.phpSingle-action service with handle() method
{Domain}/{Name}Service.phpImageKitService.phpMulti-method service class

Rules:

  • Services contain business logic only — no HTTP concerns
  • Services call models and other services, never controllers
  • Services are injectable via constructor for testability

Trait Layer

Shared traits in app/Traits/Common/ provide cross-cutting functionality:

TraitFunction
HasLocalizationAuto-resolve JSON localized columns to current locale
HasContactAttach contact records via master contacts table
HasLogAutomatic audit logging on model create/update/delete
HasAssetDynamic BelongsTo relationships to assets table

Key Files

FilePurpose
bootstrap/app.phpMiddleware stack, service container
app/Http/Middleware/Setup/SetupMiddleware.phpFirst-run redirect gate
app/Http/Middleware/Setup/MaintenanceMiddleware.phpMaintenance mode + portal redirect
app/Services/Common/IdentifierAppService.phpCentralized state checks (isSetup(), seeder(), initial())
app/Providers/Filament/PortalPanelProvider.phpPortal admin panel configuration
app/Providers/Filament/EducationPanelProvider.phpEducation admin panel configuration