Ключевые результаты:
Time-to-Action
~20 сек → ~5 сек
Не открывая отдельное приложение
Конверсия в онбординг
11%
≈20 из 200, холодная аудитория
Активные пользователи
50+
Без рекламы и продвижения
v2
В тестировании
Бот + PWA — новая итерация
Контекст
Я работаю Product Designer в рекламном агентстве. В июне 2024 у меня родился сын.
С первых недель я столкнулся с тем, что все существующие приложения для трекинга ребёнка раздражают, а не помогают. Я начал делать своё — не ради портфолио, а потому что реально нужно было.
Моя роль в проекте
Полная самостоятельность: discovery, проектирование, дизайн, продуктовые решения — без команды.
Ресурсы
- Время разработки до текущего состояния (v2.19.140):
~4 месяцапараллельно с основной работой и маленьким ребёнком - Бюджет на инфраструктуру и AI-инструменты:
~$300(VPS, БД, Coolify, Claude, Cursor) - Команда:
1 человек
Telegram-бот + PWA + платёжная система + аналитика + деплой — стал возможен за такой срок и бюджет только благодаря AI-assisted разработке. Архитектурные решения, продуктовые гипотезы, UX-логика — моя работа; кодовая реализация — совместная.
Метрика, которую хотел улучшить
Time-to-Action — время от решения «записать кормление» до момента, когда запись сохранена. У конкурентов — ~20 секунд. Это критично, когда ребёнок кричит и руки заняты.
Проблема
Откуда взялась
Я сам был пользователем. В состоянии хронического недосыпания нужно было зафиксировать: когда последний раз кормили, сколько выпил, когда уснул. Существующие приложения создавали барьер на каждом шаге.
Данные
Я изучил ТОП-5 приложений рынка: Baby Tracker, Glow Baby, Huckleberry, Sprout Baby, BabyConnect.
| Критерий | Конкуренты | Проблема |
|---|---|---|
| Регистрация | Обязательная (Email / Apple ID) | Барьер на входе |
| Время до 1-й записи | 20–60 сек (онбординг) | Слишком долго с ребёнком на руках |
| Синхронизация | Через email-инвайты (часто лагает) | Второй родитель выпадает из процесса |
| Ввод данных | 4–5 кликов (выбор типа → объём → время) | Когнитивная нагрузка при недосыпе |
| Реклама | Агрессивная, блокирует функции | Вызывает раздражение, а не помощь |
Вывод из бенчмарка
Все конкуренты проектировали для «спокойного родителя за столом», а не для «измотанного родителя в 3 ночи с ребёнком на руках». Каждый барьер — регистрация, навигация, лишний тап — в нормальном состоянии незаметен. В состоянии недосыпания он останавливает.
Исследование
Глубинные интервью
Провёл 5 интервью с родителями детей до 9 месяцев.
Критерий отбора: используют или пробовали использовать трекеры.
Ключевые вопросы:
- Как вы сейчас фиксируете кормления и сон?
- Когда данные теряются?
- Почему перестали пользоваться трекером (если перестали)?
- Что должен делать идеальный трекер?
Синтез интервью
| Боль | Цитата | Решение |
|---|---|---|
| Когнитивная нагрузка | «Мой мозг перестал работать после родов» | Один тап = одно действие |
| Высокое трение | «Пока найдёшь приложение, ребёнок уже орёт» | Telegram — уже открыт |
| Проблема синхронизации | «Муж не знает что я уже кормила час назад» | Общий чат = мгновенная синхронизация |
| Регистрация | «Ещё одно приложение с паролем — нет» | Вход через Telegram ID без регистрации |
| Реклама | «Оно показывает рекламу когда ребёнок не спит» | Никакой рекламы |
JTBD — Job-to-be-Done
Из интервью я сформулировал три ключевых Job Story:
Job 1 (основной)
Когда ребёнок только что поел или уснул — и у меня 5 свободных секунд — я хочу быстро зафиксировать событие, чтобы потом не держать это в голове и не путаться.
Job 2
Когда муж/жена берёт ребёнка — я хочу, чтобы он автоматически видел последнее состояние, чтобы нам не нужно было передавать информацию словами.
Job 3
Когда педиатр спрашивает о том, как младенец спит и ест — я хочу показать ему точную статистику, чтобы врач мог принять правильное решение.
Гипотезы и их проверка
Перед проектированием я сформулировал 4 гипотезы и проверил их запуском.
| Гипотеза | Как проверял | Результат |
|---|---|---|
| Если перенести трекинг в Telegram — Time-to-Action упадёт до <5 сек | Запустил бота, замерил время на ~10 людях (родственники и друзья, iOS) | ✅ ~5 сек vs ~20 у конкурентов |
| Родителям нужен выбор конкретного бренда смеси из-за разницы в дозах | Реализовал онбординг с выбором брендов, изучил дозировки | ❌ Дозировки ТОП-брендов идентичны. Убрал выбор — упростил онбординг |
| Классическое нижнее меню (Reply) удобнее для навигации | Проверка рендеринга на iOS и Android | ❓ Нестабильный рендеринг клавиатуры на ряде устройств |
| Сверка с нормами ВОЗ снизит тревогу родителей и станет драйвером retention | Внедрил прогресс-бар и нормы по возрасту в дашборд | ✅ Пользователи заходят «проверить статус», не только записать |
❌ Про смеси
Пользователи просили добавить конкретные бренды смесей. Я проанализировал дозировки и убрал этот выбор вообще — потому что разницы нет, а лишний шаг в онбординге создаёт барьер.
❓ Про меню
Нестабильный рендеринг — это проблема платформенной совместимости, не UX-флоу. Сам флоу был правильным. Переход на Inline-кнопки сохранил логику взаимодействия, но потребовал переработки всего UI-слоя бота.
Вывод: платформенный тест совместимости должен идти до проектирования UI-компонентов, а не после.
v1 — MVP: только Telegram-бот
Первая версия продукта — исключительно бот. Никакого PWA. Вся логика, весь UX — внутри Telegram.
Онбординг в боте
Язык (Выкл.) → Consent → Создание ребёнка → Дата рождения → Тип питания → Часовой пояс → Ночной режим → Подтверждение.
Ключевое преимущество платформы (Telegram — без регистрации) даёт право задать эти вопросы: пользователь ещё не устал от форм. Часовой пояс — единственное поле со смарт-дефолтом (определяется автоматически); остальное можно поменять позже.
State-Aware UX
Вместо классического дерева экранов я спроектировал линейный State-Aware Flow — бот сам определяет точку входа по текущему состоянию ребёнка и показывает единственное релевантное действие.
Проблема стандартного подхода
Каждый раз: Вход → Добавить → Выбор действия → Форма с полями. Это 3–4 клика и когнитивная нагрузка.
Моё решение
Всё через Inline-кнопки и текстовые сообщения — в Telegram это максимум доступного инструментария без кастомного UI.
Смарт-функции при фиксации кормления:
- Норма по возрасту в сообщении — родитель видит «220 мл — норма» до ввода
- Последние кормления показаны как контекст
Метрики — v1
Измерения проводились самостоятельно и на малой выборке. Это MVP-валидация, а не формальный UX-тест.
| Метрика | Результат | Контекст |
|---|---|---|
| Time-to-Action | ~5 сек vs ~20 у конкурентов | Самозамер + ~10 человек на iOS |
| Конверсия в онбординг | 11% (≈20 из 200) | Холодная аудитория: группа мамочек, без рекламы |
| Синхронизация между родителями | 80% семейных пар подключили второго пользователя | На выборке активных пользователей MVP |
| Активных пользователей | 50+ без рекламы и продвижения | Данные v1, MVP отключён |
v1 → v2: почему добавили PWA
MVP подтвердил гипотезу: бот как инструмент быстрой фиксации работает. Но использование показало границу — бот не справляется с «глубоким» функционалом.
Что не влезало в бота:
- История событий за несколько дней — в боте это либо бесконечный скролл сообщений, либо через кнопки навигации по неделям, но листать события в чате неудобно
- Статистика — отдельные блоки по кормлению и сну в сообщениях, без визуализации и сравнения периодов
- Настройки — занимали много экранов бота
Всё это было реализовано и протестировано в v1. Проблема не в том, что не влезало — а в том, что бот не подходит для этого типа взаимодействия: аналитика и настройки требуют экрана, а не чата.
Решение
| Бот | PWA |
|---|---|
| Быстрая фиксация (Job 1, Job 2) | Аналитика и контекст (Job 3) |
| Уведомления | История, статистика, настройки |
| Работает в фоне | Открывается, когда нужна глубина |
Бот стал проще — часть функционала ушла в PWA. PWA взяла на себя всё, что требует экрана и времени.
Настройки ребёнка — от модалок к экрану. Первая версия раздела «Настройки» в PWA собиралась быстро, без продуманной структуры — несколько отдельных модалок (уведомления, доступ, профиль, режим дня), лишь бы функция была.
Когда редизайн дизайн-системы дошёл до этого раздела, встал вопрос формы: контент настроек ребёнка оказался объёмнее остальных разделов приложения, и шторка (паттерн для быстрых действий с малым числом шагов) для такого объёма не подходила.
Решение — вынести настройки ребёнка на отдельную полноэкранную страницу, а внутри самой формы сократить число полей до необходимых.
Это плановая зачистка технического долга — дизайн-система дошла и до этого раздела.
v2 — Бот + PWA (в тестировании)
PWA не дублирует бот — у неё другая роль: показать, что произошло, и дать контекст. Бот — это фиксация (скорость), PWA — статус и анализ (глубина).
Общие паттерны
Сводка (дашборд) → История → Статистика → Настройки — 4 вкладки нижней навигации. Порядок отражает частоту использования: сводку проверяют чаще всего, статистику — реже, настройки — редко.
Три паттерна закреплены как правило на уровне всего приложения, а не выбираются каждый раз заново:
| Паттерн | Когда использовать |
|---|---|
| Полный экран | Контент большой, нужна навигация внутри, пользователь задерживается |
| Шторка | Быстрое действие с небольшим количеством шагов, возврат назад |
| Попап | Подтверждение, форма из 1–2 полей, деструктивное действие |
Пример применения: фиксация кормления/сна — шторка (короткое действие, возврат на дашборд сразу после); настройки ребёнка — полноэкранная страница (объём контента перерос шторку). Дальше — как это правило работает на каждой конкретной странице.
Страница: Дашборд
Хедер
Решает три задачи одновременно: контекст, доступ и персонализация.
Иконка и имя ребёнка — не декоративный элемент, а быстрый переход в настройки профиля. Рядом — кнопка смены ребёнка: она появляется только если детей больше одного, иначе не занимает место.
Переключатель темы вынесен в хедер намеренно — это частое действие, не настройка.
Статус-карточки и персонализация
- Статус-карточки «следующее действие» — система сама считает и показывает «Через 1 ч 20 мин — около 14:45»
- Карточка возраста и периода развития — контекст, почему ребёнок ведёт себя именно так
- Акцентный цвет под ребёнка (на Free — для одного, в Premium — свой цвет у каждого) — персонализация и быстрое узнавание активного ребёнка
- Светлая и тёмная тема — выбор пользователя
Логика статус-карточек: каждая показывает два числа — сколько осталось до события (оценить приближение) и в котором часу это будет (привязать к привычному времени). Обе карточки равнозначны — это не иерархия кормление > сон, а плотность данных.
Быстрая запись — разделение обязательного и настраиваемого
Блок прошёл несколько итераций, прежде чем сложился в текущий вид: фиксированная пара «Кормление + Сон» всегда сверху — это два самых частых действия (Job 1), их доступность не должна зависеть от того, что пользователь настроил.
Ниже — до четырёх настраиваемых кнопок под второстепенные действия: у каждого родителя свой набор (кому-то важен «Подгузник», кому-то «Прогулка»).
Управление составом и порядком вынесено в отдельную шторку, а не в инлайн-редактирование на самих кнопках — если разрешить менять их прямо на дашборде, один и тот же элемент одновременно и «нажми — запишется», и «нажми — настраивается», и непонятно, в каком он сейчас режиме. Шторка разводит эти два состояния явно.
Порядок внутри шторки меняется перетаскиванием пальцем, а не стрелками ▲▼: стрелки технически работали, но были чужеродны на фоне остальных прямых жестов приложения — свайпов шторок, перетаскивания карточек в Статистике.
Сетка адаптируется по числу включённых кнопок (1–4 колонки) — под конкретный набор, без пустых мест под неактивные слоты.
Тот же принцип — не патчить решение, если оно не готово, а временно убрать — применён к кнопке смены ребёнка в хедере: шеврон «настройки ребёнка» в попапе выбора убран целиком, когда выяснилось, что иконка не сообщает о своей функции, а для активного ребёнка вообще не срабатывает.
Страница: Фиксация кормления и сна
Шторка — по тому же правилу, что и везде в приложении: короткое действие с небольшим числом шагов, пользователь возвращается на дашборд сразу после. Паттерн взят из анализа банковских приложений: открывается поверх, закрывается свайпом, не требует возврата назад.
Почему табы внутри шторки: у каждого типа кормления разные параметры ввода (смесь: объём; грудь: сторона; таймер: запуск/пауза/стоп). Табы разделяют три разных формы под одним действием.
Страница: История
Free: последние 7 дней. Premium: 90 дней + навигация по месяцам + редактирование. Лимиты — часть модели монетизации, а не отдельное UX-решение: пользователь видит структуру (группировка по дням, редактирование) на обоих тарифах, разница только в глубине.
Edge cases: пустое состояние за день, paywall-баннер при достижении лимита.
Страница: Статистика — не фиксированный отчёт, а настраиваемая система
Бар-чарты по дням: кормления (грудь + смесь), сон (ночной + дневной). Период: неделя / месяц. Экспорт Excel для педиатра.
Страница устроена в три независимых слоя, каждый со своей настройкой:
Карточки-показатели. Список кандидатов (кормления, объём, сон, подгузники — и ещё 8 будущих метрик) вынесен в отдельную шторку с переключателями и drag-реордером. Реализованные метрики работают сразу; нереализованные показаны в том же списке притушенными, с бейджем «скоро» — не спрятаны, но и не притворяются рабочими.
Правило появилось из конкретного промаха: кнопка «Прикорм» в интерфейсе выглядела полностью готовой, но по тапу не происходило ничего — пользователь не мог отличить баг от «пока не сделано».
С тех пор это правило действует одинаково для каждого типа события — везде, где эти типы встречаются: быстрая запись на дашборде, выбор типа события, карточки статистики.
Графики. До 3 графиков одновременно, каждый — независимый выбор метрики (только те, где есть данные по дням) и вида отображения (бар/линия). Защита от дублирования превентивная: метрика, уже занятая одним графиком, становится недоступной для выбора в другом — не постфактум-ошибка, а невозможность совершить её физически.
Сравнение периодов — пример полного цикла итераций в одну сессию, не фичи-галочки. Требование родилось из Job 3 (показать педиатру динамику): «если закралось подозрение, что ребёнок стал меньше есть или спать — увидеть разницу».
Сначала — переключаемое сравнение с отдельной кнопкой-тумблером; после обсуждения тумблер убрали — сравнение с предыдущим периодом сделали включённым всегда, без возможности выключить.
Контрол сначала жил внутри карточки первого графика, затем — при добавлении второго графика — переехал в общую шапку страницы, потому что относился к обеим карточкам сразу, а не только к одной.
Все три слоя — один и тот же паттерн настройки (шторка со свичами, где применимо — drag-реордер), применённый к разным типам контента одной страницы, а не три случайных решения.
Дизайн-система
Продукт построен на shadcn/ui (Radix UI primitives) поверх собственного слоя токенов и компонентов.
Почему shadcn/ui:
- Компоненты copy-paste — полный контроль над кодом без зависимости от внешней библиотеки
- Radix UI примитивы — доступность из коробки
- Tailwind + CSS-переменные — простое управление темой
Шрифт — системный, типографика — своя. Кастомного шрифта нет: приложение работает на системном стеке платформы (-apple-system/Segoe UI/Roboto, без единого @font-face в проекте).
При этом шкала размеров и весов — не хаотичный набор значений на каждом экране, а последовательная система: от мелких подписей и лейблов до крупных акцентных чисел на статус-карточках, с понятной ролью у каждой ступени.
Акцентный цвет — привязан к ребёнку, а не к теме. Цвет можно настроить и на Free — но только для одного ребёнка, потому что Free вообще ограничен одним профилем. Premium снимает именно это ограничение: детей может быть несколько, и у каждого — свой цвет из 6 вариантов; при переключении активного ребёнка цвет переопределяется через CSS-переменную — весь UI-кит и кастомные компоненты перекрашиваются сразу, без похода в настройки темы.
Цвет виден не только в PWA — он отражается и в боте, цветным кружком в шапке главного меню, который меняется вместе с активным ребёнком. Это решает две задачи разом: персонализацию и быструю ориентацию — если детей двое и больше, по цвету сразу понятно, кто сейчас выбран, без чтения имени.
На уровне данных цвет хранится как токен, а не как значение: в базе — семантический ключ («pink»), а не hex-код; конкретный оттенок определяется целиком на стороне PWA-темы, поэтому смена оттенка не требует миграции данных.
Компромисс: «чистые» shadcn-примитивы (Select, Popover, Calendar) сидят на статичных дизайн-токенах и не подхватывают акцентный цвет — они остаются фиолетовыми независимо от цвета ребёнка. Риск задеть уже работающие элементы не оправдывал исправление ради визуальной идеальности на некритичных контролах.
UI-кит — своя надстройка, не голый shadcn. Базовые интерактивные элементы (кнопка, иконка-кнопка, аватар, бейдж) вынесены в собственный слой поверх shadcn-паттерна, но на кастомных CSS-переменных, а не на статичных shadcn-токенах — иначе тема и персональный акцент ребёнка просто перестали бы работать в новых компонентах. Цель — одна точка изменения: правка радиуса или цвета в одном файле применяется сразу везде, а не по каждой странице вручную.
Тема — ручное переключение, без авто-определения по системе. Светлая и тёмная тема — через CSS-переменные, переключатель в хедере.
Кому-то нравится светлая тема в целом, но ночью нужно быстро убрать яркость экрана — переключатель даёт сделать это сразу при заходе в приложение, не завися от системных настроек телефона. Автоматическое определение темы по системе технически возможно, но пока не сделано: без проверки на пользователях не вижу смысла добавлять эту сложность заранее.
Документация системы — не разовая справка, а инструмент проверки. Токены, компоненты и сопоставление с переменными Figma сведены в одну страницу с постоянной сверкой против реального кода — не «как должно быть», а как есть на самом деле. Эта дисциплина уже находила настоящие расхождения между тем, что задокументировано, и тем, что в проде: например, у BottomNav не было фокус-кольца, хотя оно есть у всех остальных интерактивных компонентов, — баг всплыл именно при попытке свести всё в одну систему координат. Подробнее о том, как устроена эта документация и что она вскрыла — на странице дизайн-системы.
Что не сработало
Фидбек от пользователей MVP был нерелевантным
30 первых пользователей знали мою жену — их запросы были продиктованы желанием помочь, а не реальной болью. Пример со сменами смесей (см. «Гипотезы и их проверка») — как раз оттуда: просьба, продиктованная заботой, а не проблемой. Научился различать «хотелки» и реальные проблемы.
Медицинские данные — юридический барьер
Хотел добавить медицинский блок: прививки, визиты к педиатру, история болезней. Данные о диагнозах и прививках в России попадают под специальные персональные данные (152-ФЗ, ст. 10) — для их обработки нужна отдельная инфраструктура и сертификация. Функционал отложен. Пока — только бытовые данные (кормление, сон, замеры).
Выводы
Что сработало:
- State-Aware UX — пользователь всегда видит одно релевантное действие, не меню
- Telegram как платформа — нет регистрации, мгновенная синхронизация
- Решения на основе данных, а не запросов (убрал выбор смеси)
- Разделение бот/PWA по ролям: скорость vs глубина
Что я бы сделал иначе:
- Протестировал рендеринг Reply-клавиатуры до проектирования флоу
- Задокументировал фидбек от MVP-пользователей формально
- Раньше выделил PWA в отдельный слой
Кейс обновляется по мере развития продукта. Последнее обновление: 2026-08-26.