Ваш список покупок сливают 946 компаниям. Я же написал свой

Как инди-разработчик на Kotlin Multiplatform собрал семейное приложение на 3 платформы - с физикой конфетти, растущим маскотом и деплоем через shell-скрипт.

Я поручил AI исследовать privacy policy Listonic, потому что мне нужно было понять, почему бесплатное приложение для покупок весит 80 мегабайт и тратит батарею как 3D-шутер. Оказалось, причина простая: там внутри рекламная биржа размером с небольшую корпорацию.

946 компаний-партнёров. Срок хранения данных - 10 лет. Ты вбиваешь "хлеб белый", а на другом конце мира аналитический отдел Unilever обновляет твой потребительский профиль.

Я закрыл документ и подумал: а что если сделать приложение, которое просто... ничего этого не делает?

Ваш список покупок сливают 946 компаниям. Я же написал свой

Рынок, который застрял между блокнотом и шпионажем

Прежде чем писать первую строчку кода, я неделю прожил внутри чужих приложений. Устанавливал всё, что находил по запросу "список покупок" - от топа выдачи до последней страницы.

Картина получилась странная. Весь рынок - это два полюса с пустотой посередине.

Полюс первый: заметки. Яндекс Заметки, Заметки Mail.ru и им подобные. Технически в них можно вести список покупок. Практически - это как забивать гвозди микроскопом, только наоборот: слишком примитивно для задачи. Совместный доступ? Скриншот в мессенджер. Синхронизация? "Перешли мне ещё раз, не вижу".

Полюс второй: маркетинговые комбайны. Listonic с его 946 партнёрами - это не аномалия. Bring! работает по той же схеме: бизнес-модель строится на рекламе Nestle и Carrefour. Когда приложение "рекомендует" тебе йогурт - оно не рекомендует. Оно продаёт. AnyList берёт $12 в год за веб-доступ и доступен только на английском. OurGroceries не обновлялся содержательно три года - пользователи просят добавить отслеживание цен, а разработчики молчат. "Купи батон" синхронизируется только через WiFi (кто ходит в магазин с WiFi?).

Вот и весь выбор: или блокнот, или приложение, которое знает о твоих покупках больше, чем твой терапевт.

Мне показалось, что между этими крайностями поместится что-то нормальное.

Моя точка входа: холодильник, жена и вечное "а молоко?"

Я не стартапер. Я наёмный разработчик, Senior Android/KMP Developer. Днём - код за зарплату. Вечерами - код для души.

Ситуация, которая запустила всё, банальная до зубной боли. Жена смотрит в холодильник, составляет мысленный список. Я ухожу в магазин, покупаю что помню. Прихожу - и выясняется, что помню я плохо. Созвон из магазина помогает, но только если жена берёт трубку (спойлер: не всегда). Сообщение в мессенджере помогает, но только если я его замечаю между полками с крупами (спойлер: тоже не всегда).

Это не драма. Это мелочь. Но мелочь, которая повторяется три-пять раз в неделю и каждый раз чуть-чуть раздражает обоих. Семейный список покупок - маленький бытовой ритуал. Когда он работает гладко, в доме становится чуть тише. Не метафорически - реально меньше вопросов "а ты купил?" и "а почему не то?"

Что получилось: Foodee

Foodee - семейное приложение для покупок. Один человек добавляет товар, другой видит его мгновенно. Не "через минуту". Не "когда обновит ленту". Мгновенно - через WebSocket.

Жена кладёт "молоко" в список, пока стоит у холодильника. Я в магазине вижу уведомление раньше, чем она закроет дверцу. Если я в подвале супермаркета и связи нет - приложение копит изменения в офлайн-очереди и отправляет всё, как только сеть вернётся. Без дублей, без конфликтов, без "перезагрузите приложение".

Никакой рекламы. Никакой продажи данных. Никаких подписок. Список покупок - последнее место в жизни, где нужно торговаться за приватность.

Что внутри: 21 тысяча строк и ноль молитв (ладно, немного молитв)

