В прогоне курса кабинет «Кодиума» собрали за 5 заданий агенту, около часа его работы. Новую работу делали три задания: сборка, выкладка и связка с ботом. Два остальных чинили то, что агент назвал готовым: секрет по умолчанию и время в UTC. А ещё две дыры, удалённый .env и ключ по умолчанию, нашлись только проверкой руками. Теперь твоя очередь: свой заказчик, свой кабинет и та же привычка проверять сервер самому.
Чему научишься в этом уроке:
• собрать кабинет заявок для своего заказчика по своему ТЗ;
• выложить его на сервер в России с копией и проверкой восстановления;
• проверить вход под каждой ролью и сервер после агента;
• сдать комплект доказательств без секретов.
С чего начать
Продолжай кабинет из миссий уроков 5.3–5.5, новый не собирай: здесь закрываешь пункты чек-листа, которые ещё не закрыты, и собираешь сдачу. Если миссии ты пропускал, возьми ТЗ из урока 5.6. Если своего заказчика нет, делай «Кодиум», но поменяй одно поле или одну роль на своё, чтобы задание агенту не было копией. Задание на сборку бери из урока 5.3 и подставь свои поля, роли и статусы. Что не меняется никогда:
- пароли через pwdlib с Argon2, passlib не использовать;
- вход через подписанную cookie, секрет только в .env, без значения по умолчанию;
- права проверяются на сервере в каждом обработчике;
- CSRF-токен в формах, не больше 5 попыток входа в минуту;
- все SQL-запросы с параметрами;
- время хранится в UTC, показывается по Москве с пометкой «МСК»;
- персональные данные только на сервере в России.
Чек-лист П4
Отмечай пункт только после того, как увидел сам: открыл в браузере, выполнил команду, прочитал вывод.
- Тесты pytest проходят, и в выводе видно, что проверяются роли (403 для менеджера), 6-я попытка входа (429), форма без CSRF и приём заявки без ключа (401).
- В проекте нет мусора: папки pip и Microsoft, кэши и база не попали в git (.gitignore из урока 5.3).
- Без SESSION_SECRET или INGEST_KEY приложение не стартует (урок 5.4).
- Сервер в России: ufw с OpenSSH, HTTPS, лимит на /login, служба active после твоего перезапуска.
- Ты вошёл под менеджером и под владельцем: у менеджера только заявки, у владельца ещё пользователи, аналитика, выгрузка.
- Копия ночью, 14 штук, уходит на Яндекс Диск; восстановление проверено, лог сохранён.
- .env на сервере на месте, права 600, в коде нет секретов по умолчанию и тестовых лазеек (grep из урока 5.5); в боевом коде нет проверок «это тест»:
grep -nE "TESTING|IS_TEST" main.pyничего не находит. - Отпечатки ключа приёма на двух серверах совпадают; старый или неверный ключ получает 401.
- Уведомление в Telegram без имени и телефона, со ссылкой в кабинет.
- Время в списке и карточке по Москве с пометкой «МСК».

Порядок работы
- Первый заход: ТЗ, задание на сборку, тесты зелёные у тебя на компьютере.
- Второй: вход и роли, проверка без секретов по умолчанию, сам входишь под каждой ролью локально.
- Третий: сервер в России, выкладка, копия и восстановление, проверка сервера руками.
- Четвёртый: связка с ботом и формой, отпечатки ключей, время по Москве, снимки для сдачи.
- Закладывай 3–4 часа, если миссии 5.3–5.5 сделаны: агент в прогоне работал около часа, остальное время уходит на проверки и починку.
Перед снимками закрой имена и телефоны, адреса серверов, токены и пароли. Пароли пользователей лежат только в /root/crm-paroli.txt, агенту и в чат их не отдавай.
Для проверки восстановления пригодится команда PRAGMA integrity_check;: её выполняют на восстановленной базе, ответ ok значит, что файл цел. Следующий уровень, если заказчик вырастет, это непрерывная копия базы во внешнее хранилище (программа litestream). Для «Кодиума» ночной копии хватает.

