feat(feedback): personal AI models, AI run tracking and profiles/options endpoint

- user_settings allowlist: feedback_models (up to 10 personal model configs)
- normalizeFeedbackModels() validation, UI block "Мои модели" in #fbPromptModal
- GET /api/ai/profiles/options for tutors (no api_key), used by feedback/shorts
- feedbacks columns ai_prompt/ai_model/ai_duration_ms + backup/restore support
- "ИИ-запрос" popover on feedback card with status, model, timing and prompt
- audit: feedback.update / feedback.ai.run / feedback.ai.error labels
This commit is contained in:
dev
2026-10-07 16:30:27 +03:00
parent a73b1b3f8c
commit a9fb7aaf77
13 changed files with 522 additions and 85 deletions
+9
View File
@@ -1873,6 +1873,14 @@ off = parseInt(offset, 10); if (off > 0) { OFFSET $n }
- **Ошибки:** 401/403 — от `requireAdmin`
- **Примечания:** профили лежат в `settings.ai_profiles` как JSON-массив (`getAiProfiles()`); `api_key` профиля возвращается в ответе (см. «?»)
### `GET /api/ai/profiles/options`
- **Доступ:** `requireAuth` — любой авторизованный пользователь, включая тьютора; **филиалы:** не применимо
- **Тело:** нет
- **Ответ 200:** `{ active, native: { id:'native', name:'Нативная (llama.cpp в Docker)', model: AI_MODEL }, profiles: [{ id, name, model }] }` — **без** `base_url` и `api_key`
- **Ошибки:** 401 — от `requireAuth`
- **Примечания:** лёгкий вариант `GET /api/ai/profiles` для наполнения селектов моделей на страницах, доступных тьюторам (`public/js/feedback.js` → `loadAiProfiles()`, `public/js/shorts.js` → `openShortsAi()`). Полная версия остаётся `requireAdmin`, потому что в ней отдаётся `api_key`; не заменяйте её в админ-формах
### `POST /api/ai/profiles`
- **Доступ:** `requireAdmin`; **филиалы:** не применимо
@@ -2547,6 +2555,7 @@ off = parseInt(offset, 10); if (off > 0) { OFFSET $n }
| `DELETE /api/entries/:id/photo/enhance-ai/preview` | 34. |
| `POST /api/ai/correct` | 35. |
| `GET /api/ai/profiles` | 35. |
| `GET /api/ai/profiles/options` | 35. |
| `POST /api/ai/profiles` | 35. |
| `PUT /api/ai/profiles/:id` | 35. |
| `DELETE /api/ai/profiles/:id` | 35. |