20 KiB
План проекта «Mospolytech MCP»
Команда: Деев Егор Викторович, Шмыговский Никита Сергеевич, Старков Руслан Владимирович (гр. 241–327).
Это наш рабочий план — не сдаём его никому, правим постоянно. Основан на
официальных методичках всех 8 лабораторных из СДО
(docs/sdo/) и на нашем техническом задании.
0. Важное уточнение
Предыдущая версия этого файла угадывала содержание лабораторных №2–8 (мы на тот момент их не видели) и придумала, что они про поэтапную разработку функций MCP-сервера — БД, потом инструменты, потом авторизация и т.д. Это оказалось неверно. Реальные методички описывают совсем другой курс — про DevOps-практики: виртуализацию, контейнеризацию, CI/CD, статический анализ, автотесты, миграции БД. Этот файл переписан заново по факту.
1. Два параллельных трека
Тут важно не путать две разные вещи:
- Продуктовый трек — сам MCP-сервер (то, что мы пишем в
src/). Он не привязан к номерам лабораторных — методички вообще не говорят, что конкретно писать и когда. Наша задача — держать его в рабочем состоянии, потому что начиная с ЛР2 он становится "объектом", который мы виртуализируем, контейнеризируем, гоняем через CI/CD, статически анализируем и тестируем. Без работающего прототипа лабораторные 2–8 выполнять физически не на чем. - Инфраструктурный трек — собственно 8 лабораторных. Это последовательность DevOps-практик, каждая следующая опирается на результат предыдущей (нельзя настроить CI, не имея Docker-образа; нельзя гонять автотесты в пайплайне, не имея пайплайна).
2. Логические этапы лабораторных (2–8)
Реальные лабораторные естественно группируются в 4 этапа — каждый следующий физически невозможен без результата предыдущего.
Этап А. Стенды (ЛР 2–3)
| ЛР | Тема | Что делаем |
|---|---|---|
| 2 | Виртуализация | Гипервизор, 3+ ВМ (test/stage/prod), объединяем в общую сеть (ping "от всех ко всем"), на test выкладываем проект через git, разворачиваем тулчейн, запускаем прототип |
| 3 | Контейнеризация | Docker на всех ВМ; Dockerfile для сборки и запуска приложения; docker-compose.yaml с приложением + БД/другим сервисом, volumes для сохранения данных между рестартами |
Итог этапа: на трёх ВМ поднята сеть, на test приложение собирается и запускается в Docker вместе с БД, данные переживают рестарт контейнера.
Этап Б. Конвейер CI/CD (ЛР 4–5)
| ЛР | Тема | Что делаем |
|---|---|---|
| 4 | Непрерывная интеграция | Пушим собранный образ в DockerHub; разворачиваем TeamCity server; заводим пользователей (по одному на каждого из нас); подключаем репозиторий; настраиваем сборку → образ → push в DockerHub для веток dev и prod |
| 5 | Непрерывная доставка | Добавляем шаг деплоя на stage из образа в DockerHub вместе с БД; разворачиваем TeamCity agent на test; переходим на GitFlow (или другую модель веток); feature-ветка → PR в dev с ревью от другого участника команды → после мержа сборка + автодеплой на stage |
Итог этапа: у нас настоящий CI/CD-конвейер — коммит в feature-ветку собирается, PR в dev требует ревью, после мержа приложение само уезжает на stage.
Этап В. Ворота качества в конвейере (ЛР 6–7)
| ЛР | Тема | Что делаем |
|---|---|---|
| 6 | Статический анализ кода | Минимум 2 анализатора (качество кода / безопасность / поиск секретов), шаги в пайплайне TeamCity — билд падает при находках максимальной критичности |
| 7 | Автоматизированное тестирование | Юнит + интеграционные тесты, покрытие ≥40% функционала из ТЗ; шаг тестирования в пайплайне для всех веток; демонстрация и провала, и прохождения на feature/dev/prod |
Итог этапа: код, который не проходит статический анализ или тесты, до stage/prod физически не доезжает — пайплайн его останавливает.
У нас тут есть fora — часть офлайн-тестов (tests/) уже написана заранее
(лк_api + open_api, 14 тестов). Они пригодятся напрямую в ЛР7, но 40% от
всего функционала ТЗ ими одними не наберём — MCP-сервера и слоя БД ещё нет,
их тоже придётся покрывать тестами.
Этап Г. Жизненный цикл базы данных в конвейере (ЛР 8)
| ЛР | Тема | Что делаем |
|---|---|---|
| 8 | Миграции БД | Директория со схемой БД в репозитории; статический анализатор безопасности SQL как шаг пайплайна; ручной, а затем автоматизированный деплой схемы на stage (со сверкой test/stage); отдельный prod-пайплайн с бэкапом БД перед изменениями |
Самая тяжёлая лабораторная — по сути весь этап Б, применённый отдельно к базе данных. Логично начинать только после того, как этапы А–В полностью стабильны, иначе непонятно, на чём проверять сверку схем.
3. Как отсюда следует планировать работу
Порядок такой, что физически нельзя пропустить шаг:
Прямо сейчасСделано — продуктовый трек: минимальный работающий MCP-сервер (server.pyповерхlk_api/open_api) + слой БД (SQLAlchemy-модели, первая миграция Alembic, реальный PostgreSQL на общем сервере команды). Один инструмент (list_groups, ФОД-001) уже реально ходит в кэш и обратно — то, что нужно было к ЛР2 (пункт "запустить прототип"). Подробности — раздел 6.- ЛР2 → ЛР3 — как только прототип есть, поднимаем стенды и контейнеризируем. Здесь же нужна настоящая БД в docker-compose — та, что мы придумали в разделе 4 ниже.
- ЛР4 → ЛР5 — пайплайн настраиваем один раз и дальше живём с ним постоянно: каждая следующая лабораторная (6, 7, 8) — это новые шаги в том же самом пайплайне, а не новый пайплайн с нуля.
- ЛР8 — в конце, когда схема БД уже не черновик, а что-то, что реально меняется по ходу разработки (иначе нечего мигрировать).
Отчёты по каждой лабораторной — отдельный текстовый документ со
скриншотами (см. задания в каждой методичке), кладём в docs/official/
рядом с ТЗ, по мере сдачи. Устная защита есть на каждой — со стороны
методичек 2–8 всегда есть блок "Вопросы для изучения", их надо реально
понимать, а не просто списать шаги.
3.1. По каким лабораторным двигаем функционал продукта, а где — фиксируем
Методички сами по себе не требуют конкретного объёма функций ни на одном шаге, кроме одного жёсткого места — ЛР7 требует покрытие тестами ≥40% функционала из ТЗ. Это и есть якорь, вокруг которого стоит планировать:
- До ЛР2 — сделано. MCP-сервер запускается и отвечает на ФОД-001
(
list_groups) черезopen_api. - Между ЛР2 и ЛР3 — тоже сделано. Слой БД (SQLAlchemy + Alembic) и
реальная запись — кэш списка групп (ФХД-003,
cache.py). Проверили живьём: 638 групп с rasp.dmami.ru легли вgroups_cacheна реальном PostgreSQL, повторный вызов идёт уже из кэша. Ровно то, что нужно для демонстрации в ЛР3 (записать → рестарт контейнера → данные на месте). Лог обращений к ЛК (ФХД-004) — кандидат на следующую функцию с записью, не обязательно прямо сейчас. - ЛР4–5 — основной спринт разработки функционала. Сами эти лабы не требуют нового кода продукта (там настраивается TeamCity и ветки), а значит это окно, где можно спокойно писать оставшиеся функции — ФЛК-001..007 целиком, оставшиеся ФОД, ФХД-001/002. Цель — закончить весь функционал раздела 4.2 ТЗ к концу ЛР5.
- ЛР6–7 — новый функционал не пишем, только фиксы. Это осознанное решение, а не жёсткое требование методичек: как только заработал статический анализ и тесты (этап В), любой новый код надо будет через них проводить, а переписывать тесты под ещё нестабильный функционал — двойная работа. Дешевле сначала закончить фичи (ЛР4-5), потом накрыть их готовыми тестами и спокойно поймать находки анализаторов. В ЛР7 40% покрытия наберётся без напряжения, раз к этому моменту реализовано фактически всё.
- ЛР8 — точечное изменение схемы, не новая фича. Заданию нужно, чтобы было что мигрировать (реальное изменение схемы БД + кода). Это может быть небольшая, специально приберёгнутая правка (например, добавить таблицу/поле под одну из уже реализованных функций) — не ради пользовательской ценности, а чтобы через неё честно продемонстрировать процесс миграции.
Если по ходу дела окажется, что часть функционала (раздел 4.2 ТЗ) реально не укладывается в ЛР4-5 по времени — переносим доделку на ЛР6-7 без проблем, план не жёсткий. Но если можем — лучше не тащить фиче-работу до последних лаб: чем раньше код "заморожен", тем меньше сюрпризов от анализаторов и тестов ближе к сдаче.
4. Продуктовый трек: черновая схема базы данных
Нужна к ЛР3 (для docker-compose) и будет меняться к ЛР8 (миграции), так что это живой черновик, не финал:
users— id, guid (из ЛК), login, отображаемое имя, created_atuser_sessions— user_id → legacy token, jwt, jwt_refresh, updated_at (пароль не хранится нигде и никогда — используется один раз при login)groups_cache,schedule_cache— справочные данные с TTL (ФХД-003)performance_history,payments_history,requests_history— append-only снимки (ФХД-002): каждое новое значение — новая строка, а не UPDATEnotifications— уведомления пользователя с внешним id для дедупликацииlk_access_log— user_id, action, status, created_at (ФХД-004; для открытого API строк не создаётся — ТЭ-001)
5. Открытые вопросы и риски (продуктовый трек)
- ФОД-003 (расписание преподавателя) фактически не доступно без
авторизации. Публичный
rasp.dmami.ru(на который опираетсяmospolytech_api) не имеет маршрута для поиска по преподавателю — мы проверили руками (site/teacherне существует,teachers-list.jsonотсутствует). Единственный найденный источник —getScheduleTeacherв лёгаси-API личного кабинета, требует авторизации и в самой Go-библиотеке MPU_LK_API помечен как неподтверждённый (🔎 в её API.md). Формально противоречит ТЭ-001 ("без авторизации"). Пока реализовано через ЛК-сессию как временное решение (LKClient.get_teacher_schedule). - ФЛК-007 (отправка сообщения) не имеет подтверждённого формата
запроса. Го-библиотека документирует действие только как
POST newMessage=1&<...>, реальные поля формы нигде не зафиксированы. Реализован best-effort вариант (LKClient.send_message, поляid+text) — надо проверить на реальном аккаунте перед тем, как полагаться на него. - ТСФ-003 (10 запросов/сек) пока не проверялось — станет актуальным, когда появится реальный MCP-сервер и нагрузочные тесты (перекликается с ЛР7, раздел про нагрузочное тестирование в теории, хотя оно явно не входит в задания).
6. Что уже сделано (продуктовый трек, заранее)
src/mospolytech_mcp/:
lk_api/— наш Python-порт Go-библиотеки MPU_LK_API (личный кабинет): авторизация (обе системы токенов), расписание, успеваемость, платежи, заявки, уведомления/объявления, диалоги, отправка сообщений (см. риски выше), плюсlk_get/lk_post_formкак escape hatch.open_api/— обёртка над вендореннойmospolytech_api(открытые данные: группы, расписание группы). Код библиотеки лежит вopen_api/_vendor/нетронутым — так и задумано автором (ТПО-004).api.py—UniversityAPI: один объект, который держитopenиlkвместе.db/— SQLAlchemy-модели (пока одна —GroupsCache), схема версионируется через Alembic (alembic/,alembic upgrade headприменяет миграции).cache.py—GroupsCacheStore: TTL-кэш списка групп поверх БД (ФХД-003), плюс fallback на устаревший кэш при недоступности источника (ТН-001).server.py— сам MCP-сервер (официальный Python SDK, ТПО-002), сейчас с одним инструментом —list_groups.
14/14 офлайн-тестов зелёные (tests/). open_api живьём прогнан против
настоящего rasp.dmami.ru. MCP-сервер живьём прогнан целиком: протокол →
list_groups → open_api → запись в groups_cache на реальном
PostgreSQL → повторный вызов из кэша. Для ручной проверки lk_api на
своём аккаунте — scripts/check_lk_api.py.
БД: общий PostgreSQL-сервер команды (не наш локальный, реальный
удалённый инстанс). У каждого свой пользователь — не шарим postgres/
admin. Подключение — через DATABASE_URL в .env (см. .env.example),
сам файл не коммитится. Если у вас его нет — спросите данные в чате
команды, пересылать их через репозиторий/коммиты не будем.
Дальше по плану (раздел 3.1): окно ЛР4-5 — дописываем ФЛК-001..007 целиком и оставшиеся ФОД/ФХД, дальше по разделу 3.1 фичи не трогаем.
Не портировано из MPU_LK_API (вне текущей области ТЗ, добавим при необходимости): finance.go (банковские карты), pep.go, roles.go, vaccines.go, directory.go, profile.go (семья/дети/проектная деятельность/смена группы/справки).