Контекст
TapyTap — мой первый мобильный продукт. Основную часть я написал в июне 2025: привычки с категориями и напоминаниями, отметки выполнения, серии, календарь с тепловой картой, статистика, журнал заметок, архив, светлая и тёмная темы. Начинал на Firebase, через месяц перенёс аккаунты и данные в Supabase.
В октябре 2026 я вернулся к проекту, чтобы показать его здесь, и сначала прочитал код как чужой. Кейс о том, что нашлось и что я с этим сделал.
Моя роль
Единственный разработчик: продуктовые решения, интерфейс на React Native, состояние на Zustand, схема и правила доступа в Supabase.
Второй проход в октябре 2026 я делал вместе с ИИ-агентом: ставил задачи, разбирал его находки и проверял каждое исправление на iPhone.
Решение 1 / один источник данных
За год в приложении сложилось два слоя данных. Большинство экранов работало через стор на Zustand, а добавление и редактирование привычки и сортировка категорий — через старый модуль с собственным кэшем в AsyncStorage. Часть функций существовала в двух копиях, и записей через стор старый кэш не видел.
Из-за этого жили три ошибки. Редактирование стирало напоминания: экран добавления хранил их объектом, экран редактирования ждал массив и сохранял пустой список. Новая единица измерения у количественной привычки не сохранялась. Без сети форма новой привычки показывала уже удалённую категорию, а после смены аккаунта на том же телефоне — категории предыдущего пользователя.
Теперь все экраны пишут через один стор, кэш удалён вместе со старым модулем. Код стал короче на 461 строку.
Решение 2 / доступ к данным решает база
Ключ клиента Supabase публичный по замыслу: он зашит в каждую сборку и лежит в открытой истории репозитория. Значит, данные защищают только правила RLS в самой базе. У таблицы связей между привычками и категориями они пропускали любого вошедшего пользователя — он мог читать, удалять и создавать чужие связи.
Новые правила проверяют владельца через привычку, а при создании связи — ещё и владельца категории. Миграцию я проверил на локальной копии базы скриптом с двумя аккаунтами: из 14 сценариев со старыми правилами падали 6, с новыми проходят все.
Решение 3 / схема живёт в репозитории
Схема существовала только в облачном проекте Supabase. Я снял её в миграцию, и исправление доступа ушло на прод второй миграцией поверх неё. Заодно приложение переехало с Expo SDK 54 на 57, а из зависимостей ушли Firebase, оставшийся после переезда, и ещё две библиотеки, которые нигде не импортировались.
Результат / проверка
- 15 экранов: привычки, календарь, статистика, журнал, архив, сортировка категорий и привычек;
- Expo SDK 57 и React Native 0.86,
tsc --noEmitбез ошибок,expo-doctor— 21 из 21; - ручной прогон на iPhone в Expo Go: создание и редактирование привычек, сортировка, отметки, статистика и календарь;
- правила доступа проверены 14 сценариями на двух аккаунтах.
Ограничения
Приложение не опубликовано в сторах, и пользователей, кроме меня, у него нет. Автоматических тестов нет. Параметры навигации на большинстве экранов типизированы как any, поэтому ошибки маршрутов проверка типов не ловит. На проде новые правила доступа сверены по метаданным базы; двумя живыми аккаунтами их проверяли только локально.






