Architecture générale de l'application

Documentation complète de l'architecture modulaire de l'application Laravel, avec séparation claire entre le cœur de l'application et les modules spécifiques.

Structure générale

app/

Logique liée à l'application elle-même, le cœur fonctionnel de base.

  • Http/Controllers – Contrôleurs principaux
  • Livewire – Composants Livewire de base
  • Models – Modèles principaux (User, Page)
  • Services – Services généraux
  • Filament – Configuration Filament
  • Events – Événements globaux

app/Specifics/

Modules annexes au site de base, fonctionnalités spécifiques et indépendantes.

  • FeedbackHub – Gestion des retours
  • Blog – Système de blog
  • Shop – E-commerce
  • MediaManager – Gestion des médias
  • BlockBuilder – Constructeur de blocs
  • Appointments – Rendez-vous
  • Invoices – Facturation
  • FeedbackPerso – Retours personnels

app/Specifics/Shares/

Fichiers partagés entre différents modules pour éviter la duplication de code.

  • Models – Modèles partagés
  • Enums – Énumérations communes
  • Concerns – Traits réutilisables

Structure d'un module Spec

Chaque module dans app/Specifics/ suit une structure standardisée pour maintenir la cohérence et faciliter la maintenance.

app/Specifics/ModuleName/
├── Actions/          # Actions métier (Create, Update, Delete, etc.)
├── Commands/         # Commandes Artisan spécifiques au module
├── Controllers/      # Contrôleurs HTTP si nécessaire
├── Enums/            # Énumérations spécifiques au module
├── Events/           # Événements déclenchés par le module
├── Factories/        # Factories pour les tests
├── Listeners/        # Écouteurs d'événements
├── Models/           # Modèles Eloquent
├── Observers/        # Observers Eloquent
├── Policies/         # Policies d'autorisation
├── Queries/          # Queries pour récupérer des données
├── Requests/         # Form Requests pour la validation
└── Services/         # Services métier complexes

Actions

Les Actions encapsulent la logique métier atomique. Elles sont utilisées par les Services, Controllers ou Composants Livewire.

Exemple :

CreateFeedbackAction::execute($user, $data)

Voir la documentation complète du pattern Action →

Queries

Les Queries encapsulent les requêtes complexes pour récupérer des données. Elles peuvent inclure des filtres, des relations, etc.

Exemple :

GetFeedbackListQuery::execute(['type' => FeedbackType::FEATURE])

Voir la documentation complète du pattern Query →

Services

Les Services orchestrent plusieurs Actions ou Queries pour une logique métier complexe. Ils sont généralement injectés dans les Controllers.

Voir la documentation complète du pattern Service →

DTOs (Data Transfer Objects)

Les DTOs encapsulent des données complexes passées entre couches. Ils garantissent la structure et la validation des données.

Voir la documentation complète du pattern DTO →

Models & Enums

Les Modèles et Énumérations définissent la structure des données et les types de valeurs possibles.

Voir les conventions de nommage →

Events & Listeners

Les Événements permettent de découpler les actions et les réactions. Les Listeners réagissent aux événements (notifications, logs, etc.).

Mode opératoire : Création d'une fonctionnalité de base

Guide étape par étape pour créer une nouvelle page ou fonctionnalité dans le cœur de l'application (app/).

1

Création des migrations / factories / seeder

Créer la structure de base de données et les données de test.

# Migration
php artisan make:migration create_examples_table

# Factory
php artisan make:factory ExampleFactory

# Seeder
php artisan make:seeder ExampleSeeder
2

Création des models / Enums

Définir les modèles Eloquent et les énumérations nécessaires.

# Model
php artisan make:model Example

# Enum (manuellement)
app/Enums/ExampleStatus.php
3

Création des FormRequest pour la validation

Créer les classes de validation pour les formulaires.

php artisan make:request StoreExampleRequest
php artisan make:request UpdateExampleRequest
4

Création de la route et du controller

Créer le contrôleur et définir les routes avec les middlewares nécessaires.

# Controller
php artisan make:controller ExampleController

# Route (routes/web.php ou routes/api.php)
Route::middleware(['auth'])->group(function () {
    Route::resource('examples', ExampleController::class);
});
5

Création du service et des actions

Le contrôleur récupère les données validées et les envoie vers un Service qui utilise des Actions Laravel pour la logique métier.

# Service (app/Services/)
app/Services/ExampleService.php

# Action (si logique complexe)
app/Actions/CreateExampleAction.php

# Dans le Controller
public function store(StoreExampleRequest $request, ExampleService $service)
{
    $example = $service->create($request->validated());
    return redirect()->route('examples.show', $example);
}
6

Création des vues Blade / Composants

Créer les vues Blade et les composants réutilisables.

# Vues Blade
resources/views/examples/
  ├── index.blade.php
  ├── create.blade.php
  ├── edit.blade.php
  └── show.blade.php

# Composants (si nécessaire)
php artisan make:component ExampleCard
7

Création des assets front

Ajouter les styles CSS et scripts JavaScript nécessaires.

# CSS (resources/css/)
resources/css/examples.css

# JavaScript (resources/js/)
resources/js/examples.js

# Compiler les assets
npm run build
# ou
npm run dev

Mode opératoire : Création d'un module Spec

Guide étape par étape pour créer un nouveau module dans app/Specifics/.