Весь проект - один человек. Архитектура, код, дизайн, бэкенд, деплой. Без команды, без инвестиций. Claude помогает, но скорее как резиновая уточка с расширенным словарным запасом, чем как полноценный напарник, хотя, очень умный напарник

Цифры:

  • 21 095 строк на Kotlin Multiplatform
  • 69% кода - общий между всеми платформами
  • 3 платформы из одной кодовой базы: Android, iOS, Web (WASM), Desktop
  • Архитектура: Clean Architecture + MVI - потому что "это же просто списочек" ни разу не оправдание для каши в коде

Стек: Compose Multiplatform для UI, Ktor и на клиенте, и на сервере, Room для локальной базы, Koin для DI, Navigation Component 3 для навигации. На бэкенде -- Ktor Server, MySQL, Docker Compose, Nginx. Всё крутится на VPS.

Самая интересная часть - синхронизация. SyncEngine занимает под пятьсот строк: пять мьютексов, circuit breaker, офлайн-очередь. Шесть race condition-ов я поймал и починил вручную. Тестов на всё это хозяйство - ноль. Абсолютный, стерильный ноль. Живу с этим, как с хронической болезнью: знаю, что однажды аукнется, но пока симптомов нет.

Ещё один момент, которым я одновременно горжусь и стыжусь: Navigation3 в продакшне. Не RC, не beta - alpha. Типобезопасная навигация настолько удобна, что я написал 57 строк кастомного сериализатора и решил, что оно того стоит. Два крэша на этапе разработки - приемлемая цена за нормальный DX.

SHA-256 на чистом JavaScript? 59 строк. Потому что для WASM-таргета нужно было реализовать хэширование без нативных библиотек. Горжусь ли я этим? Нет. Работает ли? Да.

Конфетти, маскот и зачем в утилитарном приложении нужны эмоции

Из десяти протестированных приложений для покупок - ни одно не пыталось вызвать хоть какую-то эмоцию, кроме раздражения. Они все решают задачу. Никто не делает процесс хотя бы нескучным. А ведь это рутина, которая повторяется каждую неделю.

Я решил экспериментировать.

Маскот Фуди. Живёт внутри приложения, меняет приветствия в зависимости от времени суток. Утром бодрит, поздно вечером сочувствует, при ошибке сервера утешает: "Облако устало, попробуй через минутку!". И самое главное - Фуди растёт. Закрыл первый список - 120dp. Три подряд - 140dp. Пять - 160dp и статус, который мотивирует закрыть шестой. Визуально рост почти незаметный, но подсознание ловит.

9 ачивок. "Ночная сова" за покупку после 23:00. "Марафонец" за 20+ товаров в одном списке. "Ранняя пташка" за покупку до 7 утра. Я не верил, что кому-то это будет интересно (моя жена проверяет прогресс ачивок чаще, чем я проверяю мониторинг сервера).

Pull-to-refresh с характером. 7 фаз обновления, каждая со своей фразой. Не "Загрузка...", а маскот с репликами в зависимости от стадии.

Конфетти. Когда все позиции в списке отмечены - экран взрывается. 40 частиц с настоящей физикой: гравитация, вращение, три формы. Не gif, не Lottie - кастомная симуляция на Canvas..

Ваш список покупок сливают 946 компаниям. Я же написал свой

Монетизация: три чашки кофе

У Foodee нет подписки. Нет рекламы. Нет paywall, где "базовая версия" хуже "платной". Все функции доступны всем.

Монетизация - добровольные донаты. Три варианта:

  • Espresso - 99 рублей
  • Cappuccino - 249 рублей
  • Latte - 449 рублей

Оформлены как кофе для маскота. YooKassa для платежей. При каждом донате мне прилетает уведомление в Telegram.

Работает ли это как бизнес-модель? Пока рано говорить. Но мне нравится идея: приложение зарабатывает не на том, что ограничивает пользователя, а на том, что пользователю хочется сказать спасибо. Наивно? Вероятно. Но альтернатива - реклама или paywall - мне не нравится больше.

