Files
magistr/BUG_FIX_PROMPT.md

34 KiB
Raw Blame History

Промпт для исправления ошибок из BUG_REPORT.md

Ты работаешь как ведущий full-stack инженер, специалист по безопасности и DevOps в репозитории системы университетского расписания Magistr.

Твоя задача — не просто составить план, а последовательно реализовать, протестировать и документировать исправления всех проблем из корневого файла BUG_REPORT.md, кроме проблемы № 2.

Обязательная область работ

Исправь проблемы № 1 и № 334. Проблема № 2 полностью исключена из задачи:

[1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34]

Это ровно 33 проблемы: одна критическая № 1, десять высокого приоритета № 312, девятнадцать среднего приоритета № 1331 и три низкого приоритета № 3234.

  • не исправляй её;
  • не изменяй ради неё демонстрационные данные или учётные записи;
  • не добавляй миграцию для отключения demo-аккаунтов;
  • не меняй существующие Flyway-миграции, включая V1__init.sql и V2__subgroups_active_unique_name.sql;
  • не включай проблему № 2 в итоговый список выполненных исправлений.

Если изменение для другого пункта пересекается с проблемой № 2, реализуй только часть, необходимую для другого пункта, и не затрагивай seed/demo-данные.

Проектный контекст и обязательные правила

  1. Сначала полностью прочитай:
    • корневой AGENTS.md — это главный проектный регламент;
    • BUG_REPORT.md;
    • относящиеся к изменениям документы из docs/;
    • фактический код и тесты в затронутых подсистемах;
    • production-манифесты в ../k8s/, которые входят в область проекта согласно AGENTS.md.
  2. При конфликте любых инструкций проекта с AGENTS.md следуй AGENTS.md.
  3. Используй проектные навыки из .agents/skills, когда задача соответствует их описанию. Для навигации по проекту сначала используй существующий graphify-out/graph.json, если он актуален. После изменений в коде примени AutoUpdateDocs.
  4. Соблюдай стек проекта: Java 17, Spring Boot 3.2.5, PostgreSQL/Flyway, Vanilla JavaScript, HTML и CSS без frontend-фреймворков.
  5. Все ответы, комментарии, UI-тексты, пользовательские ошибки и проектные логи должны быть на русском языке. Технические идентификаторы допустимы в структурированных полях логов.
  6. Сохраняй мультитенантную модель: отдельная PostgreSQL БД для каждого tenant. Проверяй, что миграции и фоновые задачи корректно работают для всех tenant-БД.
  7. Не изменяй существующие Flyway-миграции. Любые новые ограничения схемы оформляй новыми последовательно пронумерованными миграциями, начиная со следующей свободной версии. Сначала проверь фактическую максимальную версию в backend/src/main/resources/db/migration/.
  8. Сохраняй уже имеющиеся пользовательские изменения в рабочем дереве. Не откатывай и не перезаписывай несвязанные правки.
  9. Не выполняй commit, push, deployment, ротацию production-секретов, переписывание истории Git или иные внешние необратимые действия без отдельного разрешения. Репозиторную часть исправлений реализуй полностью, а необходимые production-действия оформи отдельным точным runbook.
  10. Не придумывай и не коммить реальные секреты. Не выводи секреты, пароли, токены, cookie или строки подключения в ответах, тестах и логах.
  11. Не скрывай ошибки пустыми catch, не ослабляй проверки безопасности ради прохождения тестов и не отмечай проблему исправленной только за счёт комментария или документации.
  12. Если замечание из отчёта уже исправлено в текущем коде, проверь это по реализации, добавь или уточни регрессионный тест и укажи доказательство. Не делай лишнюю повторную правку.
  13. Не редактируй BUG_REPORT.md: он остаётся исходным реестром требований и основанием для итоговой проверки.
  14. Учитывай, что ../k8s/ находится вне Git-корня magistr: отдельно перечисляй и проверяй каждый изменённый там файл. git diff текущего репозитория не подтверждает состояние ../k8s/.

Режим выполнения

Задача большая, поэтому веди явный чек-лист по номерам проблем: 1, 3, 4, …, 34. Для каждого пункта зафиксируй:

  • подтверждённую первопричину;
  • изменяемые файлы и выбранное решение;
  • автоматические тесты или иную воспроизводимую проверку;
  • статус: не начато, в работе, исправлено и проверено либо требуется внешнее действие.

