104 lines
3.3 KiB
PHP
104 lines
3.3 KiB
PHP
<?php
|
|
/**
|
|
* AI Usage Stats Endpoint
|
|
* GET /api/v1/ai-usage/stats
|
|
*
|
|
* Returns AI token consumption stats for the current tenant.
|
|
* Super admin sees system-wide; admin sees their tenant only.
|
|
*/
|
|
|
|
use App\Core\Database;
|
|
use App\Middleware\RoleMiddleware;
|
|
|
|
$decoded = RoleMiddleware::require(['super_admin', 'admin']);
|
|
|
|
$db = Database::getInstance();
|
|
|
|
$period = $_GET['period'] ?? 'month'; // day, week, month, all
|
|
$tenantId = $decoded['tenant_id'];
|
|
$isSuperAdmin = $decoded['role'] === 'super_admin';
|
|
|
|
// Date range
|
|
$dateCondition = match ($period) {
|
|
'day' => "AND a.created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)",
|
|
'week' => "AND a.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)",
|
|
'month' => "AND a.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)",
|
|
default => "",
|
|
};
|
|
|
|
$tenantCondition = $isSuperAdmin ? "" : "AND a.tenant_id = ?";
|
|
$params = $isSuperAdmin ? [] : [$tenantId];
|
|
|
|
// Totals
|
|
$sql = "SELECT
|
|
COUNT(*) as total_requests,
|
|
COALESCE(SUM(a.prompt_tokens), 0) as total_prompt_tokens,
|
|
COALESCE(SUM(a.completion_tokens), 0) as total_completion_tokens,
|
|
COALESCE(SUM(a.total_tokens), 0) as total_tokens,
|
|
COALESCE(SUM(a.estimated_cost), 0) as total_cost
|
|
FROM ai_usage_log a
|
|
WHERE 1=1 $tenantCondition $dateCondition";
|
|
|
|
$stmt = $db->prepare($sql);
|
|
$stmt->execute($params);
|
|
$totals = $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
|
|
// Breakdown by action type
|
|
$sql2 = "SELECT
|
|
a.action_type,
|
|
COUNT(*) as requests,
|
|
COALESCE(SUM(a.total_tokens), 0) as tokens,
|
|
COALESCE(SUM(a.estimated_cost), 0) as cost
|
|
FROM ai_usage_log a
|
|
WHERE 1=1 $tenantCondition $dateCondition
|
|
GROUP BY a.action_type
|
|
ORDER BY tokens DESC";
|
|
|
|
$stmt2 = $db->prepare($sql2);
|
|
$stmt2->execute($params);
|
|
$breakdown = $stmt2->fetchAll(\PDO::FETCH_ASSOC);
|
|
|
|
// Breakdown by model
|
|
$sql3 = "SELECT
|
|
a.model_name,
|
|
COUNT(*) as requests,
|
|
COALESCE(SUM(a.total_tokens), 0) as tokens,
|
|
COALESCE(SUM(a.estimated_cost), 0) as cost
|
|
FROM ai_usage_log a
|
|
WHERE 1=1 $tenantCondition $dateCondition
|
|
GROUP BY a.model_name
|
|
ORDER BY tokens DESC";
|
|
|
|
$stmt3 = $db->prepare($sql3);
|
|
$stmt3->execute($params);
|
|
$modelBreakdown = $stmt3->fetchAll(\PDO::FETCH_ASSOC);
|
|
|
|
// Daily trend (last 30 days)
|
|
$sql4 = "SELECT
|
|
DATE(a.created_at) as date,
|
|
COALESCE(SUM(a.total_tokens), 0) as tokens,
|
|
COALESCE(SUM(a.estimated_cost), 0) as cost,
|
|
COUNT(*) as requests
|
|
FROM ai_usage_log a
|
|
WHERE 1=1 $tenantCondition AND a.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
|
|
GROUP BY DATE(a.created_at)
|
|
ORDER BY date ASC";
|
|
|
|
$stmt4 = $db->prepare($sql4);
|
|
$stmt4->execute($params);
|
|
$dailyTrend = $stmt4->fetchAll(\PDO::FETCH_ASSOC);
|
|
|
|
json_success([
|
|
'period' => $period,
|
|
'totals' => [
|
|
'requests' => (int) $totals['total_requests'],
|
|
'prompt_tokens' => (int) $totals['total_prompt_tokens'],
|
|
'completion_tokens' => (int) $totals['total_completion_tokens'],
|
|
'total_tokens' => (int) $totals['total_tokens'],
|
|
'estimated_cost_usd' => round((float) $totals['total_cost'], 4),
|
|
],
|
|
'by_action' => $breakdown,
|
|
'by_model' => $modelBreakdown,
|
|
'daily_trend' => $dailyTrend,
|
|
]);
|