Aller au contenu principal

Golden Workflow

Le Golden Workflow est le flux de traitement obligatoire pour toute requête dans le projet.

Route
→ Middleware (auth, permissions, rate-limit)
→ Form Request (validation des entrées)
→ Policy (autorisation)
→ Controller (orchestration mince)
→ Service (logique métier)
→ Repository / Model (persistance)
→ Event / Log (audit, effets de bord)
→ Resource / View (formatage de la réponse)
→ Response

Détail de chaque couche

Route

  • Appartient au module
  • Nom stable (routes, menus, permissions peuvent en dépendre)
  • Middleware appliqué au niveau du groupe

Middleware

  • Authentification (Keycloak ou API key)
  • Vérifications d'accès générales
  • Rate limiting si nécessaire

Form Request

  • Valide toutes les entrées externes
  • Peut contenir authorize() basique
  • Ne contient pas de logique métier

Policy

  • Autorisation model-spécifique
  • Appelée via $this->authorize() dans le contrôleur
  • Toujours côté serveur — jamais uniquement côté vue

Controller

  • Mince — max quelques lignes par action
  • Appelle le service
  • Retourne la réponse

Service

  • Toute la logique métier
  • Transactions pour les opérations multi-write
  • try/catch pour les workflows sensibles
  • Logs sur les états critiques

Repository / Model

  • Persistance et accès aux données
  • Scopes Eloquent réutilisables
  • Relations explicites avec clés id_*

Event / Log

  • Événements pour les changements de domaine significatifs
  • Logs d'audit obligatoires pour les actions sensibles
  • Listeners en queue pour les effets de bord lents

Response

  • Vue Blade, redirection, JSON ou Resource API
  • Jamais de logique métier dans la vue
  • Données préparées par le contrôleur ou le service

Exemple complet

// Route
Route::put('users/{user}', [UserController::class, 'update'])
->middleware(['web', 'keycloak.auth'])
->name('admin.users.update');

// Form Request
class UpdateUserRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:150'],
'id_role' => ['required', 'integer', 'exists:roles,id_role'],
'is_active' => ['boolean'],
];
}
}

// Controller
public function update(UpdateUserRequest $request, User $user): RedirectResponse
{
$this->authorize('update', $user); // Policy
$this->userService->update($user, $request->validated()); // Service
return redirect()->route('admin.users.edit', $user)
->with('success', 'Utilisateur mis à jour.');
}

// Service
public function update(User $user, array $data): User
{
return DB::transaction(function () use ($user, $data): User {
$user->fill($data)->save();
Log::info('User updated', ['id_user' => $user->id_user]);
return $user;
});
}