1

Création de la structure du module

Créer la structure de dossiers du module et les migrations.

# Structure de dossiers
app/Specifics/ModuleName/
├── Actions/
├── Enums/
├── Models/
├── Requests/
└── ...

# Migration
php artisan make:migration create_module_name_table
2

Création des models / Enums

Définir les modèles et énumérations spécifiques au module.

# Model
php artisan make:model Specifics/ModuleName/Models/Example

# Enum
app/Specifics/ModuleName/Enums/ExampleStatus.php
3

Création des FormRequest

Créer les classes de validation dans le module.

php artisan make:request Specifics/ModuleName/Requests/StoreExampleRequest
4

Création des Actions

Créer les Actions qui encapsulent la logique métier.

# Action
app/Specifics/ModuleName/Actions/CreateExampleAction.php

class CreateExampleAction
{
    public function execute(array $data): Example
    {
        return DB::transaction(function () use ($data) {
            $example = Example::create($data);
            event(new ExampleCreated($example));
            return $example;
        });
    }
}
5

Création des Queries (si nécessaire)

Créer les Queries pour les requêtes complexes de récupération de données.

# Query
app/Specifics/ModuleName/Queries/GetExamplesQuery.php

class GetExamplesQuery
{
    public function execute(array $filters = []): Collection
    {
        return Example::query()
            ->when($filters['status'] ?? null, fn($q, $status) =>
                $q->where('status', $status))
            ->get();
    }
}
6

Création des routes et contrôleurs

Créer les routes et contrôleurs (ou utiliser Livewire).

# Option 1 : Controller
php artisan make:controller Specifics/ModuleName/Controllers/ExampleController

# Option 2 : Livewire (recommandé)
php artisan make:livewire ModuleName/Examples/Index

# Route
Route::middleware(['auth'])->group(function () {
    Route::get('/examples', Index::class)->name('examples.index');
});
7

Création des Events & Listeners

Créer les événements et écouteurs pour découpler les actions.

# Event
php artisan make:event Specifics/ModuleName/Events/ExampleCreated

# Listener
php artisan make:listener Specifics/ModuleName/Listeners/SendExampleNotification

# Enregistrer dans EventServiceProvider
8

Création des vues et composants

Créer les vues Blade et composants Livewire.

# Vues Livewire
resources/views/livewire/module-name/examples/
  ├── index.blade.php
  └── create.blade.php

# Composants Blade réutilisables
resources/views/components/module-name/example-card.blade.php
9

Utilisation des fichiers partagés (Shares)

Utiliser les modèles, enums et concerns partagés pour éviter la duplication.

# Utiliser un modèle partagé
use App\Specifics\Shares\Models\Category;
use App\Specifics\Shares\Models\Tag;

# Utiliser un concern partagé
use App\Specifics\Shares\Models\Concerns\HasComments;

class Example extends Model
{
    use HasComments;

    // ...
}

Bonnes pratiques

Séparation des responsabilités

  • Actions : Logique métier simple et atomique
  • Services : Orchestration de plusieurs actions
  • Queries : Récupération de données complexes
  • Controllers/Livewire : Gestion des requêtes HTTP

Réutilisation via Shares

  • • Utiliser les modèles partagés (Category, Tag, Comment, etc.)
  • • Utiliser les concerns (HasComments, HasReactions, etc.)
  • • Utiliser les enums partagés (CategoryType, TagType, etc.)
  • • Éviter la duplication de code entre modules

Transactions et événements

  • • Utiliser DB::transaction() dans les Actions
  • • Déclencher des événements après les actions importantes
  • • Utiliser les Listeners pour les effets de bord (notifications, logs)

Validation et autorisation

  • • Toujours utiliser des FormRequest pour la validation
  • • Créer des Policies pour l'autorisation
  • • Vérifier les permissions dans les Actions si nécessaire

Exemple complet : Flux de création

Exemple : Création d'un feedback

1. Route (routes/web.php) :

Route::get('/feedback/create', Create::class)
    ->middleware('auth')
    ->name('feedback.create');

2. Composant Livewire (app/Livewire/FeedbackHub/Feedback/Create.php) :

public function save(CreateFeedbackAction $action)
{
    $this->validate();

    $feedback = $action->execute(auth()->user(), [
        'type' => FeedbackType::from($this->type),
        'title' => $this->title,
        'description' => $this->description,
    ]);

    return redirect()->route('feedback.show', $feedback);
}

3. Action (app/Specifics/FeedbackHub/Actions/CreateFeedbackAction.php) :

public function execute(User $user, array $data): Feedback
{
    return DB::transaction(function () use ($user, $data) {
        $feedback = Feedback::create([
            'user_id' => $user->id,
            'status' => FeedbackStatus::OPEN,
            ...$data,
        ]);

        event(new FeedbackCreated($feedback));

        return $feedback;
    });
}

4. Listener (app/Specifics/FeedbackHub/Listeners/SendFeedbackNotification.php) :

public function handle(FeedbackCreated $event)
{
    // Envoyer une notification aux admins
    CreateNotificationAction::execute(...);
}

Prêt à développer ?

Suivez ces modes opératoires pour créer de nouvelles fonctionnalités de manière cohérente et maintenable. N'hésitez pas à consulter les modules existants comme référence.

Prendre rendez-vous