Architecture Overview

Comprehensive guide to LaraDashboard's architecture, design patterns, and system components for developers building modules and extensions.

Architecture Overview

LaraDashboard follows a clean, modular architecture built on Laravel's best practices. Understanding this architecture is essential for developers who want to extend, customize, or build modules for the platform.

High-Level Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        Presentation Layer                        │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │
│  │   Livewire   │  │    Blade     │  │   React Components   │  │
│  │  Components  │  │   Views      │  │    (LaraBuilder)     │  │
│  └──────────────┘  └──────────────┘  └──────────────────────┘  │
├─────────────────────────────────────────────────────────────────┤
│                       Application Layer                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │
│  │ Controllers  │  │  Form        │  │    API Resources     │  │
│  │              │  │  Requests    │  │                      │  │
│  └──────────────┘  └──────────────┘  └──────────────────────┘  │
├─────────────────────────────────────────────────────────────────┤
│                        Service Layer                             │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │
│  │   Services   │  │  Registries  │  │   Hooks System       │  │
│  │              │  │              │  │                      │  │
│  └──────────────┘  └──────────────┘  └──────────────────────┘  │
├─────────────────────────────────────────────────────────────────┤
│                         Domain Layer                             │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │
│  │    Models    │  │   Policies   │  │     Observers        │  │
│  │              │  │              │  │                      │  │
│  └──────────────┘  └──────────────┘  └──────────────────────┘  │
├─────────────────────────────────────────────────────────────────┤
│                     Infrastructure Layer                         │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │
│  │   Database   │  │    Cache     │  │    File Storage      │  │
│  │              │  │              │  │                      │  │
│  └──────────────┘  └──────────────┘  └──────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Design Patterns

LaraDashboard implements several design patterns to maintain clean, extensible code:

Service Pattern

Business logic is encapsulated in service classes:

namespace App\Services;

class PostService
{
    public function __construct(
        private SlugService $slugService,
        private CacheService $cacheService
    ) {}

    public function create(array $data): Post
    {
        $data['slug'] = $this->slugService->generateUnique(
            $data['title'],
            Post::class
        );

        $post = Post::create($data);

        $this->cacheService->forget('posts.recent');

        return $post;
    }

    public function update(Post $post, array $data): Post
    {
        $post->update($data);

        $this->cacheService->forget("post.{$post->id}");

        return $post->fresh();
    }
}

Registry Pattern

Extensible systems use registries for dynamic registration:

namespace App\Services;

class EmailProviderRegistry
{
    protected array $providers = [];

    public function register(string $key, string $class): void
    {
        $this->providers[$key] = $class;
    }

    public function get(string $key): ?EmailProviderInterface
    {
        if (!isset($this->providers[$key])) {
            return null;
        }

        return app($this->providers[$key]);
    }

    public function all(): array
    {
        return $this->providers;
    }
}

Observer Pattern

Model events trigger observers for side effects:

namespace App\Observers;

class PostObserver
{
    public function created(Post $post): void
    {
        ActionLog::create([
            'user_id' => auth()->id(),
            'action' => 'created',
            'model_type' => Post::class,
            'model_id' => $post->id,
        ]);
    }

    public function updated(Post $post): void
    {
        Cache::forget("post.{$post->id}");
    }

    public function deleted(Post $post): void
    {
        $post->meta()->delete();
        $post->clearMediaCollection('featured');
    }
}

Policy Pattern

Authorization logic lives in policy classes:

namespace App\Policies;

class PostPolicy
{
    public function viewAny(User $user): bool
    {
        return $user->can('posts.view');
    }

    public function create(User $user): bool
    {
        return $user->can('posts.create');
    }

    public function update(User $user, Post $post): bool
    {
        if ($user->can('posts.edit')) {
            return true;
        }

        return $user->id === $post->user_id
            && $user->can('posts.edit_own');
    }

    public function delete(User $user, Post $post): bool
    {
        return $user->can('posts.delete');
    }
}

Request Lifecycle