Ваш список покупок сливают 946 компаниям. Я же написал свой

Что не работает и за что стыдно

Не рекламная статья - значит, и про провалы тоже.

SyncEngine без тестов. Под пятьсот строк кода с пятью мьютексами, circuit breaker-ом и офлайн-очередью. Шесть гонок данных нашёл руками. Покрытие тестами: 0%. Каждый день жду, когда прилетит. Пока не прилетело (или прилетело, но я не заметил, что ещё хуже).

iOS - не в App Store. Код написан, на симуляторе работает. Но $99 в год за Apple Developer Program и танцы с сертификатами - это то, до чего у инди-разработчика руки (и бюджет) доходят в последнюю очередь. Опубликовано в RuStore - процесс занял часы, не недели.

Деплой: shell-скрипт с ноутбука. Никакого CI/CD. Никаких автотестов перед продакшном. Мой внутренний инженер каждый раз делает вот такое лицо. Но продукт - в проде, пользователи пользуются. А CI/CD... ну, когда-нибудь. Может быть.

Alpha-навигация в проде. Navigation3 -- альфа-версия. Я знаю, как это звучит. Но type-safe routes настолько удобны, что 57 строк кастомного сериализатора и пара крэшей на этапе разработки -- цена, которую я готов платить.

Можно ли так делать? Строго говоря, нельзя. Работает ли это? Каждый день. Пока жалоб ноль (возможно, корреляция с количеством пользователей, но я предпочитаю верить в качество кода).

Три вещи, которые я понял за эти полгода

Запуск с багами лучше незапуска без багов. Три месяца я полировал архитектуру. Clean Architecture, MVI, 15 expect/actual пар. Идеально спроектировано. Ни одного пользователя. Момент, когда я нажал "публикация" с тремя известными багами, оказался переломным. Баг в проде мотивирует сильнее, чем баг в dev-ветке: за ним стоит живой человек.

Один разработчик - это свобода принимать решения за секунды и невозможность болеть. Хочу маскота - маскот появляется завтра. Хочу конфетти - конфетти появляются сегодня. Ни одного митинга, ни одного спринта, ни одного "давайте вынесем в бэклог". Обратная сторона: если сервер упал в субботу вечером, починка - тоже моя проблема. И тестирование. И деплой. И ответ пользователю.

Приватность - конкурентное преимущество, о котором никто не думает. 946 партнёров у Listonic - не баг, а бизнес-модель. Люди не читают privacy policy приложения для списка покупок. Но когда показываешь цифры - реакция одинаковая: "серьёзно?!". "Мы не собираем данные" звучит как маркетинг. Но это можно доказать - и оно привлекает.

Foodee не собирает, и, тем более, уж, не отправляет никакие данные. Всё, что собирает приложение, это device_id, для регистрации пользователя, и чтобы связать два устройства в семью, но дальше докер-контейнера это не уходит. Никакие персональные данные не собираются.

Ваш список покупок сливают 946 компаниям. Я же написал свой

Вместо заключения: три вопроса, на которые я не знаю ответа

Я не пришёл на vc.ru рекламировать приложение. Я пришёл за обратной связью. Серьёзно. У инди-разработчика нет продактов, нет фокус-групп, нет аналитиков. Есть жена (которая пользуется), друзья (которые "да-да, круто") и комментарии в интернете.

Вот что меня реально мучает:

  1. Донаты как единственная монетизация - это жизнеспособно или я обманываю себя? Может, нужна freemium-модель с чем-то реальным за деньги?
  2. Стоит ли вкладываться в Apple Developer Program прямо сейчас -- или лучше сначала нарастить аудиторию на Android?
  3. Как вы находили первых пользователей для своих проектов? Что работало, а что оказалось потерей времени?

Буду в комментариях. Отвечу каждому, кто напишет по делу. И не по делу тоже )))

Попробовать Foodee - бесплатно, без регистрации по email, работает сразу после ввода имени:

3
9 комментариев