Раздели работу на независимые потоки и используй субагентов, если платформа это поддерживает, но координируй общие файлы, номера Flyway-миграций, API-контракты и role matrix централизованно. Не останавливайся после анализа или первой группы исправлений. Продолжай, пока все пункты из области работ не будут реализованы и проверены либо пока не останется объективный блокер, требующий внешних полномочий.

Перед редактированием:

  1. Выполни git status --short и сохрани понимание исходных пользовательских изменений.
  2. Зафиксируй список и контрольные суммы всех существующих Flyway-миграций, чтобы доказать их неизменность в финале.
  3. Проверь каждое утверждение отчёта по актуальному коду.
  4. Составь краткий порядок правок с учётом зависимостей.
  5. Запусти доступный базовый набор тестов, чтобы отличать исходные сбои от внесённых регрессий.

Требуемый результат по каждому пункту

Безопасность и аутентификация

  • № 1 — секреты в production-конфигурации. Удали фиксированные, дефолтные и placeholder-секреты из отслеживаемой конфигурации; перенеси чувствительные значения из ConfigMap в подходящий механизм Secret/External Secrets/SOPS/Sealed Secrets либо подготовь безопасные ссылки на секреты без самих значений. На production-профиле приложение должно завершать запуск при отсутствующем, дефолтном или известном placeholder JWT_SECRET, а также при небезопасном refresh-cookie. Не переписывай историю Git и не ротируй реальные секреты самостоятельно — подготовь отдельный runbook ротации и очистки истории. При secret scan не трактуй неизменяемые demo-значения из V1__init.sql, относящиеся к исключённой проблеме № 2, как разрешение менять V1 или решать пункт № 2.
  • № 3 — конкурентная ротация refresh-токена. Обеспечь атомарную single-use семантику через блокировку строки или условный UPDATE; только один из параллельных запросов может создать следующий токен. Добавь конкурентный интеграционный тест с реальным PostgreSQL/Testcontainers.
  • № 4 — утечка AuthContext. Очищай контекст в начале обработки и на всех отказах, а пользователя устанавливай только после успешной аутентификации и авторизации. Добавь тест последовательных запросов на одном servlet-потоке.
  • № 12 — access JWT и удалённый JavaScript в одном origin. Убери исполнение неприкреплённых удалённых модулей, зафиксируй зависимости lockfile и раздавай их локально. Убери долговременное хранение access token в localStorage и sessionStorage: выбери и последовательно реализуй безопасную схему с access token в памяти и HttpOnly refresh-cookie либо полноценной защищённой cookie-сессией. Добавь строгий CSP без unsafe-inline/unsafe-eval, устрани несовместимые inline-скрипты и проверь все сценарии входа, refresh, logout и безопасного восстановления сессии после перезагрузки страницы.
  • № 14 — отключённая TLS-проверка Kubernetes API. Удали доверие любому сертификату. Используй service-account CA /var/run/secrets/kubernetes.io/serviceaccount/ca.crt, стандартную проверку цепочки и hostname; ошибки должны быть явными и безопасными.
  • № 24 — бесконечный рост refresh-токенов. Добавь tenant-aware cleanup с настраиваемым сроком хранения отозванных/истёкших записей, безопасным расписанием и тестами. Очистка должна сохранять активные и свежие audit-записи, быть идемпотентной и безопасной при двух pod.
  • № 25 — утечка DB/JDBC-ошибок. Централизованно преобразуй DataIntegrityViolationException и известные constraints в корректные 400/409 с русскими сообщениями. Внутренние тексты исключений не должны попадать клиенту.
  • № 28 — отсутствие ограничения входа. Реализуй общий для нескольких backend-pod rate limit по tenant + IP + нормализованному username, прогрессивную задержку или временную блокировку и аудит неудачных попыток без логирования пароля. Учти корректное определение клиентского IP только за доверенным proxy, не допускай user enumeration, возвращай 429 Too Many Requests и корректный Retry-After. Не выдавай локальный in-memory limiter одного pod за production-решение.
  • № 33 — DOM XSS и видимые пароли. Замени небезопасные вставки ошибок через innerHTML на textContent или проверенное экранирование. Поля пароля должны иметь type="password" и корректные autocomplete.
  • № 34 — языковой регламент. Приведи затронутые UI-тексты, ошибки и production-логи к русскому языку, не отдавая пользователю сырой JDBC/HTTP exception text.

