Full Technology Stack

Frontend Layer

Library / ToolVersionPurposeNotes
React18.3Core UI library — component model, hooks, state managementFunctional components throughout, no class components
Inertia.js1.2Client/server bridge — eliminates the need for a REST API for page rendersPages are React components, data is passed as props from Laravel controllers
Tailwind CSS4.0Utility-first CSS frameworkUsed with the Vite plugin for JIT compilation
Vite5.4Frontend build tool and dev server with HMRReplaces Laravel Mix. Configured in vite.config.js
shadcn/uiPre-built accessible UI components (dialogs, dropdowns, tables)Components are copied into the codebase and customized
Lucide React0.400Icon library — 1,400+ consistent SVG iconsTree-shakeable, used throughout the UI
React i18next14.xInternationalization — EN and ES language supportTranslation files in resources/js/i18n/
Recharts2.12Chart library for dashboard analyticsLine charts, bar charts, pie/donut charts for KPI visualization
Ziggy2.3Exports Laravel named routes to JavaScriptAllows using route() helper in React components

Backend Layer

Library / ToolVersionPurposeNotes
Laravel12.xPHP application framework — routing, ORM, queues, events, validationBuilt on PHP 8.2+ with modern PHP features
Spatie Laravel Permission6.xRole and permission management, stored in databaseRoles: super-admin, admin, manager, dispatcher, courier, accountant, customer
Spatie Laravel Activity Log4.xAutomatic audit logging for all Eloquent model eventsLogs causer (user), subject (model), description, and metadata as JSON
Laravel Sanctum4.xAPI token authentication for the REST APISPA authentication uses Sanctum's cookie-based session for Inertia
Laravel Socialite5.xOAuth 2.0 social login library (installed, not active in this version)Package is present but social login routes are not enabled in the basic version.
Barryvdh DomPDF3.xPDF generation for invoices, shipment labels, and reportsUses Blade views as PDF templates
maatwebsite/excel3.xExcel and CSV export for reportsLeverages Laravel queues for large exports
intervention/image3.xImage processing for logo uploads and resizingRequires GD or Imagick PHP extension

Infrastructure Layer

ComponentDefaultAlternativePurpose
DatabaseMySQL 8.0MariaDB 10.6+Primary relational data store for all application data
CacheRedisFile driverQuery result caching, view cache, rate limiting counters
SessionRedisFile / DatabaseUser session storage. Redis recommended for multi-server deployments
QueueRedisDatabase / SyncBackground job processing — emails, PDF generation, report exports
File StorageLocal diskAWS S3 / S3-compatibleLogos, shipment labels, employee documents, report files

Project Folder Structure

The project follows standard Laravel conventions with additional directories for services, React components, and localization files.

