~/oybek.dev
работы
Frontend Lead Architect· HR SaaS

alfii

Founding frontend engineer для alfii — HR SaaS из ОАЭ, который ведёт реальный расчёт зарплат. Я отвечал за фронтенд с первого коммита: задал архитектуру, перестроил кодовую базу на React, перевёл Redux-Saga на RTK Query и переписал работу с деньгами так, чтобы расчёт зарплат шёл в центах от начала до конца. Кроме того, я сделал работу, которой большинство frontend-лидов не касаются: банковские переводы через DAPI для зарплат по WPS, биллинг на Stripe и полный пайплайн CI/CD и Docker.

Время деплоя
3–4 ч → 15 мин
Новые эндпоинты
−90% времени
Сборка бэкенда
Вдвое быстрее
Превью на PR
Мгновенно

alfii — это современная HR-платформа для ОАЭ: расчёт зарплат и выплаты по WPS, отпуска, смены, онбординг и данные сотрудников, под слоганом «простой и умный HR-софт для растущего бизнеса». Компания привлекла $2.5M на pre-seed раунде. Я пришёл как founding frontend engineer и остался в роли Frontend Lead Architect — а это значит, что я отвечал за фронтенд с самого первого коммита и за немалую часть инфраструктуры под ним.

Задача

У HR-стартапа на pre-seed есть одна задача важнее всех остальных: он обязан вести реальный расчёт зарплат, и вести его правильно, прежде чем ему вообще начнут доверять. Всё остальное — поток онбординга, календарь отпусков, планировщик смен — это базовый минимум, который можно дорабатывать итерациями. А вот в зарплатах ошибаться нельзя. Если ошибка округления превращается в неверную выплату, продукту конец.

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

Abstract neon-green circuit traces converging from many scattered nodes into a single clean spine on a near-black grid
Один фронтенд, в собственности с первого коммита

Что я построил

Я задал архитектуру и построил React-приложение от А до Я. Доставшаяся мне кодовая база требовала работы, поэтому значительная часть задачи свелась к тому, чтобы перестроить и улучшить сам React — превратить запутанный код в то, в чём команда может двигаться быстро.

Крупнейшим структурным решением был слой данных. Приложение работало на Redux-Saga — мощном, но тяжёлом инструменте: каждый эндпоинт означал типы экшенов, сагу, редьюсеры и селекторы, а асинхронная логика была размазана по файлам. Я перевёл всё это на RTK Query. Это свернуло почти весь шаблонный код в одно описание API с генерируемыми хуками, кэшированием и инвалидацией из коробки. После миграции подключение нового эндпоинта сократилось с полудня возни с сагами до нескольких строк — примерно на 90% меньше времени на каждый. Почему я выбираю React на реальных продуктах, я подробнее пишу на странице этой технологии.

Фронтенд не существует в изоляции. Бэкенд alfii написан на Python, и я плотно работал с этой командой, чтобы заранее определить API-контракты — формы запросов и ответов для каждой фичи — чтобы обе стороны могли двигаться независимо, не блокируя друг друга. Сначала контракт, потом обе команды строят под него.

Баг с деньгами

Самая трудная задача была не визуальной. Это были деньги. Валюта в JavaScript — это ловушка: 0.1 + 0.2, как известно, не равно 0.3, и как только ты начинаешь складывать зарплаты, удержания и надбавки по всему штату, дрейф чисел с плавающей точкой превращается в реальные деньги, которые не сходятся. Для зарплатного продукта это не косметический баг — это неверная выплата.

Я перевёл весь денежный путь на целочисленные центы от начала до конца — суммы хранятся, передаются и считаются как целые числа, и только на самом краю, для отображения, форматируются в десятичную дробь. Никаких float в вычислениях. Именно это решение позволяет alfii вести расчёт зарплат, которому можно доверять.

Two abstract neon-green numeric streams on a near-black grid — a jagged drifting line resolving into a single exact aligned rail
Деньги в центах, точно от начала до конца

Банковские переводы и биллинг

Выплата зарплат в ОАЭ идёт через WPS — Wage Protection System — поэтому выплатить зарплату значит провести деньги через банки, а не просто показать число. Я интегрировал DAPI для банковских переводов, чтобы зарплаты уходили реальными транзакциями, а не отчётом, который кто-то вручную перенабивает в банковский портал.

С другой стороны баланса — собственная выручка alfii. Я провёл полный анализ для биллинга на Stripe и вместе с командой бэкенда настроил подписочный воркфлоу, чтобы продукт мог брать оплату за себя. Поднять платежи от начала до конца — деньги уходят сотрудникам, деньги приходят от клиентов — это та работа, на которую я опираюсь как fractional CTO, и она лежит в основе того, как я строю веб-приложения.

DevOps, потому что кто-то должен был

Роль founding frontend в pre-seed компании редко ограничивается только фронтендом. Истории деплоя не было вовсе, поэтому я её построил.

Я настроил стратегию git-веток и стейджинга, затем полный пайплайн CI/CD, чтобы выкатка перестала быть ручной рутиной. До этого деплой был упражнением на 3–4 часа; после — около 15 минут. Я написал multi-stage Docker-сборку для Python-бэкенда с правильным кэшированием слоёв, что сократило время сборки бэкенда примерно вдвое. И я подключил превью-ссылки на каждый PR — у каждого pull request свой живой URL — чтобы продакт-оунеры могли сами кликнуть в изменение и проверить его, а не ждать созвона.

Abstract neon-green pipeline of nodes branching from a single trunk into staged stages, each branch ending in a small glowing preview tile, on a near-black technical grid
Ветка, стейджинг, превью — один живой URL на каждый pull request

Результат

alfii прошёл путь от ранней кодовой базы до платформы, которая ведёт реальный расчёт зарплат, платит зарплаты через банк и выставляет счета собственным клиентам — с фронтендом, построенным так, чтобы в него добавляли, а не воевали с ним.

Цифры, которые имели значение каждый день: деплои сократились с 3–4 часов примерно до 15 минут, добавление нового эндпоинта после миграции на RTK Query стало занимать примерно на 90% меньше времени, сборки бэкенда ускорились вдвое благодаря работе с Docker, а каждый pull request выходил с мгновенной превью-ссылкой для тех, кто решает, что выпускать.

Именно такую работу я беру на себя как senior-инженер, встроенный в команду-основатель — я владею поверхностью от начала до конца и инфраструктурой под ней, а не только теми частями, что вынесены в название должности. О том, как этот white-label, senior-developer формат выглядит на практике, я писал отдельно.

Есть похожая задача?

Начать проект