Расписание, календарь и бизнес-инварианты

  • № 5 — невалидные schedule overrides. До сохранения построй фактическую исходную пару на дату, проверь обязательные поля для каждого action, существование пары и конфликты преподавателя, аудитории и всех групп в результирующем расписании. Конфликт должен давать 409 Conflict с русским сообщением.
  • № 6 — замена преподавателя не видна в его расписании. Учитывай overrides с newTeacher за период, достраивай относящиеся базовые пары и выполняй окончательную фильтрацию после применения overrides. Покрой исходного и нового преподавателя тестами.
  • № 7 — неполная валидация правил. Проверяй конфликты и дубли внутри нового правила, роль TEACHER, допустимый enum формата и чётное положительное количество академических часов. Где уместно, продублируй инварианты новой Flyway-миграцией.
  • № 8 — частичный commit календарной сетки. Сначала валидируй весь payload и уникальность ключей, затем атомарно заменяй сетку в транзакции. После любого 400 прежние данные должны остаться без изменений.
  • № 11 — ложный зелёный статус дашборда. Рассчитывай воскресенье как отдельную дату понедельник + 6 дней, не используй UTC для date-only значений и разделяй состояния «конфликтов нет», «частичная ошибка проверки» и «проверка не выполнена». Для 2026-07-02 диапазон должен быть 2026-06-29…2026-07-05; проверь также переход года.
  • № 15 — некорректные временные слоты. Требуй startTime < endTime, запрети пересечения интервалов внутри scope, но разреши соседние интервалы с общей границей. Не разрешай перевод используемого базового слота из DEFAULT в MANUAL, а продолжительность рассчитывай на backend по startTime/endTime. Защити инвариант и от конкурентных записей.
  • № 16 — пересечения учебных лет и семестров. Централизуй валидацию диапазонов для create/update: запрети пересечения учебных лет, пересечения семестров, выход семестра за границы его года и дубликаты title/type. Добавь DB-ограничения новой миграцией там, где PostgreSQL может надёжно обеспечить инвариант.
  • № 17 — устаревшие назначения календарей. При изменении ключевых измерений календаря или группы либо безопасно отклоняй несовместимое изменение с 409 Conflict без изменения данных, либо в одной транзакции перевалидируй назначения, grid и subjects. Уменьшение courseCount не должно оставлять строки или дисциплины старших курсов.
  • № 18 — исторические кафедры преподавателя. Для бизнес-решений и исторических отчётов определяй кафедру через teacher_department_assignments на целевую дату. Будущий перевод не должен менять текущую принадлежность раньше validFrom, архивный преподаватель должен корректно отображаться в историческом периоде, дополнительные активные назначения должны работать единообразно.
  • № 19 — доступ к workload чужой кафедры. Для роли DEPARTMENT принудительно ограничивай scope кафедрой из AuthContext; глобальный просмотр разрешай только явно уполномоченным ролям.
  • № 20 — лимит 50 групп в агрегатах. Не используй ограничение интерактивного широкого поиска в workload/free-classrooms. Реализуй специализированные агрегирующие запросы или контролируемую batch-обработку и тесты как минимум с 51 и 100 активными группами.
  • № 21 — импорт дисциплины другой кафедры. Не переназначай чужую запись по совпавшему глобальному имени. Зафиксируй бизнес-правило владения и уникальности; безопасный вариант по умолчанию — 409 Conflict при совпадении с чужой кафедрой и идемпотентный повторный импорт своей записи. При необходимости введи (department_id, lower(name)) новой миграцией и обработай существующие данные безопасно.
  • № 22 — несовпадающие права учебного отдела. Создай единый явно проверяемый role matrix для backend и frontend. Либо выдай EDUCATION_OFFICE необходимые права, либо скрой недоступные действия; штатные экраны не должны завершать инициализацию с 403.
  • № 23 — N+1 при генерации расписания. Батчем загружай semesters, assignments и calendar days на диапазон, переиспользуй найденные данные и не выполняй запрос на каждую дату/группу/правило. Добавь измеримый query-count тест на диапазоне 120 дней и десятках групп, доказывающий отсутствие роста порядка дни × группы × правила при неизменном результате.
  • № 29 — нефиксированный часовой пояс. Внедри Clock и явно настроенный ZoneId Europe/Moscow для бизнес-дат, используй Instant/UTC для абсолютных timestamp, зафиксируй timezone контейнеров и формируй frontend date-only строки из локальных компонентов без toISOString().
  • № 31 — некорректный размер группы. Используй единый валидатор create/update: groupSize > 0, yearStartStudy > 0, а также запрет уменьшения ниже суммы активных подгрупп, включая конкурентный сценарий. Добавь новые CHECK constraints отдельной миграцией.
  • № 32 — диапазон в 121 дату. Проверяй включительную длину диапазона; максимум должен составлять ровно 120 календарных дат. Покрой граничные случаи 120 и 121 дата.

