Sharifa — бэкенд исламского приложения: аудит, доработка и DevOps
Студия-разработчик исламского мобильного приложения (Коран/мусхаф, азкары, дуа) · Исламское просвещение / мобильные приложения (религиозный контент)
Серверная часть живого исламского приложения работала в бою без тестовой копии: не работала регистрация, падали платежи, часть обещанного в задании отсутствовала.
- PHP
- Laravel
- MySQL
- REST API
- Laravel Sanctum
- Laravel Fortify
- Firebase Cloud Messaging
- YooKassa/платежи
- FFmpeg
- Docker
- Nginx
- GitLab CI/CD
- OpenAPI
- Vue 3 (админка — анализ)
- Flutter (мобильный клиент — анализ)
В цифрах
- 49
- таблиц в боевой БД (полный DDL-аудит)
- 27 / 40 / ~120 / ~56 / ~33
- контроллеров API / моделей / Actions / FormRequests / Resources в аудированном бэкенде
- 22
- бэкенд-задач из ТЗ разобрано (7 багов/нерабочее, 10 нового функционала, 5 доработок/конфигурации)
- 19
- содержательных изменений в бэкенде; 45 файлов, +2492/−195 строк
- 62
- коммита автора в sharifa_back за 06.2026 — наибольший вклад среди авторов за период
- 604
- постраничных шрифта QCF v2 мусхафа опубликовано (целостность sha256, версионирование)
- 38
- эндпоинтов мобильного Flutter-клиента сверено с бэкендом (816 dart-файлов)
- 5
- первопричин падений автотестов диагностировано и устранено (ветка fix/test-suite-failures)
Ключевое
- Начал с разбора, не меняя в бою ни строчки: весь код, база на 49 таблиц, окружение. Составил таблицу расхождений между заданием и тем, что реально работает.
- Разобрал 22 задачи и честно разделил их: сломанное, недостающее, ненастроенное. Заказчик увидел картину состояния, а не список работ.
- 62 коммита за месяц — наибольший вклад в проект среди всех участников за этот период.
- Опубликовал 604 постраничных шрифта Корана с проверкой целостности каждого файла: при таком объёме подмена одного файла иначе не заметна.
- Написал план переезда, при котором приложение перенастраивается на новый адрес сервера без выпуска новой версии в магазинах.
Задача
Sharifa — мобильное приложение для мусульман: Коран с постраничным мусхафом, азкары, дуа, хадисы, гайды по намазу, групповые задания и счётчики чтения. Приложение живое и обслуживает реальных пользователей в обоих магазинах приложений.
Серверная часть к моменту, когда меня подключили, была уже большой, но работала в рискованном состоянии: единственный экземпляр в бою, без тестовой копии, с отладочными настройками на боевом сервере. Не работала почта — а без неё нельзя зарегистрироваться. Падали платежи. Не были настроены фоновые задачи. Часть обещанного в техническом задании просто отсутствовала: синхронизация закладок между устройствами, постраничный Коран, удаление аккаунта.
Что сделано
- Начал с разбора, не меняя в бою ни строчки: весь код, вся база на 49 таблиц, окружение и инфраструктура. Составил таблицу расхождений между техническим заданием и тем, что реально работает, — по каждому пункту с доказательством, а не по памяти.
- Разобрал 22 задачи из задания и разделил их честно: сломанное, недостающее, ненастроенное. Заказчик увидел картину состояния системы, а не список работ.
- Починил критичное — каждую правку отдельно и с тестами: оплата перестала падать на пустых реквизитах, из ответов сервера убраны поля, которые не должны были уходить наружу, добавлены ограничение частоты запросов и защита от перебора.
- Дописал то, чего не было: синхронизация закладок с папками и заметками, удаление аккаунта по требованию пользователя, выдача постраничных шрифтов Корана, обработка заявок.
- Опубликовал 604 постраничных шрифта мусхафа с проверкой целостности каждого файла и версионированием — при таком объёме повреждение или подмена одного файла иначе не заметны.
- Написал инструкцию развёртывания на чистый сервер и план переезда, при котором приложение перенастраивается на новый адрес без выпуска новой версии в магазинах.
Итог
22 задачи из технического задания разобраны, по ним внесено 19 содержательных изменений в серверную часть. За месяц работы это оказался наибольший вклад в проект среди всех участников — 62 коммита.
Регистрация заработала: до этого её блокировала неработающая почта. Оплата перестала падать на пустых реквизитах. Из ответов сервера убраны поля, которые не должны были уходить наружу. Появились синхронизация закладок между устройствами, удаление аккаунта по требованию пользователя и постраничный Коран — 604 шрифта опубликованы с проверкой целостности каждого.
Пять причин, по которым падали автотесты, найдены и устранены: набор тестов снова показывает состояние кода, а не шум, — иначе им перестают пользоваться.
Технические детали
Решение и подход
Бэкенд построен на чистом слоёном Laravel 11: тонкие контроллеры + одноклассовые Action-объекты (одна операция = один класс), Form Requests для валидации, Resources для формы ответа, две параллельные системы фильтров и отдельный Sorter. Мультиязычность — через модели-спутники *Translation + глобальный LocaleScope, локаль из заголовка Mobile-locale; админы намеренно обходят скоуп. Авторизация — Sanctum (мобильное API) + Fortify (кастомная верификация по коду), роли через колонку role и AdminMiddleware. Свои доработки я встраивал строго в существующий паттерн домена (Action/Request/Resource), сохраняя консистентность.
Каждая фича шла полным циклом spec → TDD-план → реализация → независимое ревью, отдельной веткой feature/*/fix/* с интеграцией в integration/staging и проверкой бесконфликтной сборки. Шрифты мусхафа (~344 МБ) намеренно вынесены из git и раздаются статикой nginx с агрессивным кэшем; манифест-эндпоинт независим от раздачи файлов (до публикации отдаёт штатный 503/404). Все правки прода предусматривают бэкап конфига и откат за один шаг, а работа с боевой БД/сервером — только read-only и с явного согласия.
Стек и обоснование
PHP 8.3 / Laravel 11 / MySQL 8 — существующий стек продукта; доработки следуют его конвенциям. Sanctum + Fortify — токены для мобильного API и кастомная верификация. Firebase Cloud Messaging (kreait/laravel-firebase) — пуши; YooKassa SDK — платежи/донаты; FFmpeg — аудио азкаров. Nginx + PHP-FPM + GitLab CI — раздача и деплой; supervisor + cron — недостающие на старом проде queue/scheduler. OpenAPI (Redocly/Spectral) — контракт API. Смежно проанализированы Vue 3 (админ-SPA) и Flutter (Riverpod, dio, Drift, auto_route, Freezed) — мобильный клиент; их разработка велась другими командами, моя роль здесь — анализ интеграции и контракты.
Инженерные вызовы
- Боевой прод без страховки. Единственный экземпляр без staging, dev-конфигурация и открытый
APP_DEBUG— любые проверки только read-only, изменения с бэкапом и откатом; раздача шрифтов проектировалась так, чтобы не задеть соседний мультитенантный проект (регресс-проверка после каждого reload nginx). - Расхождение «приложение живёт, домен отключён». Установлено, что фактический адрес бэкенда не захардкожен, а приходит из Firebase Remote Config (проект
sharifa-cmd), без дефолтов в коде, — это объяснило поведение прода и задало безопасную стратегию переезда (переключение URL без релиза в сторах). - Каскад блокеров из аудита. Неработающая почта → 0 авторизованных пользователей → мертвы все auth-фичи (трекинг, салаваты, группы); платежи сломаны на уровне кода + пустые креды. Зафиксирована причинно-следственная цепочка и приоритезирована «Фаза 0» разблокировки.
- Передача без push-доступа. На раннем этапе фича шрифтов оформлена как автономный git-bundle + 6 патчей с инструкцией fast-forward — чтобы команда с доступом могла принять её без потери истории.
- Две параллельные системы фильтров и нюансы локализации (админ обходит
LocaleScope) требовали аккуратной сверкиuse-импортов перед каждой доработкой.
Услуги в проекте
- аудит
- доработка существующего
- разработка
- деплой
- DevOps
- безопасность
- миграция (планирование переезда)
- интеграция мобильного клиента
- API-контракт/документация
- ПДн/GDPR