Кейс из прогона: 13:27 превратилось в 10:27
Владелец вошёл в кабинет и увидел, что заявка, отправленная в 13:27 по Москве, показана как 10:27: часы сервера идут по UTC, ты встречал это в уроке 3.5. Задание на починку: хранить время в UTC, показывать везде (список, карточка, журнал, аналитика, выгрузка) по Москве через zoneinfo(«Europe/Moscow») с пометкой «МСК», тест на перевод времени. Главное в нём хвост, вывод из кейса с удалённым .env:
Обнови на сервере <адрес сервера в Москве> (НЕ трогай .env и базу; после обновления сам перезапусти службу и проверь, что она поднялась и .env на месте), покажи вывод pytest -q.
Агент работал 8,6 минуты, тестов стало 9 из 9, .env на месте, служба active. Перезапуск и проверку .env всё равно делаешь сам. Шаги 1–4 прогона (сборка, выкладка, исправление секрета и связка) стоили около 0,28 $ в CloseRouter, починка времени добавила немного сверху.
Если не получилось
- Тесты зелёные, а вход владельцем подделывается → в коде секрет по умолчанию; урок 5.4.
- Менеджер видит «Пользователи» → права проверяются только скрытием кнопки; попроси проверку роли в обработчике и тест на 403.
- После перезапуска кабинет не поднялся → проверь, на месте ли .env; урок 5.5.
- Копия делается, а на Диске пусто → токен в .env заглушка или без права записи.
- Бот получает 401 → отпечатки ключей не совпали.
- Время на 3 часа меньше → показ в UTC; задание с zoneinfo выше.
- В git попала база или .env → убери из индекса, добавь в .gitignore, смени секреты, которые успели попасть в историю.
- certbot ругается на домен → поддомен ещё не смотрит на новый сервер; проверь A-запись, как в уроке 3.3.
- После включения ufw пропал SSH → OpenSSH не разрешили первым; зайди через консоль в панели Timeweb и разреши OpenSSH.
Контрольный вопрос. Все тесты зелёные. Чем ты докажешь заказчику, что менеджер не видит раздел «Пользователи»?
Подсказка: Чем проверка глазами отличается от отчёта?
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Контрольный вопрос. Что из этого можно положить в сдачу практики?
Подсказка: По чему из списка нельзя восстановить секрет или узнать данные людей?
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Контрольный вопрос. Агент закончил обновление и пишет «служба перезапущена, .env не трогал». Что делаешь?
Подсказка: Вспомни, сколько прожила служба без .env в прогоне.
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Задание. МИССИЯ «Кабинет заявок для своего заказчика». 1. Запиши заказчика и ТЗ из урока 5.6 (поля, роли, статусы). 2. Возьми кабинет из миссий 5.3–5.5 (если их не делал, собери по уроку 5.3) и пройди чек-лист П4 по пунктам. 3. Выложи на сервер в России, сделай копию и проверь восстановление. 4. Свяжи с ботом или формой из П1–П2, сверь отпечатки ключа. 5. Войди сам под каждой ролью. Принято, если: приложены снимки кабинета под двумя ролями (меню видно, личные данные закрыты), полный вывод pytest -q, лог восстановления из копии (удалённая заявка вернулась), отпечатки ключа приёма с двух серверов (совпадают), снимок ls -l и списка имён переменных .env на сервере (без значений) и systemctl status после твоего перезапуска, пустой вывод grep -nE «TESTING|IS_TEST» main.py, плюс заполненный чек-лист из 10 пунктов.
Подсказка: Если какой-то пункт чек-листа не получился, напиши, что видишь, и приложи вывод: наставник поможет быстрее.
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Что дальше
П4 закрыт: у заказчика заявки в одном месте, у тебя кабинет на сервере в России с копиями и проверенными ролями. В П5 строим дашборды: из тех же заявок делаем картину, по которой владелец принимает решения.
Итог:
• кабинет собран по своему ТЗ и проходит тесты на роли, вход и приём заявок;
• данные на сервере в России, восстановление из копии проверено;
• после агента ты сам проверяешь .env, перезапуск, ключи и время;
• комплект сдачи собран без секретов и личных данных.