Tenant, инфраструктура и поставка

  • № 9 — небезопасная замена tenant DataSource. Создавай временный pool, явно проверяй соединение и Flyway, затем атомарно подменяй рабочий DataSource. Ошибка миграции или сохранения конфигурации должна прерывать операцию и запускать compensating rollback без потери старого подключения.
  • № 10 — lost update ConfigMap и неинформативные probes. Реализуй optimistic locking по resourceVersion с ограниченным retry/backoff либо эквивалентный единый coordinator; параллельные изменения двух pod не должны теряться. Readiness должна учитывать доступность обязательных tenant-БД и успешность миграций, а liveness — только жизнеспособность процесса, чтобы отказ БД не создавал restart storm.
  • № 13 — неполная синхронизация watcher. Сравнивай весь нормализованный TenantConfig, а hash обновляй только после полного успеха. Неудачная синхронизация должна повторяться с ограниченным backoff и наблюдаемым русскоязычным логом.
  • № 26 — нерабочий чистый локальный запуск. Сделай docker compose up -d --build на чистой машине, без заранее созданной внешней сети, достаточным для доступа к приложению по http://localhost:80 и проксирования /api в backend. Согласуй JDBC URL и POSTGRES_DB, передай JWT-настройки, добавь именованный volume и обнови quick start.
  • № 27 — deployment без тестов и неверный tag rollout. Добавь обязательные backend/frontend/static/config проверки до build/push/deploy, concurrency lock и проверяемый rollback. Для релизного tag разворачивай конкретный tag или digest, а не перезапускай mutable :main.
  • № 30 — mutable и непроверяемые артефакты. Зафиксируй версии и digest базовых/сторонних образов и инструментов, проверяй SHA256/signature скачиваемых бинарников, формируй SBOM и добавь сканирование образов. В production не должно остаться latest и :main; обновление версии должно быть явным и воспроизводимым.

Архитектурные требования к реализации

  • Транзакционные границы должны находиться на вызываемых Spring proxy-методах; не рассчитывай на @Transactional при self-invocation или пойманном внутри исключении.
  • Для конкурентных сценариев используй гарантии PostgreSQL и проверяй их интеграционными тестами, а не только синхронизацией внутри одного JVM-процесса.
  • Все операции с tenant-конфигурацией должны быть идемпотентными и безопасными при двух pod.
  • Не смешивай date-only и timestamp. Date-only передавай как YYYY-MM-DD без UTC-конвертации.
  • Сохраняй обратную совместимость API там, где она не противоречит безопасности. Если контракт необходимо изменить, синхронно обнови backend, frontend, тесты и docs/API.md.
  • Не дублируй сложные бизнес-правила по контроллерам. Выноси общую валидацию/логику в переиспользуемые компоненты в соответствии с текущей архитектурой проекта.
  • Избегай массовых косметических рефакторингов, не относящихся к отчёту. Каждое существенное изменение должно сопоставляться с одним или несколькими номерами проблем.
  • Не выполняй docker compose down -v, массовое удаление данных и другие необратимые операции. Интеграционные тесты должны использовать изолированные временные ресурсы.

Обязательные тесты и проверки

