Эх сурвалжийг харах

feat: add ResolveActiveUnit middleware and ResolvesActiveUnit trait

- ResolveActiveUnit middleware reads X-Unit-Id header, validates
  unit ownership, and merges active_unit_id into the request
- ResolvesActiveUnit trait provides activeUnitId() helper for controllers
- Apply ResolveActiveUnit to all auth:sanctum routes
ebagabee 2 долоо хоног өмнө
parent
commit
6bb046d58d

+ 28 - 0
app/Http/Controllers/Concerns/ResolvesActiveUnit.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Http\Controllers\Concerns;
+
+use App\Models\User;
+use Illuminate\Support\Facades\Auth;
+
+/**
+ * Fornece um helper para obter o ID da unidade ativa da request.
+ *
+ * O middleware ResolveActiveUnit valida o header X-Unit-Id e injeta
+ * 'active_unit_id' na request quando o usuário possui múltiplas unidades
+ * e selecionou uma específica no frontend.
+ * Se nenhuma unidade estiver selecionada, retorna a primeira unidade do usuário.
+ */
+trait ResolvesActiveUnit
+{
+    protected function activeUnitId(?User $user = null): ?int
+    {
+        $fromRequest = request()->input('active_unit_id');
+        if ($fromRequest) {
+            return (int) $fromRequest;
+        }
+
+        $user = $user ?? Auth::user()?->loadMissing('units');
+        return $user?->units->first()?->id;
+    }
+}

+ 34 - 0
app/Http/Middleware/ResolveActiveUnit.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Symfony\Component\HttpFoundation\Response;
+
+class ResolveActiveUnit
+{
+    /**
+     * Lê o header X-Unit-Id enviado pelo frontend, valida que a unidade
+     * pertence ao usuário autenticado e disponibiliza como active_unit_id
+     * na request para que os serviços possam usá-la ao filtrar dados.
+     */
+    public function handle(Request $request, Closure $next): Response
+    {
+        $unitId = $request->header('X-Unit-Id');
+
+        if ($unitId && Auth::check()) {
+            $user = Auth::user();
+            $user->loadMissing('units');
+
+            $validUnit = $user->units->firstWhere('id', (int) $unitId);
+
+            if ($validUnit) {
+                $request->merge(['active_unit_id' => $validUnit->id]);
+            }
+        }
+
+        return $next($request);
+    }
+}

+ 1 - 1
routes/api.php

@@ -9,7 +9,7 @@
     }
 });
 
-Route::middleware(['auth:sanctum', 'ability:access'])->group(function () {
+Route::middleware(['auth:sanctum', 'ability:access', \App\Http\Middleware\ResolveActiveUnit::class])->group(function () {
     $authRoutes = glob(__DIR__ . "/authRoutes/*.php");
     foreach ($authRoutes as $authRoute) {
         Route::group([], $authRoute);