Опыт
Сухая хронология с датами и стеком лежит в резюме. Здесь - то, что за ней стоит: задачи, на которых пришлось разбираться, и находки, которые обычно и обсуждают на собеседовании.
Продуктовая IT-компания (под NDA), 2025 - сейчас
Единственный фронтендер. 1352 коммита из 1550, около 3 500 тестов, 49 релизов. Пришёл, когда лежал демо-прототип на несколько десятков файлов; ни один его файл сегодня не существует.
Подделка отправителя в управлении записью. Обработчик команд записи приходил через WebRTC data-channel и не проверял, кто на самом деле отправитель. Участник звонка мог назваться кем угодно и навесить всем собеседникам залипший тост «идёт запись» вместе с заблокированной кнопкой. Поймал на ревью, чинил по TDD: первым делом тест, где один участник подделывает другого.
Микрофон, включавшийся сам. После переподключения клиент на мгновение снимал публикацию микрофона - шёл полный republish треков. Монитор здоровья устройств видел «микрофон отключён» и услужливо включал его обратно, против воли человека. Причина нашлась в поведении медиа-SDK; лечится хранением намеренного состояния мьюта отдельно от фактического.
Залипание навигации из-за ResizeObserver. В календаре один узел сидел под двумя ResizeObserver’ами, и один из них писал inline-переменную от собственной высоты элемента. Петля на сотню срабатываний за секунды не давала Next завершить переход: адрес менялся, экран нет, помогала только перезагрузка. Локально не воспроизводилось - диагностировал по HAR-логу.
Отдельно поставил CI со сборкой и подписью под macOS и Windows: Developer ID с нотаризацией, Windows через аппаратный токен по PKCS11. Встроил trivy в конвейер и довёл прод-образ с 49 находок до нуля.
Caerus, 2024 - 2026 - caerusrentacar.com
Сайт проката, владелец которого был одним из основателей GlobalRental. С мая 2024 сайт работал на движке GlobalRental: я поднял его вторым брендом через конфиг, им заменили прежний сайт проката. В августе 2025 развел фронтенды по двум репозиториям. В марте 2026 отделил его целиком. До этого на проде оба продукта крутили один бинарник на одной базе и различались только переменными окружения, разделения данных в схеме не было вообще. Разделять такое вслепую - верный способ уронить оба.
Начал с аудита прода: карта процессов, разница конфигураций, снапшот как точка отката. Потом своя база и свой бэкенд, перенос броней, машин и кабинета без потерь, автодеплой. Дальше багфиксы и поддержка, все 92 коммита этого этапа мои.
Кабинет стал рабочим календарем проката: около 1400 записей за два года. Прямых броней с сайта становится больше: 13 за 2025 год, 31 за 2026-й, в сезон до 10 в месяц. Стек - Next.js, Express, Prisma с PostgreSQL, ваучеры собираются в PDF на сервере, письма уходят через отдельный сервис.
Платформа психотерапии и коучинга, 2025 - 2026
Фронтенд в команде под отдельным лидом. Мой участок - фича «Супервизии» целиком, от онбординга до оплаты: поле «о себе как о супервизоре» в профиле, публичный поиск супервизоров с фильтрами и бесконечной подгрузкой, покупка супервизии клиентом, кабинет специалиста со способами оплаты, списком сессий, отменой и переносом, отражение супервизий в календаре отдельным цветом.
Next.js 15 на App Router в Nx-монорепозитории, Feature-Sliced Design, Zustand, CSS Modules. Фичу собрал через агентный spec-driven процесс: 4-5 часов работы против собственной ручной оценки в 19 часов.
EVIRMA, 2025 - evirma.ru
Расширение Manifest V3 для продавцов Wildberries: аналитика рекламы встраивается прямо в интерфейс маркетплейса. В команде 7-8 человек, 56 смёрдженных PR из 229 - второе место после техлида. По коммитам вышло бы 13%, но там squash-merge и один PR равен одной задаче.
Технически это работа в чужом продакшене, где ничего тебе не принадлежит: перехват fetch в
world: MAIN для чтения внутреннего API, ограничение частоты запросов по token bucket
(маркетплейс банит за частоту), фоновые задачи в service worker с восстановлением после
усыпления, React-инжекты в чужую вёрстку с изоляцией стилей через собственный плагин сборки.
Мои зоны: воронка продаж селлера с нуля, статистика кампаний по ключам и дням с расчётом ДРР и
СРР, экспорт в многостраничные книги Excel.
GlobalRental, 2023 - 2025
Агрегатор аренды авто в Черногории, globalrental.pro: клиент ищет машину по городу и датам и бронирует без регистрации, прокатчик ведет в кабинете календарь броней, сезонные тарифы и свой парк. Я был техническим директором, и роль менялась. В 2023 году вел студию-подрядчика Infinity со стороны инвестора: ТЗ и бизнес-логика, объем этапов, приемка, прод-сервер и деплой. В 2024 писал код вместе с разработчиком студии: на мне почта на react-email, Telegram-бот с уведомлениями о бронях, Sentry, админка со статистикой, расчет цен по сезонам. С декабря 2024 остался единственным разработчиком фронта и бэка: модерация, вход под партнером, валюты и страны, SEO-техника (ЧПУ, canonical, hreflang, schema.org), а в 2025 аренда яхт. Во фронтенде мои 331 коммит из 645, в бэкенде 136 из 294.
Stripe подключил и проверил боевым платежом, но реальные клиенты онлайн-оплатой так и не воспользовались: проект закрыли раньше. Next.js 14, Express, Prisma с PostgreSQL. На этом же движке с 2024 года работал Caerus.
App In The Air, 2019 - 2024, США
Пришел, когда у компании было мобильное приложение и не было веб-продукта, вырос от разработчика до тимлида команды из пяти человек. Скриншоты продуктов.
Сначала веб-покупка авиабилетов: поиск рейсов по socket.io с выдачей на лету, тарифы, пассажиры, оплата с 3DS. Потом отели и white-label виджет отелей, который авиакомпании встраивали к себе, в проде он работал у Smartavia. Дальше корпоративный B2B-портал: кабинет компании, сотрудники, корпоративные карты, travel policy, отчеты, авиа и отели. Первую версию портала мы сделали вдвоем с коллегой, потом я вел его фронтенд.
Попутно перевели фронтенд на Nx-монорепо, я обновил React 17 на 18, внедрил Next.js и настроил отдельный стенд в Cloud Run на каждую релизную ветку. Сайт appintheair.com тоже был на мне целиком. Фронтендеров нанимал сам: вакансия, техинтервью, тестовое с разбором кода.
webrise, 2016 - 2019
Агентство, много заказчиков и самый разнообразный период. Сбербанк Страхование - полный редизайн основного сайта и полтора десятка страховых калькуляторов, включая внутренние для сотрудников банка. Тема, которую любят копать: ошибка в расчётной форме выдаёт клиенту неверную цену полиса, поэтому расчёты покрывались тестами.
Ингосстрах - основной сайт и линейка калькуляторов. Образовательная платформа всероссийского конкурса с видео и чатом в браузере и лекциями преподавателей. Магазин Усачевского рынка с мобильными приложениями на React Native. Промо-акции Unilever, браузерная игра для Ritter Sport, цифровая платформа университета путей сообщения с подпроектами для студентов, старост и преподавателей.
Займер, 2014 - 2016 - zaymer.ru
Робот выдачи микрозаймов на карту без участия человека, Россия и Казахстан. Разрабатывал личный кабинет клиента и личный кабинет сотрудника. Laravel 5, KatanaFramework, MySQL, PostgreSQL, MongoDB, тесты на Selenium. Финтех с реальными деньгами: цена ошибки в расчётах измеряется в чужих рублях, и это дисциплинирует лучше любого регламента.
it-infinity, 2013 - 2014 - itinfinity.ru
Первые коммерческие сайты: редизайн существующих на чистых HTML, CSS и JS поверх 1С-Битрикс. Первая строчка в карьере.