DEV Community

Cover image for Как я строил информационный портал для силовых ведомств и едва не потерял весь проект на этапе согласования
Dmitry Nosov
Dmitry Nosov

Posted on

Как я строил информационный портал для силовых ведомств и едва не потерял весь проект на этапе согласования

Три часа ночи. Я смотрю в экран, где красным светятся 47 незакрытых задач в Jira. Завтра — демо для заказчика. И вот тогда я ещё не знал, что самым сложным окажется вовсе не код.

Всё началось с относительно понятного технического задания: разработать информационный портал для сотрудников силовых ведомств. Внутренняя система, закрытая, для служебного пользования. Агрегация нормативной базы, новости приказов, личный кабинет с документами. Звучало как обычный корпоративный интранет, только с особыми требованиями к безопасности.

Первые два спринта шли хорошо.

Когда архитектура упирается в регламент

Я выбрал стек, который знал: React на фронте, Node.js с Express на бэке, PostgreSQL. Авторизация через JWT, роли, стандартный RBAC. Нарисовал схему, показал тимлиду, тот кивнул. Поехали.

Но примерно на третьей неделе выяснилось: требования к хранению данных у ведомственных систем совсем другие. Никакого облака. Только on-premise, сертифицированное железо, и — главное — всё должно проходить через отдел безопасности заказчика прежде, чем попасть на сервер.

Поэтому мой красивый CI/CD пайплайн с автодеплоем в Docker-контейнерах лёг на полку.

Этот скрипт я написал и никогда не запустил в проде

docker-compose up --build -d

"Это нельзя. У нас нет разрешения на Docker в защищённом контуре."

Я замер. Трижды перечитал письмо от безопасника. Потом написал: «А что можно?»

Ответ пришёл через сутки. Список разрешённого ПО, согласованного с их регулятором, занимал полстраницы. Там не было половины того, что я использовал.

Переписать или переосмыслить

Вот тут и начался настоящий проект.

Можно было сесть и методично переписать всё под ограничения. Но я понял: если просто адаптировать старое решение, получится лоскутное одеяло, которое постоянно будет расползаться. Лучше зайти иначе: принять ограничения как данность с самого начала и строить под них.

Первое, что ушло: автоматический деплой. Вместо него появился пакет обновления — архив с чётко описанной последовательностью действий для системного администратора заказчика. Звучит как шаг назад, но на практике это оказалось надёжнее: у них всегда был контроль над тем, что появляется в контуре.

release/
├── changelog.md
├── install.sh # только для тестовой среды
├── migrations/
│ └── 001_add_roles.sql
├── dist/
│ └── app.tar.gz
└── verify.sh # проверка целостности

Второе: хранение чувствительных данных. Никаких токенов в localStorage, никаких персональных данных в логах. Это кажется очевидным, но в обычной разработке часто срезают углы, которые здесь просто не существовали.

// Плохо — и в обычном проекте, и здесь тем более
localStorage.setItem('user_token', token);

// Так: httpOnly cookie, короткий TTL, флаг secure
res.cookie('session', token, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 30 * 60 * 1000 // 30 минут
});

Третье, и неожиданное: UX для людей, которые не работают с компьютером большую часть дня.

Сотрудники ведомств часто заходят в систему редко, по конкретной нужде: найти приказ, скачать форму, проверить статус документа. Они не будут изучать интерфейс. Поэтому всё, что требовало больше двух кликов, мы упрощали. Поиск — на главной странице, крупно, без лишних фильтров по умолчанию. Документы — скачать одной кнопкой, без регистрации формата.

Демо, которое чуть не провалилось по не-технической причине

За день до демо один из согласующих прислал список правок. Не технических, а терминологических: портал должен был использовать конкретную ведомственную терминологию, принятую в их приказах. «Пользователь» везде заменить на «сотрудник». «Уведомление» — на «служебное сообщение». Таких замен оказалось больше двадцати.

Я потратил вечер на поиск по всей кодовой базе и замену строк. Хорошо, что у нас были вынесены все UI-тексты в отдельный файл локализации ещё с самого начала, — это спасло несколько часов.

// i18n/ru.js — хорошее решение, принятое без особых причин в первый день
export default {
'user.greeting': 'Добро пожаловать, сотрудник',
'notification.new': 'Новое служебное сообщение',
'document.download': 'Скачать документ',
// ...
};

Демо прошло. Замечания были, но уже по содержанию, а не по архитектуре.

Что я вынес из этого

Сейчас, если кто-то спрашивает про разработку для закрытых ведомственных систем, я говорю одно: узнай об ограничениях инфраструктуры до первого коммита. Не на второй неделе, не после первого спринта. До.

Техническая часть решаема почти всегда. Архитектура переписывается, стек меняется. Но если ты две недели строил на облаке, а потом узнаёшь, что облака нет, — это больно и дорого.

Похожие продукты для этой аудитории уже существуют. Например, https://впогонах.рф/ — портал, ориентированный именно на сотрудников силовых ведомств, с учётом их специфики. Смотреть на такие решения полезно ещё до старта собственного: понять, какие задачи уже решены, а где есть пространство для манёвра.

Ограничения, с которыми мы столкнулись, я бы не назвал проблемой. Скорее, они заставили сделать систему чище: без лишних зависимостей, с явным разделением слоёв, с документацией, написанной для людей, а не для галочки.

Последняя строка в нашем changelog.md на финальном релизе была такой:

v1.0.0 — первый стабильный релиз. Потребовал 4 месяца, 3 переработки архитектуры и 1 ночь на переименование всех кнопок.

Это нормально. Так и работает разработка в условиях реальных ограничений.

Top comments (0)