Безопасность, соответствие и эксплуатация

Построено, чтобы держать данные клиентов многих компаний

LOYALTI мультитенантна с первой строки: в каждой таблице есть тенант, каждый запрос ограничен им, а платформа работает на стеке, который ваша команда эксплуатации уже знает.

Изоляция тенантов

Идентификатор тенанта в каждой бизнес-таблице и включённая защита на уровне строк в ключевых таблицах. Пользователи, ключи касс, вебхуки и токены принадлежат одному тенанту; доступ к чужим данным возвращает 403 и покрыт тестами. Панель суперадмина управляет тенантами, не заглядывая в их данные.

Аутентификация и доступ

JWT с короткими токенами доступа и refresh-токенами в защищённых cookie, хеширование паролей актуальным алгоритмом Symfony, двухфакторный вход для администраторов платформы, принудительная смена сгенерированного пароля, защита входа от перебора. Роли у пользователей и доступ только к выбранным магазинам у менеджеров.

Секреты и ключи

Ключи провайдеров SMTP, SMS, MAX, Telegram, Viber, push и S3 хранятся в базе зашифрованными ключом, который живёт только в окружении. Ключи касс и 1С хранятся хешами, открытый текст показывается один раз. Вебхуки подписывают тело.

Аудит и прослеживаемость

Каждое изменение в кабинете пишет запись аудита с автором, сущностью, действием и данными, помесячное секционирование. Движения баллов — журнал только на добавление; заказы хранят правила, которые дали им баллы. Журнал запросов 1С с маскированием ключей.

Персональные данные и согласия

Тексты согласий с версиями по тенанту, учёт того, кто какую версию и из какого источника принял, отказы от каналов, которые кампании соблюдают, реквизиты оператора в документах. Выгрузка и удаление данных участника — операции API. Платформа может размещаться на серверах в России, провайдеры SMS и хранилища копий российские.

Резервные копии и восстановление

Дампы базы по расписанию с хранением локально и в S3-совместимом хранилище, восстановление из кабинета, схема, которая разворачивается из двух миграций и перед каждым релизом сверяется с полной историей.

Развёртывание

Образы Docker, стек Swarm, один деплой до живого сервера

Два образа, бэкенд и nginx с собранным фронтендом, публикуются CI-конвейером. Стек Swarm с PostgreSQL и TimescaleDB, PgBouncer, Redis, RabbitMQ, пятнадцатью воркерами, планировщиком и сервисом резервных копий. Traefik завершает TLS. Первый деплой поднимает swarm, генерирует секреты, прогоняет миграции, импортирует города и переводы и проверяет health-эндпоинт.

Тот же стек работает на ноутбуке через Docker Compose для разработки, с Mailpit для почты и стеком мониторинга по запросу.

КомпонентВерсия
PHP8.5.12 с Symfony 7.4, DBAL без ORM
PostgreSQL16 с TimescaleDB, PgBouncer впереди
Очереди и кэшRabbitMQ 4, Redis 7
ФронтендNuxt 3, Vue 3, TypeScript, Tailwind
МониторингPrometheus, Grafana, Loki, Alertmanager
Тесты389 файлов PHPUnit, PHPStan на максимальном уровне, сквозные тесты Playwright

Эксплуатация внутри продукта

Очереди, логи и алерты в панели суперадмина

Глубина очередей, упавшие сообщения с повтором, логи приложения, правила алертов, запуски резервных копий и страница здоровья живут в панели, поэтому оператору платформы редко нужна консоль. Метрики Prometheus и health-эндпоинт подключаются к тому, за чем ваша команда уже следит.

Журнал аудита с фильтрами по действию и сущности