deprixa-plus/
├── app/
│   ├── Console/
│   │   └── Commands/
│   │       └── CleanActivityLog.php       # Prune old audit log entries
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Auth/                      # Login, register, password reset, 2FA
│   │   │   ├── Api/                       # API v1 controllers
│   │   │   ├── Settings/                  # All settings sub-controllers
│   │   │   │   ├── BrandingController.php
│   │   │   │   ├── CompanyController.php
│   │   │   │   ├── LocaleController.php
│   │   │   │   ├── NotificationsController.php
│   │   │   │   ├── SecurityController.php
│   │   │   │   └── UpdatesController.php
│   │   │   ├── ShipmentController.php
│   │   │   ├── ClientController.php
│   │   │   ├── InvoiceController.php
│   │   │   ├── ReportController.php
│   │   │   └── DashboardController.php
│   │   ├── Middleware/
│   │   │   ├── CheckPermission.php        # Spatie permission gate middleware
│   │   │   └── HandleInertiaRequests.php  # Shares global Inertia props
│   │   └── Requests/                      # Form request validation classes
│   ├── Models/
│   │   ├── User.php
│   │   ├── Shipment.php
│   │   ├── ShipmentStatus.php
│   │   ├── Client.php
│   │   ├── Invoice.php
│   │   ├── InvoiceItem.php
│   │   ├── Branch.php
│   │   ├── ServiceType.php
│   │   └── Setting.php                    # Key-value settings store
│   └── Services/
│       ├── ShipmentService.php            # Business logic for shipments
│       ├── InvoiceService.php
│       ├── NotificationService.php
│       └── ReportService.php
├── config/
│   ├── app.php
│   ├── auth.php
│   ├── database.php
│   ├── filesystems.php
│   └── permission.php                     # Spatie permission config
├── database/
│   ├── migrations/
│   │   ├── 0001_01_01_000000_create_users_table.php
│   │   ├── create_shipments_table.php
│   │   ├── create_clients_table.php
│   │   ├── create_invoices_table.php
│   │   ├── create_branches_table.php
│   │   ├── create_settings_table.php
│   │   └── create_activity_log_table.php  # From spatie/laravel-activitylog
│   └── seeders/
│       ├── DatabaseSeeder.php
│       ├── RoleSeeder.php                 # Creates all roles and permissions
│       ├── UserSeeder.php                 # Default admin user
│       ├── SettingSeeder.php              # Default company settings
│       └── ShipmentStatusSeeder.php
├── public/
│   ├── index.php
│   ├── build/                             # Compiled frontend assets (Vite output)
│   └── storage -> ../storage/app/public  # Symlink (php artisan storage:link)
├── resources/
│   ├── js/
│   │   ├── app.jsx                        # Inertia app entry point
│   │   ├── bootstrap.js
│   │   ├── Components/
│   │   │   ├── Layout/                    # Sidebar, topbar, breadcrumb
│   │   │   ├── UI/                        # shadcn/ui adapted components
│   │   │   ├── Shipment/                  # Shipment-specific components
│   │   │   └── Charts/                    # Recharts wrappers
│   │   ├── Layouts/
│   │   │   ├── AuthLayout.jsx             # Login/register page wrapper
│   │   │   └── AppLayout.jsx              # Main authenticated app wrapper
│   │   ├── Pages/
│   │   │   ├── Auth/                      # Login, Register, ForgotPassword, 2FA
│   │   │   ├── Dashboard/                 # Dashboard.jsx with KPI cards + charts
│   │   │   ├── Shipments/                 # Index, Create, Show, Edit
│   │   │   ├── Clients/
│   │   │   ├── Invoices/
│   │   │   ├── Reports/
│   │   │   └── Settings/                  # All settings sub-pages
│   │   └── i18n/
│   │       ├── en.json                    # English translations
│   │       └── es.json                    # Spanish translations
│   └── views/
│       ├── app.blade.php                  # Inertia root template
│       └── pdf/                           # PDF Blade templates (invoices, labels)
├── routes/
│   ├── web.php                            # All Inertia page routes (authenticated)
│   ├── api.php                            # REST API v1 routes (Sanctum)
│   └── console.php                        # Scheduled command definitions
├── storage/
│   ├── app/
│   │   └── public/                        # User uploads (accessible via symlink)
│   ├── framework/
│   │   ├── cache/
│   │   ├── sessions/
│   │   └── views/                         # Compiled Blade view cache
│   └── logs/
│       └── laravel.log
├── .env                                   # Environment configuration (not in git)
├── artisan                                # Laravel CLI entry point
├── composer.json
├── package.json
└── vite.config.js

System Architecture Diagram

This diagram shows how the major system components interact at runtime.

Browser React + Inertia.js Tailwind CSS HTTPS Nginx Web Server SSL Termination PHP-FPM Laravel 12 Controllers Services / Models Spatie RBAC Activity Log Sanctum / Socialite Queue Worker MySQL 8 Primary Database All app data Redis Cache / Sessions Job Queues Storage Local / S3 Files & Labels Mail (SMTP) Mailgun / SES / SendGrid API Consumers Mobile apps, integrations Sanctum Bearer tokens -- - HTTPS request — Database — Cache/Queue - - - External service

Request Data Flow

Inertia.js Page Request (Authenticated Users)

  1. Browser sends an HTTP GET to https://app.yourdomain.com/shipments
  2. Nginx routes to PHP-FPM socket
  3. HandleInertiaRequests middleware runs, shares global props (auth user, flash messages, permissions, settings) with the React page
  4. ShipmentController@index queries the database with Eloquent, applies permission scopes, paginates results
  5. Controller returns Inertia::render('Shipments/Index', ['shipments' => ...])
  6. For full page loads: Laravel returns a full HTML page with the React app bootstrapped inside the Blade template
  7. For Inertia SPA navigations: Laravel returns a JSON response with X-Inertia header — React swaps the page component without a full reload

