system: AI-провайдеры + блок «Расход AI»
* components/SystemSettings.js: добавлен компонент UsageSummary сверху — сводка вызовов и стоимости с переключателем периода (Сегодня/Неделя/ Месяц/Всё) и группировкой (по сервису/провайдеру/модели). Виджеты cost_rub/calls/tokens/images + таблица breakdown. * components/SystemSettings.js: в массив CATEGORIES добавлена категория 'ai_providers' первой — Aleksei видит все 11 строк (Текст/Картинки ключи+URL+модели + AI_USD_RUB_RATE + AI_PROVIDER_MARKUP) сверху. Существующая инфраструктура SettingRow (маскировка секретов, save+toast) переиспользуется без изменений. * lib/engine.js: добавлены engine.usageSummary(params) и engine.usageRecent(limit). * app/api/admin/usage/summary/route.js (новый): прокси-роут к engine /api/usage/summary через requireAdmin. Verify: * next build прошёл без ошибок. * /system → 307 redirect на /login (неавторизованный — корректно). * /api/admin/usage/summary → 403 Forbidden (не-админ — корректно).
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { requireAdmin } from '@/lib/session';
|
||||
import { engine } from '@/lib/engine';
|
||||
|
||||
// GET /api/admin/usage/summary?range=today&group_by=service
|
||||
export async function GET(req) {
|
||||
const admin = await requireAdmin();
|
||||
if (!admin) return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
|
||||
try {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const params = {};
|
||||
if (searchParams.get('range')) params.range = searchParams.get('range');
|
||||
if (searchParams.get('group_by')) params.group_by = searchParams.get('group_by');
|
||||
if (searchParams.get('service')) params.service = searchParams.get('service');
|
||||
const data = await engine.usageSummary(params);
|
||||
return NextResponse.json(data);
|
||||
} catch (err) {
|
||||
return NextResponse.json({ error: err.message }, { status: err.status || 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user