withCount(['apiKeys', 'usageLogs']); // Search if ($request->filled('search')) { $search = $request->search; $query->where(function ($q) use ($search) { $q->where('user_id', 'like', "%{$search}%") ->orWhere('alias', 'like', "%{$search}%"); }); } // Filter by status if ($request->filled('status')) { if ($request->status === 'active') { $query->active(); } elseif ($request->status === 'blocked') { $query->blocked(); } } // Sort $sortField = $request->get('sort', 'created_at'); $sortDirection = $request->get('direction', 'desc'); $query->orderBy($sortField, $sortDirection); $users = $query->paginate(20)->withQueryString(); return view('gateway-users.index', compact('users')); } /** * Show the form for creating a new gateway user. */ public function create() { $budgets = Budget::all(); return view('gateway-users.create', compact('budgets')); } /** * Store a newly created gateway user in storage. */ public function store(Request $request) { $validated = $request->validate([ 'alias' => 'nullable|string|max:255', 'budget_id' => 'nullable|exists:budgets,budget_id', 'metadata' => 'nullable|array', ]); // Generate unique user_id $userId = 'user_' . Str::random(16); $user = GatewayUser::create([ 'user_id' => $userId, 'alias' => $validated['alias'] ?? null, 'budget_id' => $validated['budget_id'] ?? null, 'spend' => 0, 'blocked' => false, 'metadata' => $validated['metadata'] ?? [], ]); return redirect() ->route('gateway-users.show', $user->user_id) ->with('success', 'Gateway User created successfully!'); } /** * Display the specified gateway user. */ public function show(string $userId) { $user = GatewayUser::with(['apiKeys', 'budget']) ->findOrFail($userId); // Get usage statistics for last 30 days $stats = $this->getUserStatistics($userId, 30); // Get recent logs $recentLogs = $user->usageLogs() ->with('apiKey') ->orderByDesc('timestamp') ->limit(50) ->get(); // Get daily usage for chart (last 30 days) $dailyUsage = $user->usageLogs() ->selectRaw('DATE(timestamp) as date, COUNT(*) as requests, SUM(cost) as cost, SUM(total_tokens) as tokens') ->where('timestamp', '>=', now()->subDays(30)) ->groupBy('date') ->orderBy('date') ->get(); return view('gateway-users.show', compact('user', 'stats', 'recentLogs', 'dailyUsage')); } /** * Show the form for editing the specified gateway user. */ public function edit(string $userId) { $user = GatewayUser::findOrFail($userId); $budgets = Budget::all(); return view('gateway-users.edit', compact('user', 'budgets')); } /** * Update the specified gateway user in storage. */ public function update(Request $request, string $userId) { $user = GatewayUser::findOrFail($userId); $validated = $request->validate([ 'alias' => 'nullable|string|max:255', 'budget_id' => 'nullable|exists:budgets,budget_id', 'metadata' => 'nullable|array', ]); $user->update($validated); return redirect() ->route('gateway-users.show', $user->user_id) ->with('success', 'Gateway User updated successfully!'); } /** * Remove the specified gateway user from storage. */ public function destroy(string $userId) { $user = GatewayUser::findOrFail($userId); // Delete associated API keys and usage logs $user->apiKeys()->delete(); $user->usageLogs()->delete(); $user->delete(); return redirect() ->route('gateway-users.index') ->with('success', 'Gateway User deleted successfully!'); } /** * Toggle block status of a gateway user. */ public function toggleBlock(string $userId) { $user = GatewayUser::findOrFail($userId); $user->blocked = !$user->blocked; $user->save(); $status = $user->blocked ? 'blocked' : 'unblocked'; return redirect() ->back() ->with('success', "User has been {$status} successfully!"); } /** * Bulk actions for gateway users. */ public function bulkAction(Request $request) { $validated = $request->validate([ 'action' => 'required|in:block,unblock,delete', 'user_ids' => 'required|array|min:1', 'user_ids.*' => 'exists:users,user_id', ]); $count = 0; switch ($validated['action']) { case 'block': GatewayUser::whereIn('user_id', $validated['user_ids']) ->update(['blocked' => true]); $count = count($validated['user_ids']); $message = "{$count} user(s) have been blocked successfully!"; break; case 'unblock': GatewayUser::whereIn('user_id', $validated['user_ids']) ->update(['blocked' => false]); $count = count($validated['user_ids']); $message = "{$count} user(s) have been unblocked successfully!"; break; case 'delete': foreach ($validated['user_ids'] as $userId) { $user = GatewayUser::find($userId); if ($user) { $user->apiKeys()->delete(); $user->usageLogs()->delete(); $user->delete(); $count++; } } $message = "{$count} user(s) have been deleted successfully!"; break; } return redirect() ->route('gateway-users.index') ->with('success', $message); } /** * Get user statistics for a given time period. */ private function getUserStatistics(string $userId, int $days) { return \App\Models\UsageLog::where('user_id', $userId) ->where('timestamp', '>=', now()->subDays($days)) ->selectRaw(' COUNT(*) as total_requests, SUM(prompt_tokens) as total_prompt_tokens, SUM(completion_tokens) as total_completion_tokens, SUM(total_tokens) as total_tokens, SUM(cost) as total_cost, AVG(total_tokens) as avg_tokens_per_request ') ->first(); } }