feat: полный бэк и фронт (попытки, разбор, импорт, ИИ, назначения)

- Сервисы: testAttemptService, testAccess, document import/gen/extract, LLM, assignment, aiEditor
- Конфиг: devAuthor, featureFlags; messages/ru; интеграция V.9 (skip без БД)
- API/роуты: app, auth, server; Dockerfile и env example
- Фронт: TestAttempt, TestAttemptReview, AttemptReviewBlock, стили, правки App/api/login/vite
- compose и README; смоук-тесты расширены

Закрывает отсутствие модулей в origin после клона.

Made-with: Cursor
This commit is contained in:
Константин Лебединский
2026-04-24 22:55:15 +05:00
parent a68331c86b
commit 0fe04d4d99
38 changed files with 3683 additions and 491 deletions
+41
View File
@@ -0,0 +1,41 @@
/** Тексты ответов API для пользователей (русский). */
export const RU = {
loginAndPasswordRequired: 'Укажите логин и пароль.',
invalidCredentials: 'Неверный логин или пароль.',
useHrLogin: 'Войдите через учётную запись кадровой системы (тот же логин, что в HR).',
hrDatabaseUrlMissing:
'База кадровой системы не настроена: задайте HR_DATABASE_URL на backend.',
hrDatabaseNotConfigured: 'База кадровой системы не настроена.',
noStaffForLogin:
'К учётной записи не привязан сотрудник: в HR в карточке сотрудника должно совпадать поле веб-логина (web_login) с логином входа, как в кабинете сотрудника.',
loggedOut: 'Вы вышли из системы.',
logoutFailed: 'Не удалось выйти. Повторите попытку.',
userDataFailed: 'Не удалось загрузить данные пользователя.',
loginFailed: 'Ошибка входа. Повторите попытку.',
authRequired: 'Требуется вход в систему.',
tokenInvalid: 'Сессия истекла или недействительна. Войдите снова.',
userNotFound: 'Пользователь не найден.',
authError: 'Ошибка проверки доступа.',
insufficientPermissions: 'Недостаточно прав.',
departmentAccessDenied: 'Нет доступа к этому подразделению.',
notFound: 'Не найдено.',
fileFieldRequired: 'Прикрепите файл к полю file.',
uploadFailed: 'Не удалось принять файл.',
titleRequired: 'Укажите название.',
assignmentUserRequired: 'Передайте userId (UUID) или staffId (число, сотрудник из HR).',
assignmentUserOrStaff: 'Укажите только userId, или только staffId — не оба сразу.',
testNotFound: 'Тест не найден.',
forbidden: 'Доступ запрещён.',
versionNotFound: 'Версия не найдена.',
chainActiveRequired: 'Передайте chainActive: true/false в теле запроса.',
noActiveVersion: 'Нет активной версии теста.',
internal: 'Внутренняя ошибка сервера.',
fileTooLarge: 'Файл слишком большой (максимум 10 МБ).',
unsupportedFileType:
'Неподдерживаемый формат. Допустимы: PDF, DOCX, TXT, MD.',
attemptNotFound: 'Попытка не найдена.',
attemptNotInProgress: 'Попытка уже завершена или просрочена.',
attemptNotCompleted: 'Попытка ещё не завершена — подробный разбор доступен после отправки ответов.',
testHasNoQuestions: 'В активной версии нет вопросов. Добавьте вопросы и сохраните черновик.',
invalidOptionForQuestion: 'Выбран вариант ответа, не относящийся к вопросу.',
};