ООО «Творческое Образование» — Старший разработчик, системный аналитик
Август 2024 — настоящее времяКраснодар, удалённо. Федеральные сети онлайн и офлайн школ. Главный разработчик на проектах. grafika-art-school.ru/franchise (GRAFIKA) и arttech-school.ru/franchise (ArtTech)
Рост внутри компании
- 2024 — пришёл бэкенд-разработчиком: архитектура БД и серверная часть платформы, которую делали с нуля.
- 2025 — повышен до старшего разработчика и закрыл выпавшую роль системного аналитика. С этого момента совмещаю две штатные должности — старший разработчик и системный аналитик, каждая со своей зарплатой.
- 2026 — зона ответственности расширена на backend, frontend, DevOps, QA, архитектуру и системную аналитику, включая поддержку проектов смежных отделов на других языках.
Платформу для студентов, преподавателей, менеджеров, руководителей и партнёров делаем с нуля: веб-версия, приложения для Android и iPhone, Telegram-бот. По сути это CRM/ERP сети школ: расписания и залы, абонементы и финансы, роли и права, отчётность — девять ролей пользователей со своими правами и интерфейсами. В команде backend- и frontend-разработчики, DevOps, системные аналитики, PM и QA. Я проектирую архитектуру БД и бэкенда, пишу серверную часть, помогаю аналитикам с ТЗ, а фронтендерам с отладкой и оптимизацией запросов.
Цель Запустить платформу для федеральной сети школ и довести её до продакшна.
Действие Спроектировал архитектуру БД и бэкенда, реализовал серверную часть веба и приложений. Стек выбрал полностью асинхронный (FastAPI, SQLAlchemy 2.0 async, asyncpg), схему БД — под версионные миграции Alembic, чтобы структура менялась без простоя и без ручных правок на проде. Написал скрипты загрузки и миграции данных.
Результат Вывели продукт в продакшн. Через мои скрипты в систему заведено около 5 000 студентов, которые активно пользуются приложением.
Цель Поддержать сложную логику абонементов и расписаний для разных городов и таймзон.
Действие Сделал конструктор абонементов (направления со своими лимитами или безлимитом), запись и отмену занятий, заморозки, приостановки, трансферы, присутствие студента сразу в нескольких школах, учёт десятков городов в разных таймзонах.
Результат Бэкенд сам корректно отрабатывает эти случаи, ручных операций стало заметно меньше.
Цель Дать живую связь с пользователями.
Действие Построил систему массовых и индивидуальных push-уведомлений на Socket.IO с Redis в роли брокера — realtime масштабируется горизонтально, несколькими процессами за балансировщиком, а не одним «толстым» воркером. Онлайн-сессии и присутствие держу в Redis, доступ — по JWT с асимметричной RSA-подписью (приватный ключ не покидает эмитента, остальные сервисы проверяют токен публичным). Добавил отложенные рассылки по расписаниям и событиям, с генерацией текста по шаблонам и учётом таймзон.
Результат Школы разных городов получают уведомления вовремя, история сообщений сохраняется.
Цель Дать прозрачность обучения и обратную связь, упростить контроль для управляющей компании и партнёров.
Действие Сделал оценку занятий (рейтинги и отзывы), хранение и показ истории действий студента в его профиле, а также инструменты отчётности, рейтингов и контроля для сотрудников управляющей компании, партнёров и школ.
Результат Активность и качество занятий видны в одном месте — решения принимаются по данным, а не на глаз.
Цель Масштабировать продукт на две федеральные сети (GRAFIKA и ArtTech) и подготовить выход за рубеж.
Действие Перестроил архитектуру, расширил и местами переписал логику, структуры моделей и таблиц с сохранением данных тысяч пользователей из множества связанных таблиц. Заложил особенности дизайна и логики под каждую компанию.
Результат Одно приложение работает на две федеральные сети (GRAFIKA и ArtTech) в РФ, начата подготовка к запуску в других странах.
2026. Принял на себя backend, frontend, DevOps, QA, архитектуру и системную аналитику, в том числе поддержку проектов на других языках из смежных отделов. Отдельно взял на себя CI/CD и инфраструктуру — после аварии облачного провайдера развернул её заново в Selectel: пайплайны пяти репозиториев (бэкенд, фронтенд, конфигурация балансировщика, модели и миграции, Telegram-бот), предеплойные и постдеплойные гейты. Теперь отвечаю практически за всё, что связано с разработкой ПО в компании — от схемы БД до выкладки на прод и процесса, по которому работает команда.
Цель Сделать качество проверяемым, а выкладку — предсказуемой, когда за разработку отвечает один человек.
Действие Покрытие тестами на старте отсутствовало — тестовую инфраструктуру на обоих проектах выстроил с нуля и встроил написание тестов в сам процесс: по скиллу тестовой дисциплины агент пишет тесты вместе с кодом задачи, а гейт покрытия нового кода в CI и в предкоммитной проверке не пропустит изменение, если новые и изменённые строки покрыты меньше чем на 90 %. Стек — pytest + pytest-asyncio на бэкенде и httpx для QA-прогонов по живому API, vitest на фронтенде и Playwright для сквозных сценариев в двух браузерных профилях, десктопном и мобильном: проходы по ролям, мобильные раскладки и smoke на вход и аналитику; прогон направляется на любой поднятый стенд через переменную окружения, UI-компоненты вынесены в Storybook. Взял на себя CI/CD в GitLab. У бэкенда и фронтенда свои независимые пайплайны: у бэкенда девять стадий и 22 джоба — сборка образов → линтеры → тесты → очистка раннера → выкладка на удалённые хосты через Docker-контексты → миграции → деплой → уборка → уведомление; у фронтенда восемь стадий и 20 джобов, без стадии миграций. Каждый пайплайн разведён на три контура — тестовый стенд и два прода, GRAFIKA и ArtTech, — поэтому стадий и джобов на проекте вдвое больше, чем в одном пайплайне. Свои пайплайны есть и у репозитория моделей и миграций, и у конфигурации балансировщика, и у Telegram-бота с его собственными тремя контурами (dev, stage, prod). Базы у брендов при этом раздельные и живут на своих серверах: общими остаются модели и схема, данные у каждого свои, а бэкенд бренда и его Telegram-бот работают с одной базой. Релизы перевёл на SemVer-теги от main, чтобы каждая версия на проде была однозначно сопоставима с коммитом.
Результат Выкладка стала операцией, а не ритуалом: пайплайн сам не пустит на прод код, не прошедший линтеры и тесты, а откат — это возврат на предыдущий тег. Каждая новая фича приходит покрытой unit- и интеграционными тестами не меньше чем на 90 %, а пользовательские сценарии — e2e-прогонами; покрытие растёт с каждой задачей, а не обещается «потом».
Цель Дать каждому разработчику собственный стенд и вынести приёмку на контур, приближённый к продакшну.
Действие Когда команда была полной, контуров было больше: по два тестовых стенда на бэкенд и на фронтенд — по одному на разработчика, в команде было два бэкендера и два фронтендера, — плюс отдельный stage и прод. У каждого стенда своя база, поэтому чужие тестовые данные и незакрытые задачи не мешали; фронтенд подключается к любому бэкенду через переменную окружения, включая локальный, — на этом же удобно проверять крупные изменения архитектуры сразу на нескольких версиях приложений. Stage держал чистую базу и конфигурацию, приближённую к проду, но без персональных данных и рабочих кредов: там шли приёмка, поиск уязвимостей и демонстрации новых фич руководству и сотрудникам. На тестовых стендах данные грязные по определению — это среда разработки, и приёмку на ней проводить нельзя. Каждый контур — это свои джобы в пайплайнах всех репозиториев, свой сервер, свои конфиги nginx и свой набор переменных окружения; настройка и поддержка этой обвязки на мне.
Результат Разработчики одного стека не ждали освободившегося стенда, а на прод уходил код, прошедший приёмку на чистой базе. Когда состав команды сократился и компания урезала расходы на инфраструктуру, я свернул схему до текущей: один тестовый стенд на бэкенд и фронтенд, два прода и локальный запуск бэкенда. Разворачивать контуры и так же осознанно сворачивать их под текущие задачи и бюджет — часть работы, а не разовая настройка.
Цель Исключить релиз, который выглядит успешным, но до стенда не доехал.
Действие Разобрал инцидент: пайплайн был зелёным, но ручной джоб остался ненажатым — прод молча не обновился, а глазами это не поймали. Написал два гейта. Первый сверяет статусы всех джобов пайплайна по каждому контуру: статус «manual» означает «не нажат» и считается провалом, скрипт сразу печатает готовую команду запуска. Второй проверяет работоспособность стендов — шесть адресов, фронтенд и бэкенд каждого из трёх контуров. Предеплойный гейт собрал в одну команду: корневой preflight, flake8 и pytest на бэкенде, ESLint, Stylelint, сборка типов и vitest на фронтенде, по флагу — прогон Playwright по поднятому стенду. Сам порядок релиза зафиксировал runbook’ом: строго database → backend → frontend, теги создаются до деплоя, а после деплоя обязательны обе проверки плюс функциональный проход по интерфейсу — e2e-прогон Playwright направляется переменной окружения на уже задеплоенный контур, а не на локальную сборку, и прод проверяется на обоих брендах.
Результат «Задеплоил» больше не означает «надеюсь, доехало»: ненажатый джоб и неотвечающий стенд ловит скрипт, а не человек. Из этого вырос принцип, который я вписал в правила проекта: проверять результат, а не намерение.
Цель Убрать ручную правку конфигов балансировщика на живом сервере.
Действие Вынес конфигурацию nginx балансировщика в отдельный репозиторий и подключил его в моно-репо — 17 site-конфигов под версионным контролем. CI применяет их сам: бэкап текущих конфигов → копирование новых → nginx -t → и только при успешной валидации reload; провалилась проверка — перезагрузки нет. Там же починил проксирование WebSocket на всех контурах: Socket.IO работал локально, а на стендах отдавал 400, потому что в конфигах не было proxy_http_version 1.1 и заголовков Upgrade/Connection.
Результат Опечатка в конфиге больше не может уронить балансировщик, realtime одинаково работает на тесте и обоих продах, а история изменений инфраструктуры лежит в git, а не в памяти администратора.
Цель Поднять всю систему после аварии облачного провайдера: в октябре 2026 сбой зоны Yandex Cloud вывел из строя все серверы компании вместе с управляемым GitLab — продакшн обоих брендов, тестовый стенд, балансировщик, почту и CI. Переносить было нечего: инфраструктуры больше не существовало, уцелели только объектное хранилище и DNS-зоны.
Действие Развернул инфраструктуру с нуля в Selectel в два этапа. Первые сутки — аварийный подъём: минимальный рабочий контур, на котором платформа обоих брендов снова заработала, и пользователи вернулись к приложению. Дальше, в пределах четырёх дней, — полноценная инфраструктура взамен потерянной, с бэкапами, мониторингом и runbook’ом. Сеть и серверы: пять серверов вместо прежних шести — балансировщик с SSH-бастионом, два прода (GRAFIKA и ArtTech), тестовый контур и GitLab, — разнесённых по зонам доступности, приватная сеть с отказоустойчивым облачным роутером, группы безопасности; прод-серверы и базы данных не имеют публичных адресов и доступны только из приватной сети через бастион, вход по SSH-ключам, пользователи и алиасы доступа заведены под каждую роль. Сервисы: все приложения в Docker-контейнерах, nginx на балансировщике со всеми доменами и TLS Let's Encrypt, восстановил прод из последнего уцелевшего дампа и сверил данные по контрольным счётчикам. GitLab: вместо управляемого — свой современный GitLab CE с Container Registry: перенёс семь репозиториев со всеми ветками и тегами, раннеры, CI-переменные по трём контурам, защищённые ветки без force-push. DNS, файлы, почта: перевёл зоны обоих брендов к регистратору, перенёс объектное хранилище — файлы приложения, архивы и сайты документации со сверкой по объёму, — переписал публичные ссылки; отдельную почтовую ВМ заменил SMTP-релеем с настроенными SPF, DKIM и DMARC. Observability: ELK-стек (Elasticsearch, Logstash, Kibana) прежний DevOps отключал ради экономии ресурсов, и ошибки на проде было негде смотреть — поднял экономный self-hosted GlitchTip (~330 МБ памяти): отдельные проекты на каждый бренд, окружения prod / art-prod / test, логи и ошибки бэкенда и фронтенда в одном интерфейсе. Бэкапы в три уровня: ночные снимки дисков всех пяти серверов; свои скрипты ежедневных дампов обоих продов и GitLab вместе с его секретами — с проверкой целостности архива и минимального размера, ротацией и алертом на почту — в объектное хранилище в другом регионе и параллельно ко второму провайдеру; отдельный сторож каждое утро проверяет свежесть копий в обоих хранилищах. Восстановление из внешней копии проверил на практике — база поднимается за десятки секунд. Весь порядок развёртывания с нуля, карту серверов и грабли переезда описал runbook’ом в репозитории.
Результат Система работает на трёх независимых площадках: серверы и снимки дисков — в московском регионе Selectel, ежедневные копии — в петербургском, ещё одна — у другого провайдера; при потере любой из них данные остаются в двух других, а инфраструктура поднимается заново по runbook — ситуация, когда авария одного дата-центра уносит данные, не повторится. Расходы на инфраструктуру сократились почти вдвое: до моих оптимизаций компания платила облаку около 27–28 тыс. ₽ в месяц, в сентябре я сократил счёт до ~23 тыс. ₽ и вывел из эксплуатации сторонний сервер дашбордов — ещё больше 1 тыс. ₽ в месяц, — а после переезда платформа стоит около 15 тыс. ₽ в месяц, и это уже с бэкапами, собственным GitLab с реестром образов и мониторингом ошибок, которых раньше не было. Безопасность выросла вместе с экономией: закрытая приватная сеть, доступ только через бастион по ключам, секреты разведены по контурам.
Цель Забрать маркетинговую аналитику со стороннего сервера и перестать выжигать лимиты внешних сервисов.
Действие Перенёс подсистему аналитики с внешнего Node.js-дашборда на стороннем хостинге в свой FastAPI-бэкенд. Источников несколько, и они разной природы: Битрикс24 — лиды и сделки по REST с OAuth 2.0 и выборкой батчами; Яндекс.Директ — расход по кампаниям из асинхронных отчётов; VK Ads — расход и баланс агентских клиентов; ещё два канала (Rispromo, Flocktory) API не дают вовсе, поэтому их расход считается по числу лидов и стоимости лида для конкретной школы, а сами лиды опознаются по идентификатору источника и UTM-метке. На этом собраны юнит-экономика, план/факт, сводка для управляющей компании и UTM-дерево с бюджетами по кампаниям. Обновление данных построил по модели stale-while-revalidate: ответ формируется из своей базы сразу, фоновая догрузка стартует только если данные старше TTL, а её завершение уходит клиенту push-уведомлением по Socket.IO — вместо того чтобы держать интерфейс в ожидании и постоянно опрашивать чужие API. Частоту обращений держит распределённый rate-limiter в Redis: не чаще одного запроса в 2 секунды на портал целиком, общая пауза для всех процессов при перегрузке; выборка идёт батчами до 50 команд в одном HTTP-запросе, а длинный первичный проход по истории сделал возобновляемым по курсору. OAuth-токены хранятся зашифрованными (Fernet).
Результат Когда аналитику никто не смотрит, обращений к внешнему порталу нет вовсе — риск попасть под ограничения со стороны чужого сервиса снят, а CRM, которой пользуется вся компания, не страдает от нашей синхронизации. Сторонний сервер выведен из эксплуатации: данные, токены и расходы на инфраструктуру вернулись в наш контур.
Цель Восстановить и автоматизировать маркетинговые и продажные интеграции: их держал подрядный сервис, и после его отключения связки встали.
Действие Разобрался в чужих сервисах с нуля и собрал связки заново — через Albato и роботов Битрикс24. Лиды из квизов Marquiz, форм Tilda, RIS.Promo, ВКонтакте и eLama попадают в CRM и проходят многостадийную обработку на роботах; в момент перехода сделки в «продано» хук уходит через Albato в GetCourse и запускает написанные мной бизнес-процессы: пользователь создаётся автоматически, попадает в группы по указанному в сделке абонементу и получает регистрационное письмо. Отдельной задачей довёл заявки из CRM до Яндекс.Метрики как офлайн-конверсии: Marquiz и Tilda → Albato → Битрикс24 → коннектор B242YA → Метрика. Всего прошёл 88 связок с маппингом под каждый источник — из них 49 под офлайн-конверсии Marquiz и Tilda, остальные по ВКонтакте, eLama, RIS.Promo и GetCourse, — и настроил сам коннектор на стороне Битрикс24. Где стандартных инструментов конструктора не хватало, внедрял в Tilda свой код — точечная автоматизация под задачи, которые иначе не собрать.
Результат Продажи и маркетинг обходятся без ручных операций: пользователь в GetCourse создаётся в момент продажи сам, рекламные кампании оптимизируются по заявкам из CRM. Схему задокументировал и обучил сотрудников, которые ведут её дальше. По роли я разработчик, а не интегратор, — разобраться в незнакомых сервисах, настроить их и передать знание команде оказалось быстрее, чем искать нового подрядчика.
Цель Дать управляющей компании единую картину по двум брендам, у которых нет общей базы.
Действие Научил детальные эндпоинты аналитики отвечать за соседний контур: по параметру бренда запрос проксируется во второй контур внутренним маршрутом с сервисным токеном, право на это есть только у двух ролей. На фронтенде — экраны с бейджем бренда и человекочитаемыми сообщениями вместо кодов 404, 403 и 502.
Результат Руководство видит оба бренда в одном интерфейсе, а контуры остаются изолированными: общей базы нет, у каждого свои данные, права и цикл релизов.
Цель Не дать двум брендам разъехаться в две несовместимые кодовые базы.
Действие Оставил один бэкенд и один фронтенд-бандл на обе сети: бренд определяется доменом и флагом сборки, а различия в логике, правах и оформлении вынесены в конфигурацию, а не в форк. Фронтенд организовал по Feature-Sliced Design (слои app / pages / widgets / features / entities / shared) — границы между доменами явные, и правка одного модуля не тянет за собой соседние.
Результат Новая фича выходит сразу на обе сети, а не пишется дважды; расхождения между брендами остаются на уровне настроек.
Цель Ускорить разработку и держать единое качество кода, когда над проектом работают разные ИИ-ассистенты и агенты.
Действие Внедрил собственный процесс ИИ-ассистированной разработки: единый свод правил для всех агентов (один источник истины плюс 11 скиллов-дисциплин — git, тесты, асинхронный код, отладка, документация, подготовка и ревью MR, релизы, автоматизация), доску со спринтами, этапами и задачами, Definition of Ready и Done, ритуал коммитов, обязательные тесты и линтеры до коммита, синхронную документацию. Моно-репо с оркестратором сам маршрутизирует запрос в нужный проект и задаёт агенту порядок чтения документов. Механику вынес в скрипты-гейты: синхронность доски с файлами спринтов, валидность ссылок в документации, перевод статусов задач — одной командой; весь ритуал проверок до коммита прогоняет единый preflight. Вторым контуром завёл журналы вне-спринтовых правок (maintenance) — придумал их под то, что не стоит открытия спринта: хотфикс на проде, правка CI, конфига или документации. Такая задача идёт коротким путём — коммит прямо в ветку разработки, без feature-ветки и без ожидания конца итерации, — но обязательно с записью в журнал: дата, тип (hotfix / chore / docs), затронутые файлы, пройденные гейты и первопричина. Журналов три: корневой на общие файлы моно-репо и по одному на бэкенд и фронтенд; правка, относящаяся к задаче спринта, уходит в файл спринта, а не в журнал, — граница зафиксирована в правилах. Сокращается только процедура, а не контроль: preflight, линтеры и тесты обязательны и здесь. Любой агент (Cursor, Windsurf, Devin, Claude Code, GitHub Copilot, JetBrains AI) читает одни и те же документы и пишет код единообразно. В ежедневной работе совмещаю несколько ассистентов и под задачу выбираю подходящий. Архитектуру, ревью и финальные решения держу за собой — агенты ускоряют рутину, а не заменяют инженера.
Результат — в темпе итераций, а не в ощущениях. С августа 2024 проект шёл двухнедельными спринтами силами команды, доска велась в Jira и Confluence. В мае 2026 я перевёл цикл на свою схему с доской прямо в репозитории — так историю проекта подхватывает не только человек, но и ИИ-агент. Итерация сжалась с двух недель до нескольких дней: спринт открывается и закрывается в пределах недели, чаще — за один-три дня, а задачи и спринты закрываются в разы быстрее, чем прежде выходило у команды; бэкенд и фронтенд ведут свои доски и свои спринты, срочное идёт через журналы вне-спринтовых правок. Так, после аварии облака платформа снова работала для пользователей уже через сутки, а вся инфраструктура — десятки задач от сети до бэкапов — была развёрнута заново одним спринтом за четыре дня. И это при сократившемся составе: раньше только на бэкенде и фронтенде работали четыре разработчика, рядом были DevOps, QA, PM и аналитики. Качество при ускорении держат гейты, а не надежда: код приходит с тестами и пройденными линтерами, документация не отстаёт от кода, ни одного изменения в обход доски или журнала. Процесс существует в артефактах, а не на словах: 11 скиллов-дисциплин и 34 документа живой спецификации бэкенда и фронтенда.
Цель Уметь починить прод в день обнаружения — и не расплатиться за это дисциплиной процесса.
Действие Развёл работу на два контура. Плановый: спринт, feature-ветка, MR, релизный тег. Срочный: правка вне спринта — запись в журнал, коммит в ветку разработки и, если ждать полный цикл дороже, чем чинить, «быстрый деплой прода» в обход тестового стенда. Что при этом не сокращается: предеплойный гейт, линтеры, тесты, тест, воспроизводящий сам баг, и обе постдеплойные проверки — сверка джобов и работоспособность стендов. Уровни доступа описал таблицей в правилах: какая формулировка задачи разрешает агенту push, merge, тег и запуск ручных джобов, а какая оставляет это за мной.
Результат Так закрываются реальные инциденты. В сводной таблице сравнения каналов сумма по строкам не сходилась с итогом: интерфейс скрывал каналы, у которых в периоде есть оплаты, но нет новых лидов, — дефект пришёл из эталонной реализации, которую мы переносили к себе. Нашёл первопричину, разделил ответ бэкенда на две временные оси (лиды периода и оплаты периода), закрыл регрессию unit- и e2e-тестами: разбор, фикс, релиз и выкладка на оба прода заняли один день. Отдельно разобрал инфраструктурный инцидент — тяжёлая CI-сборка исчерпала память на хосте, где рядом живёт балансировщик; смягчил на месте параметрами системы, а разбор и рекомендации (разнести роли хостов, ограничить память джобам, мониторить память и heartbeat раннера) зафиксировал в репозитории конфигурации. Инцидент живёт в журнале с первопричиной, а не в чьей-то памяти.
Открытый проект — облегчённая версия этого процесса. Во флагманском репозитории лежит один проект, один свод правил и 12 скиллов-дисциплин: там я обкатываю приём до того, как нести его в работу. Рабочий контур сложнее по устройству, и показать его нельзя — он под NDA. Там моно-репо с оркестратором, который маршрутизирует запрос в нужный проект: правила разнесены по уровням (общие в корне, проектные внутри бэкенда и фронтенда) и не дублируются, у каждого вложенного репозитория свои доска, спринты и спецификация — 34 документа на бэкенд и фронтенд, — а рядом живут отдельные репозитории моделей с миграциями, конфигурации балансировщика и Telegram-бота. Плюс то, чего в открытом проекте нет вообще: пять пайплайнов, три контура у каждого, деплойные гейты и runbook релиза. Открытый проект удобно читать, рабочий — точнее показывает, как я строю процесс на распределённой системе.
Сами мульти-агентные системы, локальные LLM, RAG и дообучение моделей — мой полигон: на нём учусь, проверяю идеи и оттачиваю этот процесс. Методику выложил в открытом виде во флагманском проекте ai-multi-agent-system — открыто лежат AGENTS.md, _board, _docs и .agents. Другие открытые наработки: local-rag-mcp, fine-tuning, ai-tg-bot. Среди принятых проектов смежных отделов есть сервис не на моём основном стеке — Laravel 11 на PHP 8.2, узел сбора и маршрутизации лидов. Он принимает вебхуки от семи внешних источников лидогенерации (лендинги и формы, квизы, рассылки, партнёрские агентства, отдельный поток с разбивкой по городам) и дополнительно по расписанию забирает лиды из рекламных кабинетов ВКонтакте. Каждый лид нормализуется и уходит в Битрикс24 нужного франчайзи по его городу, одновременно дублируясь в портал управляющей компании: продажи на местах и УК видят одну и ту же заявку. Плюс сквозное логирование и уведомления в Telegram. Разобрался в чужой кодовой базе на другом языке и веду её дальше — PHP у меня тоже подтверждён независимой оценкой Минцифры.