EcoLMS — внутренняя платформа для работы с контентом из медиа- и документных источников. Сейчас в репозитории уже реализован workflow генерации обучающих курсов, а для meetings добавлены backend API, схема БД, worker pipeline под SaluteSpeech и UI-раздел /meetings. Репозиторий организован как pnpm-монорепозиторий с четырьмя приложениями: web, api, worker и transcription-service.
- Workspace:
pnpm@10.12.4 - Frontend: Next.js
16.2.2, React19.2.4, TypeScript5, Tailwind CSS4, shadcn/ui,react-markdown - Backend API: NestJS
11, TypeScript,pgбез ORM,class-validator,class-transformer - Worker: Python,
psycopg,boto3,pypdf,python-docx,python-pptx,striprtf - Transcription service: Python
http.server,faster-whisper,boto3,ffmpeg - Infrastructure: PostgreSQL
16, Redis7, S3-compatible storage - LLM providers: OpenAI и OpenRouter
apps/web— UI на Next.js с App Router, включаяcoursesиmeetingsapps/api— NestJS API дляcourses,meetings, загрузок, задач, артефактов и health-checkapps/worker— фоновая обработка файлов, генерация этапов курса и pipeline модуляmeetingsapps/transcription-service— сервис транскрибации аудио и видеоdoc— предметная и инфраструктурная документацияdocker— Dockerfile для каждого сервиса
Browser
-> web (Next.js)
-> api (NestJS, /api/*)
-> PostgreSQL
-> Redis
-> S3-compatible storage
-> worker (Python)
-> transcription-service (Python + faster-whisper)
- Пользователь создаёт проект через
web. apiсоздаёт запись проекта и артефакты-заготовки для этапов:source_compiled,course_outline,course_content,course_test.- Для загрузки файлов
apiвыдаёт параметры multipart upload и signed URL для частей. - Файлы уходят напрямую в S3-compatible storage.
apiставит задачу в Redis-очередьecolms:processing-jobs.workerчитает задачу, скачивает файлы, извлекает текст или транскрибирует аудио/видео, затем вызывает OpenAI/OpenRouter.- Результаты этапов сохраняются в PostgreSQL как артефакты
mdиjson. webпоказывает статус проекта, историю задач и позволяет редактировать Markdown-артефакты.
- один экран-дашборд для списка проектов и карточки проекта;
- отдельный экран
/meetingsв двухпанельной компоновке: список встреч слева, результаты обработки справа; - редактор промптов вынесен на отдельную страницу
/promptsи доступен из LMS иmeetings; - добавление новой записи встречи прямо из
/meetings: создать карточку, загрузить один файл и сразу запустить обработку; - в
meetingsи LMS используется единый паттерн уведомлений: компактные toast-like alerts в правом нижнем углу; - экран
meetingsпоказывает доступностьLLM,SaluteSpeech, баз данных и фоновых модулей через health badge, как в LMS; - в левом списке встреч есть меню
...с действиямиИнформацияиУдалить; - в хедере экрана
/meetingsесть кнопка возврата к основному интерфейсу LMS; - по пункту
ИнформацияоткрываетсяSheetс техническими деталями,jobsи артефактами; - markdown для встречи содержит только человекочитаемые разделы: саммари, протокол и поручения;
- загрузка до 5 файлов;
- поддержка документов, аудио и видео;
- запуск генерации отдельных этапов и цепочки этапов;
- просмотр и редактирование Markdown-артефактов;
- proxy-route для запросов к backend: apps/web/src/app/api/[...path]/route.ts;
- proxy-route для
PUTзагрузки в S3 по signed URL: apps/web/src/app/api/s3-upload/route.ts.
- глобальный префикс маршрутов:
/api; - контроллеры:
projects,uploads,jobs,artifacts,health,prompts; - health-check агрегирует статус
api,postgres,redis,llm,salutespeech,worker,transcription-service; - хранение и миграция минимальной схемы БД выполняются прямо из
PostgresService; - таблица
llm_promptsхранит редактируемые prompt templates дляlmsиmeetings; - очередь реализована через Redis list, без BullMQ;
- presigned URL для S3 формируются собственным кодом, без AWS SDK.
- обработка очереди из Redis;
- скачивание исходников из S3;
- извлечение текста из
pdf,docx,pptx,rtf,txt; - вызов transcription-service для аудио/видео;
- генерация
source_compiled,course_outline,course_content,course_test; - вызов только одного выбранного LLM-провайдера (
OpenAIилиOpenRouter) поLLM_PRIMARY_PROVIDER. - ошибки
quota / balance / payment requiredот LLM иSaluteSpeechнормализуются в человекочитаемый текст для UI и job logs. - prompt templates для
lmsиmeetingsчитаются из PostgreSQL (llm_prompts), а встроенные prompt definitions используются как seed по умолчанию.
- HTTP API на встроенном
HTTPServer; - endpoint
GET /health; - endpoint
POST /transcribe; - загрузка источника из S3, URL или локального пути;
- нормализация аудио через
ffmpegв16kHz mono wav; - транскрибация через
faster-whisper.
Актуальные маршруты и схема данных описаны в:
- doc/Документация_для_заказчика.md
- doc/API_описание.md
- doc/DB_схема.md
- doc/Архитектура_AI_ассистент_для_создания_обучающих_курсов.md
- doc/Модуль_встреч.md
Для нового модуля meetings уже зафиксированы и частично реализованы такие решения:
- отдельный bounded context, не смешанный с workflow курсов;
- язык встреч в V1: только русский;
- один файл на встречу;
- целевой провайдер распознавания и диаризации:
SaluteSpeech; - канонический результат хранится в PostgreSQL, а сырой ответ провайдера сохраняется в
job result_json; - ручная правка speaker labels предусмотрена в UI и модели данных;
- UI-раздел
/meetingsуже добавлен и показывает список встреч, карточку встречи и единый markdown-файл.
Что уже есть в backend:
- таблицы
meetings,meeting_source_files,meeting_upload_sessions,meeting_jobs,meeting_speakers,meeting_speaker_segments,meeting_artifacts; - REST-маршруты
/api/meetings/*; - отдельная Redis-очередь
ecolms:meeting-jobs; - worker pipeline
audio_prepared -> transcript_compiled -> meeting_summary -> meeting_protocol -> meeting_actions; - интеграция worker с
SaluteSpeechчерез async API и нормализацию diarized transcript в PostgreSQL.
- Создать
.envна основе.env.example. - Установить зависимости:
pnpm install. - Поднять локальные
Postgres + Redis:pnpm dev:infra:up. - Запустить API:
pnpm dev:api. - Запустить web:
pnpm dev:web. - При необходимости запустить transcription service:
pnpm dev:transcription. - При необходимости запустить worker:
pnpm dev:worker.
Примечание: pnpm dev:worker использует uv и зависимости из apps/worker/pyproject.toml, а для обработки встреч meetings worker требует доступный ffmpeg.
pnpm dev— webpnpm dev:web— webpnpm dev:api— apipnpm dev:worker— workerpnpm dev:transcription— transcription-servicepnpm build— buildweb+apipnpm lint— lintwebpnpm docker:up— поднять стек через Docker Composepnpm docker:down— остановить стек
Ключевые переменные:
ECOLMS_API_BASE_URLPOSTGRES_URLREDIS_URLS3_ENDPOINTS3_BUCKETS3_REGIONS3_ACCESS_KEY_IDS3_SECRET_ACCESS_KEYOPENAI_API_KEYOPENROUTER_API_KEYLLM_PRIMARY_PROVIDEROPENAI_MODELOPENROUTER_MODELLLM_TIMEOUT_SECONDSTRANSCRIPTION_SERVICE_URLWHISPER_MODEL_SIZEWHISPER_COMPUTE_TYPEWORKER_JOB_QUEUE_KEYWORKER_MEETING_JOB_QUEUE_KEYSALUTESPEECH_AUTH_KEYSALUTESPEECH_OAUTH_URLSALUTESPEECH_REST_URLSALUTESPEECH_UPLOAD_URLSALUTESPEECH_RECOGNIZE_URLSALUTESPEECH_TASK_URLSALUTESPEECH_DOWNLOAD_URLSALUTESPEECH_SCOPESALUTESPEECH_MODELSALUTESPEECH_LANGUAGESALUTESPEECH_CA_CERT_PATHSALUTESPEECH_SSL_NO_VERIFYSALUTESPEECH_POLL_INTERVAL_SECONDSSALUTESPEECH_TIMEOUT_SECONDS
Для обратной совместимости api и worker также понимают старые алиасы SBER_*
и могут собрать OAuth Basic key из SBER_CLIENT_ID + SBER_CLIENT_SECRET, если
SALUTESPEECH_AUTH_KEY не задан.
SALUTESPEECH_AUTH_KEY допускает три формата: готовый base64, строку
client_id:client_secret или значение с префиксом Basic .
Если используется SALUTESPEECH_CA_CERT_PATH=certs/russiantrustedca.pem, каталог
certs/ должен быть скопирован в runtime-образ worker, иначе этап
transcript_compiled завершится системной ошибкой [Errno 2] No such file or directory.
Полный пример находится в .env.example.