Phase 10: Per-User Rate Limits — messages + tokens, quota UI, admin usage
Backend:
- max_ai_messages_per_day + max_ai_tokens_per_day on User model (nullable, override)
- Migration 008: add columns + seed default settings (100 msgs, 500K tokens)
- usage_service: count today's messages + tokens, check quota, get limits
- GET /chats/quota returns usage vs limits + reset time
- POST /chats/{id}/messages checks quota before streaming (429 if exceeded)
- Admin user schemas expose both limit fields
- GET /admin/usage returns per-user daily message + token counts
- admin_user_service allows updating both limit fields
Frontend:
- Chat header shows "X/Y messages · XK/YK tokens" with red highlight at limit
- Quota refreshes every 30s via TanStack Query
- Admin usage page with table: user, messages today, tokens today
- Route + sidebar entry for admin usage
- English + Russian translations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,7 +39,8 @@
|
||||
"skills": "Skills",
|
||||
"personal_context": "My Context",
|
||||
"pdf": "PDF Reports",
|
||||
"pdf_templates": "Templates"
|
||||
"pdf_templates": "Templates",
|
||||
"usage": "Usage"
|
||||
},
|
||||
"dashboard": {
|
||||
"welcome": "Welcome, {{name}}",
|
||||
@@ -56,7 +57,9 @@
|
||||
"unarchive": "Unarchive",
|
||||
"delete_confirm": "Are you sure you want to delete this chat?",
|
||||
"limit_reached": "Chat limit reached",
|
||||
"streaming": "AI is thinking..."
|
||||
"streaming": "AI is thinking...",
|
||||
"quota_messages": "{{used}}/{{limit}} messages",
|
||||
"quota_tokens": "{{used}}K/{{limit}}K tokens"
|
||||
},
|
||||
"admin": {
|
||||
"context_editor": "Primary Context Editor",
|
||||
@@ -197,6 +200,13 @@
|
||||
"default_max_chats": "Default Max Chats",
|
||||
"default_max_chats_desc": "Default chat limit for new users"
|
||||
},
|
||||
"admin_usage": {
|
||||
"title": "Usage Statistics",
|
||||
"user": "User",
|
||||
"messages": "Messages Today",
|
||||
"tokens": "Tokens Today",
|
||||
"no_data": "No usage data available."
|
||||
},
|
||||
"common": {
|
||||
"loading": "Loading...",
|
||||
"error": "An error occurred",
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
"skills": "Навыки",
|
||||
"personal_context": "Мой контекст",
|
||||
"pdf": "PDF отчёты",
|
||||
"pdf_templates": "Шаблоны"
|
||||
"pdf_templates": "Шаблоны",
|
||||
"usage": "Использование"
|
||||
},
|
||||
"dashboard": {
|
||||
"welcome": "Добро пожаловать, {{name}}",
|
||||
@@ -56,7 +57,9 @@
|
||||
"unarchive": "Разархивировать",
|
||||
"delete_confirm": "Вы уверены, что хотите удалить этот чат?",
|
||||
"limit_reached": "Достигнут лимит чатов",
|
||||
"streaming": "ИИ думает..."
|
||||
"streaming": "ИИ думает...",
|
||||
"quota_messages": "{{used}}/{{limit}} сообщений",
|
||||
"quota_tokens": "{{used}}K/{{limit}}K токенов"
|
||||
},
|
||||
"admin": {
|
||||
"context_editor": "Редактор основного контекста",
|
||||
@@ -197,6 +200,13 @@
|
||||
"default_max_chats": "Лимит чатов по умолчанию",
|
||||
"default_max_chats_desc": "Лимит чатов для новых пользователей"
|
||||
},
|
||||
"admin_usage": {
|
||||
"title": "Статистика использования",
|
||||
"user": "Пользователь",
|
||||
"messages": "Сообщения сегодня",
|
||||
"tokens": "Токены сегодня",
|
||||
"no_data": "Данных пока нет."
|
||||
},
|
||||
"common": {
|
||||
"loading": "Загрузка...",
|
||||
"error": "Произошла ошибка",
|
||||
|
||||
Reference in New Issue
Block a user