validate([ 'email' => 'required|email', 'password' => 'required', 'device' => 'sometimes|string|max:80', ]); $tenant = app(TenantManager::class)->current(); if (! $tenant) { throw ValidationException::withMessages([ 'email' => 'Tenant subdomain required.', ]); } $user = User::where('email', $request->email)->first(); if (! $user || ! Hash::check($request->password, $user->password)) { throw ValidationException::withMessages([ 'email' => 'Invalid credentials.', ]); } if ($user->company_id !== $tenant->id) { throw ValidationException::withMessages([ 'email' => 'User does not belong to this tenant.', ]); } if ($user->status !== 'active') { throw ValidationException::withMessages([ 'email' => 'Account inactive.', ]); } $token = $user->createToken($request->input('device', 'api'))->plainTextToken; return response()->json([ 'token' => $token, 'user' => [ 'id' => $user->id, 'name' => $user->name, 'email' => $user->email, 'role' => $user->role, ], 'tenant' => [ 'slug' => $tenant->slug, 'name' => $tenant->display_name ?? $tenant->name, ], ]); } public function me(Request $request): JsonResponse { $u = $request->user(); return response()->json([ 'id' => $u->id, 'name' => $u->name, 'email' => $u->email, 'role' => $u->role, 'tenant_slug' => app(TenantManager::class)->current()?->slug, ]); } public function logout(Request $request): JsonResponse { $request->user()->currentAccessToken()->delete(); return response()->json(['ok' => true]); } }