API Request Flow (External Integrations)

  1. Client sends POST to /api/tokens with email, password, device_name
  2. Laravel validates credentials, creates a Sanctum personal access token, returns it in the response
  3. Client includes Authorization: Bearer {token} header on subsequent requests
  4. Sanctum middleware authenticates the token, loads the user with their Spatie roles and permissions
  5. API controller processes the request and returns JSON

Background Job Flow (Notifications, Exports)

  1. User triggers an action (e.g., mark shipment delivered)
  2. Controller calls a Service class method
  3. Service dispatches a queued Job (e.g., SendDeliveryNotification::dispatch($shipment))
  4. Job is serialized and pushed to the Redis queue
  5. Queue worker (running as a Supervisord process) picks up the job and executes it asynchronously
  6. On failure, the job is retried up to 3 times with exponential backoff

Authentication Architecture

Deprixa Plus supports four authentication methods:

MethodUsed ByImplementation
Email + Password All users — primary login method Laravel built-in auth with session cookies. Rate-limited to prevent brute force.
TOTP 2FA Any user who enables it; enforced for admins if configured Time-based One-Time Password (RFC 6238). Compatible with Google Authenticator, Authy, 1Password.
API Bearer Token External integrations, mobile apps Laravel Sanctum personal access tokens. Created via POST /api/tokens. Revocable.

Inertia SPA vs. REST API

The Inertia frontend uses Laravel's session-based authentication (cookies) — not Bearer tokens. Bearer tokens are only for external API consumers. This means the Inertia app benefits from CSRF protection and traditional Laravel session security automatically.

Permissions Architecture (Spatie)

Deprixa Plus uses Spatie Laravel Permission for all access control. Permissions are stored in the permissions table and assigned to roles. Roles are assigned to users. The permission cache is stored in Redis.

php
// In a controller: checking permissions
public function destroy(Shipment $shipment)
{
    $this->authorize('delete-shipments');
    // or: Gate::authorize('delete-shipments');
    // or: abort_unless(auth()->user()->can('delete-shipments'), 403);

    $shipment->delete();
}

// In middleware (routes/web.php)
Route::middleware(['auth', 'permission:manage-settings'])
    ->prefix('settings')
    ->group(function () {
        Route::get('/', [SettingsController::class, 'index']);
        // ...
    });

// In React (Inertia shared props)
// HandleInertiaRequests.php shares:
// $permissions = auth()->user()->getAllPermissions()->pluck('name')
// Used in React as: page.props.auth.permissions.includes('delete-shipments')

Dynamic Settings Store

Application settings (company info, branding, locale, notification preferences) are stored in a settings table as key-value pairs. This allows runtime configuration without modifying code or environment files.

sql
CREATE TABLE settings (
    id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    key         VARCHAR(255) NOT NULL UNIQUE,
    value       TEXT,
    type        ENUM('string','boolean','json','integer') DEFAULT 'string',
    group       VARCHAR(100) DEFAULT 'general',
    created_at  TIMESTAMP,
    updated_at  TIMESTAMP
);

Settings are read with a typed helper and cached in Redis:

php
// Get a setting value with a default
setting('company.name', 'My Company');

// Set a setting
setting(['company.name' => 'Deprixa Plus Corp']);

// Flush settings cache (called automatically on save)
Cache::forget('app_settings');

Multi-Tenant Architecture

Deprixa Plus uses a single-database, shared-schema multi-tenancy model:

Role Hierarchy

text
Super Admin ──→ Full access to everything + organization management
    │
Admin ──→ Full operational + settings access within their organization
    │
Employee ──→ Daily operations (shipments, customers, pickups, warehouse, import) — no financial data, no settings
    │
Driver ──→ Assigned shipments and pickups only — dedicated mobile-friendly dashboard
    │
Customer ──→ Self-service portal (My Locker, Pre-Alerts, Tracking, Contacts)