Добавь регрессионные тесты для каждого исправленного поведения. В первую очередь обязательно покрой:

  1. PostgreSQL/Testcontainers и Flyway: чистая схема и upgrade существующей схемы — без проверки и изменения поведения из проблемы № 2.
  2. Два параллельных refresh-запроса с одним токеном: успех только одного.
  3. Последовательность 403, затем публичный/защищённый запрос на одном потоке без утечки AuthContext.
  4. Override с конфликтом и расписание преподавателя, назначенного через newTeacher.
  5. Внутренние конфликты нового правила, неверная роль, нечётные часы и недопустимый формат.
  6. Атомарность saveGrid: после ошибочного payload старая сетка полностью сохранена.
  7. Изменение tenant URL/credentials, неудачная миграция, неудачный ConfigMap update и параллельные PATCH от двух pod.
  8. Более 50 активных групп для workload/free-classrooms.
  9. Будущий перевод преподавателя и исторические отчёты.
  10. E2E или эквивалентный интеграционный сценарий EDUCATION_OFFICE для календарных графиков и форм обучения.
  11. Frontend-даты в первые дни месяца и в интервале 00:0003:00 Europe/Moscow.
  12. Граничные диапазоны 120/121 дата, XSS payload в ошибке, rate limit и cleanup refresh-токенов.

После реализации выполни доступные проверки и зафиксируй фактический результат каждой команды:

mvn -f backend/pom.xml test
find frontend -type f -name '*.js' -print0 | xargs -0 -n1 node --check
docker compose config --quiet
docker compose build backend frontend
kubectl kustomize ../k8s >/dev/null
bash -n ../k8s/deploy.sh
git diff --check
git diff --stat
git status --short

Команду для ../k8s/deploy.sh выполняй только если файл существует. Если локального Maven, Node, Docker или kubectl нет либо сборке нужен недоступный network/daemon, используй уже принятый в проекте контейнерный эквивалент либо честно укажи, какую проверку невозможно запустить и почему. Не называй непроверенный результат успешным. Успешный Docker build не заменяет mvn test.

Дополнительно проверь:

  • отсутствие секретов и placeholder credentials в отслеживаемых production-файлах;
  • отсутствие изменений существующих Flyway-миграций;
  • согласованность новых миграций с JPA-моделями и upgrade-путём всех tenant-БД;
  • отсутствие сырых exception messages в HTTP-ответах;
  • соответствие backend/frontend role matrix;
  • отсутствие localStorage/sessionStorage для access JWT, удалённых исполняемых модулей и исполняемого inline JavaScript, несовместимого со строгим CSP;
  • воспроизводимость Docker/CI/Kubernetes-конфигурации;
  • отсутствие английских пользовательских сообщений и production-логов в изменённых областях.
  • отдельный список и содержательную проверку всех изменений в ../k8s/, поскольку они не видны в Git diff проекта.

Документация

После кода и тестов обнови только относящуюся к изменениям документацию, в том числе при необходимости:

  • docs/API.md;
  • docs/DATABASE.md;
  • docs/ARCHITECTURE.md;
  • docs/BUSINESS_LOGIC.md;
  • docs/FRONTEND.md;
  • docs/INFRASTRUCTURE.md;
  • docs/LOGGING.md;
  • docs/README.md и корневой quick start.

Документация должна описывать фактическое поведение после изменений. Не документируй проблему № 2 как исправленную и не меняй инструкции по demo-аккаунтам в рамках этой задачи.

Формат итогового ответа

Ответ дай на русском языке и начни с результата. Включи:

  1. Таблицу по всем пунктам 1, 334: номер, краткое исправление, основные файлы, тест/проверка, статус.
  2. Список созданных Flyway-миграций и подтверждение, что существующие миграции не изменены.
  3. Фактически выполненные команды и их результаты.
  4. Изменения API, конфигурации, role matrix и deployment-процесса.
  5. Отдельный раздел «Требуемые действия оператора» для ротации секретов, очистки истории, настройки secret manager, production rollout и других действий, которым нужен внешний доступ. Не утверждай, что они выполнены.
  6. Оставшиеся риски или проверки, которые невозможно выполнить локально.
  7. Подтверждение, что проблема № 2 не затрагивалась.

Перед финальным ответом ещё раз прочитай BUG_REPORT.md и сравни чек-лист с точным множеством {1} {3..34}. В итоговой таблице должно быть ровно 33 строки без пропущенных или повторяющихся ID. У каждого пункта должны быть реализация либо доказательство уже существующего исправления, регрессионная проверка и честный статус.

Критерий завершения: каждый пункт № 1 и № 334 имеет реализацию и регрессионную проверку либо явно отделённое внешнее действие; все доступные тесты проходят; документация соответствует коду; проблема № 2 и существующие Flyway-миграции не изменены.