Understanding the request lifecycle helps when debugging or extending:

┌──────────────────────────────────────────────────────────────────┐
│                         HTTP Request                              │
└──────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌──────────────────────────────────────────────────────────────────┐
│  1. Middleware Pipeline                                          │
│     - Authentication                                             │
│     - Authorization                                              │
│     - Rate Limiting                                              │
│     - CSRF Protection                                            │
└──────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌──────────────────────────────────────────────────────────────────┐
│  2. Route Resolution                                             │
│     - Match route pattern                                        │
│     - Apply route middleware                                     │
│     - Resolve controller/action                                  │
└──────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌──────────────────────────────────────────────────────────────────┐
│  3. Form Request Validation                                      │
│     - Validate input data                                        │
│     - Authorize action                                           │
│     - Sanitize inputs                                            │
└──────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌──────────────────────────────────────────────────────────────────┐
│  4. Controller Action                                            │
│     - Invoke service layer                                       │
│     - Process business logic                                     │
│     - Return response                                            │
└──────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌──────────────────────────────────────────────────────────────────┐
│  5. Response                                                     │
│     - Render view (Blade/Livewire)                               │
│     - Return JSON (API)                                          │
│     - Redirect                                                   │
└──────────────────────────────────────────────────────────────────┘

Core Components

Controllers

Controllers handle HTTP requests and delegate to services:

namespace App\Http\Controllers\Backend;

class PostController extends Controller
{
    public function __construct(
        private PostService $postService
    ) {}

    public function store(StorePostRequest $request)
    {
        $post = $this->postService->create($request->validated());

        return redirect()
            ->route('admin.posts.edit', $post)
            ->with('success', 'Post created successfully');
    }
}

Form Requests

Validation and authorization in dedicated classes:

namespace App\Http\Requests\Post;

class StorePostRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('posts.create');
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'content' => ['required', 'string'],
            'status' => ['required', Rule::in(['draft', 'published'])],
            'category_ids' => ['array'],
            'category_ids.*' => ['exists:terms,id'],
        ];
    }

    public function messages(): array
    {
        return [
            'title.required' => 'Please enter a title for your post.',
            'content.required' => 'Post content cannot be empty.',
        ];
    }
}

Services

Business logic encapsulated in service classes:

namespace App\Services;

