[{"data":1,"prerenderedAt":234},["ShallowReactive",2],{"project-ru-abandoned-carts":3,"recommendation-mention-sources":173},{"id":4,"title":5,"body":6,"category":131,"context":132,"cover":133,"coverAlt":134,"demo":135,"description":136,"extension":137,"featured":138,"locale":139,"meta":140,"navigation":141,"order":142,"path":143,"published":141,"repository":135,"results":144,"role":151,"seo":152,"slug":153,"stack":154,"stem":170,"year":171,"__hash__":172},"projects\u002Fru\u002Fprojects\u002Fabandoned-carts.md","«Брошенные корзины» — платный продукт inSales для продавцов",{"type":7,"value":8,"toc":116},"minimark",[9,14,18,21,25,28,32,37,45,49,52,56,63,70,76,80,83,87,90,96,100],[10,11,13],"h2",{"id":12},"задача","Задача",[15,16,17],"p",{},"Пока покупатель не оформил заказ, у магазина нет карточки заказа, с которой можно работать. Но товары уже выбраны, и продавцу полезно знать, что именно человек положил в корзину, на какую сумму и менялся ли состав. «Брошенные корзины» — платный продукт inSales, который позволяет с этим что-то сделать: найти незавершённые покупки зарегистрированных покупателей, изучить их и написать покупателю прямо из админки.",[15,19,20],{},"В продукте собраны аналитика, таблица корзин с фильтрами, детали и история корзины, история коммуникаций, шаблоны сообщений с предпросмотром и платный доступ. Всё это связано между собой: фильтр определяет получателей массовой рассылки, выбранная корзина даёт данные для предпросмотра, отправка обновляет таблицу и историю.",[10,22,24],{"id":23},"моя-роль","Моя роль",[15,26,27],{},"Был единственным frontend-разработчиком, работал с backend-разработчиком, продакт-менеджером, дизайнером и QA. Поначалу задача во многом состояла из макетов. Я превратил их в технические требования: сущности, состояния, пограничные случаи и структуру JSON для каждого блока — согласовал с дизайнером и backend-разработчиком. Дальше разбил работу на задачи, сделал интерфейс, расписал сценарии для QA и довёл раздел через ревью до релиза. Хранение корзин, расчёт аналитики и отправку по расписанию делает backend. Основная разработка шла с октября 2024 по апрель 2025 года итерациями, параллельно с другими задачами.",[10,29,31],{"id":30},"что-я-сделал","Что я сделал",[33,34,36],"h3",{"id":35},"корзина-это-история-а-не-строка-таблицы","Корзина — это история, а не строка таблицы",[15,38,39,40,44],{},"Покупатель может уйти, вернуться и поменять состав. Это одна корзина с несколькими сохранёнными версиями, а не две потерянные продажи. Модель мы согласовали вместе: сессия корзины, версия, актуальная версия, оформленный заказ и сообщения, привязанные к конкретной версии. В таблице номер корзины стабильный и не меняется при каждом обновлении, в деталях видны 10 последних версий. Один товар может лежать в корзине дважды с разными опциями, поэтому строки истории я различал по ключу позиции, а не по ",[41,42,43],"code",{},"id"," товара.",[33,46,48],{"id":47},"сообщение-показывает-корзину-на-момент-отправки","Сообщение показывает корзину на момент отправки",[15,50,51],{},"Если открыть сообщение из истории, интерфейс показывает состав корзины на момент отправки, а не текущий. Если подставить туда последнюю версию, история общения с покупателем исказится. Статусы «не отправлено», «ошибка» и «отправлено» в истории тоже различаются. После успешной отправки таблица и детали корзины перезагружаются, чтобы статус на экране не опережал сервер.",[33,53,55],{"id":54},"экран-обновляет-только-последний-ответ","Экран обновляет только последний ответ",[15,57,58,59,62],{},"Продавец печатает в поиске, листает страницы, открывает одну корзину за другой, не дожидаясь ответов. Запоздавший ответ на старый запрос не должен затирать свежие результаты. Я помечал поисковые запросы идентификаторами и отбрасывал устаревшие ответы, отменял загрузку дровера через ",[41,60,61],{},"AbortController"," при закрытии и перестал рендерить закрытые дроверы, чтобы скрытая панель не реагировала на изменения данных. Поиск, фильтры, пагинация и открытая корзина хранятся в URL: после перезагрузки или по присланной ссылке открывается тот же экран.",[15,64,65],{},[66,67],"img",{"alt":68,"src":69},"Настройки брошенных корзин: время, через которое корзина считается брошенной, и шаблон письма в редакторе кода","\u002Fimages\u002Fwork\u002Fabandoned-carts\u002Freminder-settings-email-template.webp",[15,71,72],{},[73,74,75],"em",{},"Настройки напоминаний: когда корзина считается брошенной, затем задержка и шаблон для каждого канала.",[33,77,79],{"id":78},"у-доступа-больше-двух-состояний","У доступа больше двух состояний",[15,81,82],{},"Одного признака «подписка есть» не хватало. Сервер отдаёт состояние пробного периода и его окончание, просрочку оплаты, счета, цену и остаток сообщений, и от этого зависят баннеры, кнопки и настройки. После запуска пробного периода настройки становятся доступны сразу. Платёжный компонент создаётся только при открытии диалога оплаты, чтобы скрытое окно не запускало свои операции.",[33,84,86],{"id":85},"три-способа-отправки-и-один-процесс-работы-с-шаблоном","Три способа отправки и один процесс работы с шаблоном",[15,88,89],{},"Продавец может написать одному покупателю, выбрать корзины на нескольких страницах для массового письма или SMS либо настроить автоматические напоминания по каждому каналу. Перед массовой отправкой форма показывает, у скольких выбранных покупателей нет нужного контакта, и предлагает их отфильтровать. Действие «выбрать вообще все корзины» мы сознательно не стали делать: оно могло дать большую нагрузку. Шаблоны редактируются в нашем общем редакторе на Monaco, а предпросмотр подставляет в Liquid товары, количество и суммы выбранной корзины.",[15,91,92],{},[66,93],{"alt":94,"src":95},"Предпросмотр письма с данными выбранной корзины рядом с формой сообщения","\u002Fimages\u002Fwork\u002Fabandoned-carts\u002Femail-preview-with-cart-data.webp",[10,97,99],{"id":98},"результат","Результат",[101,102,103,107,110,113],"ul",{},[104,105,106],"li",{},"У продукта 200+ активных платных подписчиков (на сентябрь 2026 года). Базовая цена — 1 000 ₽ в месяц после 7-дневного пробного периода.",[104,108,109],{},"В кейсе, опубликованном в мае 2025 года, inSales сообщает, что ретаргетинг по брошенным корзинам принёс одному магазину, «Хайтед», 100–350 тыс. ₽ в месяц, а 15% клиентов возвращаются и завершают покупку. Это результат одного магазина, а не средний по платформе, и он не сводится к работе frontend.",[104,111,112],{},"Аналитику выпустили в октябре 2024 года, остальной frontend доделали и выпустили к апрелю 2025-го.",[104,114,115],{},"Раздел адаптирован под десктоп и мобильные, а доработки date picker, фильтра и таблицы вошли в общий UI kit.",{"title":117,"searchDepth":118,"depth":118,"links":119},"",2,[120,121,122,130],{"id":12,"depth":118,"text":13},{"id":23,"depth":118,"text":24},{"id":30,"depth":118,"text":31,"children":123},[124,126,127,128,129],{"id":35,"depth":125,"text":36},3,{"id":47,"depth":125,"text":48},{"id":54,"depth":125,"text":55},{"id":78,"depth":125,"text":79},{"id":85,"depth":125,"text":86},{"id":98,"depth":118,"text":99},"Инструменты для продавцов","inSales","\u002Fimages\u002Fwork\u002Fabandoned-carts\u002Fcart-details-drawer.webp","Дровер «Детали корзины» в админке inSales: три товара, сумма корзины, кнопка оформления заказа и пустая история коммуникаций",null,"Аналитика, история корзин, фильтры и ручные, массовые и автоматические напоминания в админке inSales. Был единственным frontend-разработчиком; у продукта 200+ активных платных подписчиков.","md",false,"ru",{},true,5,"\u002Fru\u002Fprojects\u002Fabandoned-carts",[145,148],{"value":146,"label":147},"200+","активных платных подписчиков на сентябрь 2026 года",{"value":149,"label":150},"15%","клиентов одного магазина вернулись и завершили покупку, по кейсу inSales (май 2025)","Единственный frontend-разработчик: требования, контракты API, разработка, релиз",{"title":5,"description":136},"abandoned-carts",[155,156,157,158,159,160,161,162,163,164,165,166,167,168,169],"Vue.js","JavaScript","Data Visualization","REST APIs","Front-End Development","State Management","Responsive Web Design","Requirements Analysis","Technical Documentation","Vue Router","Monaco Editor","E-Commerce Development","Software Architecture","ApexCharts","Software as a Service (SaaS)","ru\u002Fprojects\u002Fabandoned-carts","Октябрь 2024 – апрель 2025","N_OyacD2uTVNN11T1K9jA_6IKJkwlXFK95drekc33iM",[174,184,189,204,214,219,224,229],{"stem":175,"name":176,"date":177,"featured":118,"published":141,"mentions":178},"recommendations\u002Fandrey-stikheev","Andrey Stikheev","2026-09-08",[179,182],{"project":180,"quote":181},"product-image-editor","Among his most notable projects was a sophisticated browser-based image editor built with TypeScript and Fabric.js, now used by thousands of merchants.",{"project":153,"quote":183},"He also developed the frontend for a paid abandoned-cart product and contributed to the production migration from Vue 2 to Vue 3.",{"stem":185,"name":186,"date":187,"featured":135,"published":141,"mentions":188},"recommendations\u002Fdaniil-churakov","Daniil Churakov","2026-08-27",[],{"stem":190,"name":191,"date":192,"featured":125,"published":141,"mentions":193},"recommendations\u002Fdmitry-sadovsky","Dmitry Sadovsky","2026-08-22",[194,197,199,202],{"project":195,"quote":196},"visual-storefront","For years he was the driving force behind our visual storefront editor — a large, complex application where merchants build their online stores.",{"project":180,"quote":198},"It became the tool merchants use to design product images right inside the admin panel — the kind of component companies usually buy rather than build.",{"project":200,"quote":201},"image-editor","What impressed me most was the infographic editor he built essentially from scratch: a full canvas-based graphic editor with artboards, shapes, text styling, templates, and undo\u002Fredo history, powered by an editor core he developed himself.",{"project":153,"quote":203},"Our abandoned carts functionality — with multi-channel customer messaging, communication history, and analytics — was largely his work, from UI down to the details of how requests are cancelled and states stay in sync.",{"stem":205,"name":206,"date":207,"featured":208,"published":141,"mentions":209},"recommendations\u002Fegor-fedkin","Egor Fedkin","2026-08-31",1,[210,212],{"project":180,"quote":211},"Today, the tool is actively used by around 3,000 users.",{"project":153,"quote":213},"It has already generated approximately twice the revenue needed to cover its development costs.",{"stem":215,"name":216,"date":217,"featured":135,"published":141,"mentions":218},"recommendations\u002Femmanuel-stephen","Emmanuel Stephen","2026-10-11",[],{"stem":220,"name":221,"date":222,"featured":135,"published":141,"mentions":223},"recommendations\u002Fevgeny-lonshakov","Евгений Лоншаков","2026-09-21",[],{"stem":225,"name":226,"date":227,"featured":135,"published":141,"mentions":228},"recommendations\u002Froman-gorbachev","Роман Горбачев","2026-09-17",[],{"stem":230,"name":231,"date":232,"featured":135,"published":141,"mentions":233},"recommendations\u002Fvladimir-bedarev","Bedarev Vladimir","2026-09-16",[],1793195987280]