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;
});
}