class UserService
{
    public function create(array $data): User
    {
        $user = User::create([
            'first_name' => $data['first_name'],
            'last_name' => $data['last_name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        $user->assignRole($data['role'] ?? 'subscriber');

        if ($data['send_welcome_email'] ?? false) {
            $user->notify(new RegistrationWelcomeNotification());
        }

        return $user;
    }
}

Models

Eloquent models with relationships and scopes:

namespace App\Models;

class Post extends Model
{
    use HasFactory, InteractsWithMedia, HasUniqueSlug;

    protected $fillable = [
        'title', 'slug', 'content', 'design',
        'status', 'user_id', 'parent_id',
        'featured_image_id', 'published_at',
    ];

    protected function casts(): array
    {
        return [
            'design' => 'array',
            'published_at' => 'datetime',
        ];
    }

    // Relationships
    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function categories(): BelongsToMany
    {
        return $this->belongsToMany(Term::class, 'term_relationships')
            ->where('taxonomy', 'category');
    }

    public function meta(): HasMany
    {
        return $this->hasMany(PostMeta::class);
    }

    // Scopes
    public function scopePublished(Builder $query): Builder
    {
        return $query->where('status', 'published')
            ->where('published_at', '<=', now());
    }

    public function scopeSearchable(Builder $query, string $search): Builder
    {
        return $query->where(function ($q) use ($search) {
            $q->where('title', 'like', "%{$search}%")
              ->orWhere('content', 'like', "%{$search}%");
        });
    }
}

Module System Architecture

Modules are self-contained packages with their own MVC structure:

┌─────────────────────────────────────────────────────────────────┐
│                     LaraDashboard Core                           │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │   Module A  │  │   Module B  │  │       Module C          │  │
│  │             │  │             │  │                         │  │
│  │  app/       │  │  app/       │  │  app/                   │  │
│  │  config/    │  │  config/    │  │  config/                │  │
│  │  database/  │  │  database/  │  │  database/              │  │
│  │  resources/ │  │  resources/ │  │  resources/             │  │
│  │  routes/    │  │  routes/    │  │  routes/                │  │
│  └─────────────┘  └─────────────┘  └─────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Modules communicate with core through:

  • Service Providers - Register bindings and boot logic
  • Hooks - Action and filter hooks for extensibility
  • Events - Laravel event system
  • Contracts - Interface-based communication

Hooks Architecture

The hooks system enables WordPress-like extensibility:

┌───────────────────────────────────────────────────────────────┐
│                    Hook Execution Flow                         │
├───────────────────────────────────────────────────────────────┤
│                                                               │
│  Module A                     Core                Module B    │
│  ┌───────┐                ┌─────────┐            ┌───────┐   │
│  │Register│───────────────▶│  Hook   │◀───────────│Register│  │
│  │Listener│               │ Manager │            │Listener│   │
│  └───────┘                └────┬────┘            └───────┘   │
│                                │                              │
│                    ┌───────────┴───────────┐                 │
│                    ▼                       ▼                  │
│              ┌──────────┐           ┌──────────┐             │
│              │  Action  │           │  Filter  │              │
│              │  Hooks   │           │  Hooks   │              │
│              └──────────┘           └──────────┘             │
│                    │                       │                  │
│                    ▼                       ▼                  │
│              Execute all             Transform and           │
│              listeners               return value            │
│                                                               │
└───────────────────────────────────────────────────────────────┘

Data Flow

Content Creation Flow

User Input
    │
    ▼
┌─────────────────┐
│ Form Request    │── Validation & Authorization
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Controller      │── Route to Service
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Service         │── Business Logic
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Model           │── Eloquent Operations
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Observer        │── Side Effects
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Database        │── Persist Data
└─────────────────┘

API Request Flow

API Request
    │
    ▼
┌─────────────────┐
│ Sanctum Auth    │── Token Validation
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Rate Limiting   │── Request Throttling
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ API Controller  │── Process Request
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ API Resource    │── Transform Response
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ JSON Response   │
└─────────────────┘

Security Architecture

Authentication Layers

┌───────────────────────────────────────────────────────────────┐
│                    Authentication Flow                         │
├───────────────────────────────────────────────────────────────┤
│                                                               │
│  Web Requests          API Requests                           │
│  ┌──────────┐         ┌──────────┐                           │
│  │ Session  │         │ Sanctum  │                           │
│  │ Guard    │         │ Token    │                           │
│  └────┬─────┘         └────┬─────┘                           │
│       │                    │                                  │
│       └────────┬───────────┘                                 │
│                ▼                                              │
│         ┌──────────────┐                                     │
│         │     User     │                                     │
│         │    Model     │                                     │
│         └──────┬───────┘                                     │
│                │                                              │
│                ▼                                              │
│         ┌──────────────┐                                     │
│         │    Roles     │                                     │
│         │ Permissions  │                                     │
│         └──────────────┘                                     │
│                                                               │
└───────────────────────────────────────────────────────────────┘

Permission Hierarchy

Super Admin
    │
    ├── All Permissions (wildcard)
    │
Admin
    │
    ├── users.*
    ├── roles.*
    ├── posts.*
    ├── settings.*
    └── modules.*
    │
Editor
    │
    ├── posts.view
    ├── posts.create
    ├── posts.edit
    └── media.*
    │
Author
    │
    ├── posts.view
    ├── posts.create
    └── posts.edit_own

Caching Strategy

LaraDashboard uses strategic caching:

Cache Type Driver TTL Use Case
Config File Forever Application config
Routes File Forever Route definitions
Views File Forever Compiled Blade
Settings Redis/File 24h Database settings
Permissions Redis/File 24h RBAC cache
API Responses Redis 5-60min Expensive queries

Next Steps

/