diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index c2d6b31..0000000 --- a/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -FROM python:3.13-slim as base - -WORKDIR /app - -COPY pyproject.toml ./ -COPY src/ ./src/ - -ARG VERSION=0.0.0+docker -ENV SETUPTOOLS_SCM_PRETEND_VERSION="${VERSION}" - -RUN pip install --no-cache-dir --upgrade pip && \ - pip install --no-cache-dir .[all,gateway] - -RUN useradd -m -u 1000 gateway && \ - chown -R gateway:gateway /app - -USER gateway - -EXPOSE 8000 - -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1 - -ENV GATEWAY_HOST=0.0.0.0 -ENV GATEWAY_PORT=8000 - -CMD ["any-llm-gateway", "serve"] diff --git a/LARAVEL_IMPLEMENTATION.md b/LARAVEL_IMPLEMENTATION.md deleted file mode 100644 index f750868..0000000 --- a/LARAVEL_IMPLEMENTATION.md +++ /dev/null @@ -1,1330 +0,0 @@ -# Laravel Verwaltungsoberfläche für Any-LLM Gateway -## Implementierungskonzept - ---- - -## 1. Projekt-Übersicht - -### 1.1 Ziel -Vollständige Laravel-Verwaltungsoberfläche für das Any-LLM Gateway mit: -- Benutzer-Login und Authentifizierung -- Dashboard mit Statistiken und Analysen -- Verwaltung von Users, API Keys, Budgets -- Detaillierte Nutzungsberichte -- Monitoring und Alerts - -### 1.2 Tech Stack -- **Backend**: Laravel 11.x -- **Frontend**: Livewire 3.x + Alpine.js + Tailwind CSS -- **Charts**: Chart.js / ApexCharts -- **Datenbank**: PostgreSQL (existing Gateway DB) -- **Authentication**: Laravel Breeze mit Livewire - ---- - -## 2. Datenbankstruktur (Existing Gateway DB) - -### 2.1 Tabellen-Übersicht - -``` -┌─────────────────┐ -│ users │ ← Gateway Users (API Consumers) -└────────┬────────┘ - │ - ┌────┴────┬─────────────┬──────────────┐ - │ │ │ │ -┌───▼────┐ ┌─▼────────┐ ┌──▼───────┐ ┌──▼──────────┐ -│api_keys│ │usage_logs│ │ budgets │ │budget_reset │ -└────────┘ └──────────┘ └──────────┘ │ _logs │ - └─────────────┘ -``` - -### 2.2 Tabellen-Details - -#### `users` - Gateway API Users -```sql -- user_id (PK) VARCHAR -- alias VARCHAR -- spend DOUBLE -- budget_id (FK) VARCHAR -- blocked BOOLEAN -- created_at TIMESTAMP -- updated_at TIMESTAMP -- metadata JSON -- budget_started_at TIMESTAMP -- next_budget_reset_at TIMESTAMP -``` - -#### `api_keys` - Virtual Keys -```sql -- id (PK) VARCHAR -- key_hash VARCHAR (UNIQUE) -- key_name VARCHAR -- user_id (FK) VARCHAR -- created_at TIMESTAMP -- last_used_at TIMESTAMP -- expires_at TIMESTAMP -- is_active BOOLEAN -- metadata JSON -``` - -#### `usage_logs` - Request Tracking -```sql -- id (PK) VARCHAR -- api_key_id (FK) VARCHAR -- user_id (FK) VARCHAR -- timestamp TIMESTAMP (INDEXED) -- model VARCHAR -- provider VARCHAR -- endpoint VARCHAR -- prompt_tokens INT -- completion_tokens INT -- total_tokens INT -- cost DOUBLE -- status VARCHAR -- error_message VARCHAR -``` - -#### `budgets` - Budget Definitions -```sql -- budget_id (PK) VARCHAR -- max_budget DOUBLE -- created_at TIMESTAMP -- updated_at TIMESTAMP -- budget_duration_sec INT -``` - -#### `model_pricing` - Model Costs -```sql -- model_key (PK) VARCHAR -- input_price_per_million DOUBLE -- output_price_per_million DOUBLE -- created_at TIMESTAMP -- updated_at TIMESTAMP -``` - ---- - -## 3. Laravel Projektstruktur - -### 3.1 Verzeichnisstruktur -``` -any-llm-admin/ -├── app/ -│ ├── Http/ -│ │ ├── Controllers/ -│ │ │ ├── DashboardController.php -│ │ │ ├── GatewayUserController.php -│ │ │ ├── ApiKeyController.php -│ │ │ ├── BudgetController.php -│ │ │ ├── UsageLogController.php -│ │ │ └── ModelPricingController.php -│ │ ├── Livewire/ -│ │ │ ├── Dashboard/ -│ │ │ │ ├── StatsOverview.php -│ │ │ │ ├── UsageChart.php -│ │ │ │ ├── TopUsers.php -│ │ │ │ └── RecentActivity.php -│ │ │ ├── GatewayUsers/ -│ │ │ │ ├── Index.php -│ │ │ │ ├── Create.php -│ │ │ │ ├── Edit.php -│ │ │ │ └── Show.php -│ │ │ ├── ApiKeys/ -│ │ │ │ ├── Index.php -│ │ │ │ ├── Create.php -│ │ │ │ └── Revoke.php -│ │ │ └── Budgets/ -│ │ │ ├── Index.php -│ │ │ ├── Create.php -│ │ │ └── Edit.php -│ │ └── Middleware/ -│ │ └── EnsureAdmin.php -│ ├── Models/ -│ │ ├── Admin.php (Laravel Auth User) -│ │ ├── GatewayUser.php (Gateway users table) -│ │ ├── ApiKey.php -│ │ ├── UsageLog.php -│ │ ├── Budget.php -│ │ ├── BudgetResetLog.php -│ │ └── ModelPricing.php -│ └── Services/ -│ ├── StatisticsService.php -│ ├── BudgetService.php -│ └── GatewayApiService.php -├── database/ -│ ├── migrations/ -│ │ └── 2025_11_15_000001_create_admins_table.php -│ └── seeders/ -│ └── AdminSeeder.php -├── resources/ -│ ├── views/ -│ │ ├── layouts/ -│ │ │ ├── app.blade.php -│ │ │ ├── navigation.blade.php -│ │ │ └── guest.blade.php -│ │ ├── dashboard.blade.php -│ │ ├── gateway-users/ -│ │ ├── api-keys/ -│ │ ├── budgets/ -│ │ ├── usage-logs/ -│ │ └── model-pricing/ -│ └── js/ -│ └── charts.js -└── routes/ - ├── web.php - └── api.php -``` - ---- - -## 4. Laravel Models - -### 4.1 Admin Model (Laravel Auth) -```php - 'datetime', - 'password' => 'hashed', - ]; -} -``` - -### 4.2 GatewayUser Model -```php - 'double', - 'blocked' => 'boolean', - 'metadata' => 'array', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - 'budget_started_at' => 'datetime', - 'next_budget_reset_at' => 'datetime', - ]; - - // Relationships - public function apiKeys() - { - return $this->hasMany(ApiKey::class, 'user_id', 'user_id'); - } - - public function usageLogs() - { - return $this->hasMany(UsageLog::class, 'user_id', 'user_id'); - } - - public function budget() - { - return $this->belongsTo(Budget::class, 'budget_id', 'budget_id'); - } - - public function budgetResetLogs() - { - return $this->hasMany(BudgetResetLog::class, 'user_id', 'user_id'); - } - - // Scopes - public function scopeActive($query) - { - return $query->where('blocked', false); - } - - public function scopeBlocked($query) - { - return $query->where('blocked', true); - } - - // Accessors - public function getSpendFormattedAttribute() - { - return '$' . number_format($this->spend, 2); - } - - public function getTotalRequestsAttribute() - { - return $this->usageLogs()->count(); - } - - public function getTotalTokensAttribute() - { - return $this->usageLogs()->sum('total_tokens'); - } -} -``` - -### 4.3 ApiKey Model -```php - 'boolean', - 'metadata' => 'array', - 'created_at' => 'datetime', - 'last_used_at' => 'datetime', - 'expires_at' => 'datetime', - ]; - - // Relationships - public function gatewayUser() - { - return $this->belongsTo(GatewayUser::class, 'user_id', 'user_id'); - } - - public function usageLogs() - { - return $this->hasMany(UsageLog::class, 'api_key_id', 'id'); - } - - // Scopes - public function scopeActive($query) - { - return $query->where('is_active', true) - ->where(function ($q) { - $q->whereNull('expires_at') - ->orWhere('expires_at', '>', now()); - }); - } - - public function scopeExpired($query) - { - return $query->whereNotNull('expires_at') - ->where('expires_at', '<=', now()); - } - - // Accessors - public function getMaskedKeyAttribute() - { - return 'gw-' . substr($this->id, 0, 8) . '...' . substr($this->id, -8); - } - - public function getIsExpiredAttribute() - { - return $this->expires_at && $this->expires_at->isPast(); - } -} -``` - -### 4.4 UsageLog Model -```php - 'datetime', - 'prompt_tokens' => 'integer', - 'completion_tokens' => 'integer', - 'total_tokens' => 'integer', - 'cost' => 'double', - ]; - - // Relationships - public function gatewayUser() - { - return $this->belongsTo(GatewayUser::class, 'user_id', 'user_id'); - } - - public function apiKey() - { - return $this->belongsTo(ApiKey::class, 'api_key_id', 'id'); - } - - // Scopes - public function scopeSuccess($query) - { - return $query->where('status', 'success'); - } - - public function scopeFailed($query) - { - return $query->where('status', '!=', 'success'); - } - - public function scopeToday($query) - { - return $query->whereDate('timestamp', today()); - } - - public function scopeDateRange($query, $start, $end) - { - return $query->whereBetween('timestamp', [$start, $end]); - } - - // Accessors - public function getCostFormattedAttribute() - { - return $this->cost ? '$' . number_format($this->cost, 4) : 'N/A'; - } -} -``` - -### 4.5 Budget Model -```php - 'double', - 'budget_duration_sec' => 'integer', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - ]; - - // Relationships - public function gatewayUsers() - { - return $this->hasMany(GatewayUser::class, 'budget_id', 'budget_id'); - } - - public function resetLogs() - { - return $this->hasMany(BudgetResetLog::class, 'budget_id', 'budget_id'); - } - - // Accessors - public function getMaxBudgetFormattedAttribute() - { - return '$' . number_format($this->max_budget, 2); - } - - public function getDurationHumanAttribute() - { - if (!$this->budget_duration_sec) return 'No limit'; - - $days = floor($this->budget_duration_sec / 86400); - $hours = floor(($this->budget_duration_sec % 86400) / 3600); - - return "{$days}d {$hours}h"; - } -} -``` - -### 4.6 ModelPricing Model -```php - 'double', - 'output_price_per_million' => 'double', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - ]; - - // Accessors - public function getInputPriceFormattedAttribute() - { - return '$' . number_format($this->input_price_per_million, 2) . '/M'; - } - - public function getOutputPriceFormattedAttribute() - { - return '$' . number_format($this->output_price_per_million, 2) . '/M'; - } -} -``` - ---- - -## 5. Services - -### 5.1 StatisticsService -```php - GatewayUser::count(), - 'active_users' => GatewayUser::active()->count(), - 'total_requests_today' => UsageLog::today()->count(), - 'total_spend_today' => UsageLog::today()->sum('cost'), - 'total_tokens_today' => UsageLog::today()->sum('total_tokens'), - ]; - } - - public function getUsageByProvider($days = 30) - { - return UsageLog::selectRaw('provider, COUNT(*) as count, SUM(cost) as total_cost') - ->where('timestamp', '>=', now()->subDays($days)) - ->groupBy('provider') - ->get(); - } - - public function getUsageByModel($days = 30) - { - return UsageLog::selectRaw('model, COUNT(*) as count, SUM(total_tokens) as tokens') - ->where('timestamp', '>=', now()->subDays($days)) - ->groupBy('model') - ->orderByDesc('count') - ->limit(10) - ->get(); - } - - public function getDailyUsageChart($days = 30) - { - return UsageLog::selectRaw('DATE(timestamp) as date, COUNT(*) as requests, SUM(cost) as cost') - ->where('timestamp', '>=', now()->subDays($days)) - ->groupBy('date') - ->orderBy('date') - ->get(); - } - - public function getTopUsers($limit = 10) - { - return GatewayUser::withCount('usageLogs') - ->withSum('usageLogs', 'cost') - ->orderByDesc('usage_logs_sum_cost') - ->limit($limit) - ->get(); - } - - public function getRecentActivity($limit = 20) - { - return UsageLog::with(['gatewayUser', 'apiKey']) - ->orderByDesc('timestamp') - ->limit($limit) - ->get(); - } - - public function getUserStatistics($userId, $days = 30) - { - $stats = 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(); - - return $stats; - } -} -``` - ---- - -## 6. Controllers - -### 6.1 DashboardController -```php -statsService->getDashboardStats(); - $dailyUsage = $this->statsService->getDailyUsageChart(30); - $topUsers = $this->statsService->getTopUsers(5); - $providerStats = $this->statsService->getUsageByProvider(30); - - return view('dashboard', compact( - 'stats', - 'dailyUsage', - 'topUsers', - 'providerStats' - )); - } -} -``` - -### 6.2 GatewayUserController -```php -withCount('apiKeys') - ->withCount('usageLogs') - ->paginate(20); - - return view('gateway-users.index', compact('users')); - } - - public function show($userId) - { - $user = GatewayUser::with(['apiKeys', 'budget']) - ->findOrFail($userId); - - $stats = $this->statsService->getUserStatistics($userId, 30); - $recentLogs = $user->usageLogs() - ->orderByDesc('timestamp') - ->limit(50) - ->get(); - - return view('gateway-users.show', compact('user', 'stats', 'recentLogs')); - } - - // ... weitere CRUD Methoden -} -``` - ---- - -## 7. Livewire Components - -### 7.1 Dashboard Stats Overview -```php -getDashboardStats(); - - return view('livewire.dashboard.stats-overview', [ - 'stats' => $stats - ]); - } - - public function refresh() - { - // Livewire will automatically re-render - } -} -``` - -### 7.2 Usage Chart Component -```php -getDailyUsageChart($this->days); - - return view('livewire.dashboard.usage-chart', [ - 'chartData' => $data - ]); - } - - public function updatedDays() - { - // Chart will automatically update - } -} -``` - ---- - -## 8. Views Structure - -### 8.1 Dashboard Layout -```blade - - - -
- - -