Стол — помощник по меню
Мини-приложение и бот в Telegram и MAX + веб-сайт (этап 2). План еды на неделю для семьи, каталог рецептов с фото, список покупок по отделам, дневник еды по фото. Текст через OpenRouter, картинки через Kie.
готовS1 · С1 · Каркас8/8
Цель: pnpm-монорепо, docker-compose, Prisma, Fastify с /health
готовS2 · С2 · Справочники и nutrition6/6
Цель: 350 ингредиентов, 80 замен, расчёт БЖУ и порций с тестами
готовS3 · С3 · Каталог 400 рецептов4/5
Цель: Генерация с валидатором и ручным просмотром, калории из состава
готовS4 · С4 · Идентичность, семья, ограничения7/7
Цель: Мультиплатформенный аккаунт, вход из Telegram, единый сервис запретов
готовS5 · С5 · Каркас мини-приложения6/6
Цель: Один фронт на три среды: Telegram, MAX, браузер
готовS6 · С6 · Онбординг5/6
Цель: 4 минуты от старта до плана на 3 дня, первая AI-задача образцовая
готовS7 · С7 · Сборка плана8/8
Цель: Фильтр, скоринг, LLM, пост-валидация. Экраны Сегодня и Неделя
готовS8 · С8 · Рецепты и список покупок6/6
Цель: Экран рецепта, режим готовки, покупки по отделам, обучение вкусам
В РАБОТЕS9 · С9 · Картинки4/7
Цель: Рендер карточек кодом + разовая генерация фото каталога через Kie
В РАБОТЕS10 · С9.5 · Упаковка и характер16/17
Цель: Довести интерфейс до вида, который не стыдно показать. Раздела не было ни в одном из 16 спринтов: дизайн подразумевался по ходу дела, поэтому экраны собраны правильно, но никак.
В РАБОТЕS11 · С10 · Профили, причина отказа и видимая память17/18
Цель: Система перестаёт учиться молча: спрашивает почему, показывает чему научилась и даёт отменить.
В РАБОТЕS12 · С10.5 · Качество каталога15/18
Цель: Рецепт, по которому приготовит человек, впервые вставший к плите. Стандарт, варианты блюда, факты из открытых источников.
В РАБОТЕS13 · С13 · Веб-сайт (этап 2)12/13
Цель: Лендинг под мобильный, тот же мини-апп в браузере, вход через бота
планS14 · С14 · Память и удержание0/3
Цель: Приложение должно ощущаться точнее с каждым месяцем
В РАБОТЕS15 · С15 · Продакшн на cfru6/7
Цель: Деплой, мониторинг, потолки расходов, бэкапы, нагрузочный
планS16 · С16 · Платежи0/6
Цель: ЮKassa, Stars, контекстные пейволлы, триал. По решению владельца в самом конце
В РАБОТЕS17 · С11 · Админка9/10
Цель: Пульт владельца: сколько людей, что в каталоге, куда уходят деньги, что происходит прямо сейчас
Ворклог (места остановки)
Админка дополнена разделом людей: откуда приходят (Telegram 10, MAX 4, сайт 3), по каждому логины на площадках и почта, дошёл ли до конца знакомства, кухня, даты и что именно делал. Тут же поймана своя ошибка: два запроса одного раздела делили ключ кэша и раздел падал в белый экран, в ключ добавлен адрес. Найдена причина трёхдневных планов: горизонт брался из открытой вкладки, и «Пересобрать» на вкладке «Сегодня» превращал недельный план в трёхдневный, в базе это видно как замену семидневного плана трёхдневным в ту же минуту. Теперь план всегда на неделю, умолчание сервера тоже неделя.
→ Проверить недельный план живьём после пересборки. Мелочь: у пришедших из MAX не сохраняется имя из данных запуска, вместо него внутренний номер. Хвосты: 656 брошенных кухонь (нужно да на уборку), качество шагов 0.59, шаблоны карточек для блюд без фото.
Внутри MAX приложение просило регистрацию: не был подключён мост площадки, без него нет window.WebApp и приложение считало себя браузером. Мост подключён, ждём его только на входе. Тут же поймана своя регрессия: библиотека MAX создаёт пустой window.WebApp в любом браузере, и приложение стало показывать «откройте из мессенджера» прямо в браузере — теперь требуются данные запуска, на это два теста. Достроена единая учётная запись: код связывания под любую площадку, раздел «Входы в аккаунт» в профиле, бот принимает код обычным сообщением. Проверено двумя движками на живом сайте.
→ Владельцу: вставить https://xn--24-6lclog.xn--p1ai/app/ в поле мини-приложения в кабинете MAX и проверить вход. По интеграции с доставкой: у Пятёрочки и Купера покупательского API нет, Яндекс Доставка это курьер; единственный рабочий путь — реферальная программа Яндекс Маркета, там есть ссылка на корзину с несколькими товарами, нужен договор и ключ, решение за владельцем. В админке ждут 656 брошенных кухонь (кнопка уборки есть, нужно да) и качество шагов 0.59 у загруженных рецептов.
Подключён MAX: адаптер площадки, вебхук через подписку с проверкой секрета, вход в мини-приложение той же проверкой подписи что у Telegram. Токен бота проверен, подписка создана, вебхук отвечает 401 без секрета и 200 с ним. Адрес API оказался botapi.max.ru, а не platform-api2 из справочника. Ранее в этой сессии: приглашение в семью по ссылке с общей кухней, отправка списка покупок, раздел Любит и свободный ввод продуктов, сохранение рассказанного словами до обращения к модели.
→ Владельцу вставить https://xn--24-6lclog.xn--p1ai/app/ в поле мини-приложения в кабинете MAX (только пуникод). Затем живая проверка бота и приложения в MAX. Дальше по роадмапу: шаблоны карточек для блюд без фото, управление в админке, Sentry и дашборд расходов.
Починено «не открывается на мобильном»: разметка кэшировалась навсегда, а выкладка удаляет старые файлы сборки, телефон уходил за несуществующими файлами. Теперь no-cache на разметку и immutable на assets. Добавлен раздел «Блюда» с поиском и постановкой блюда на сегодня. Добавлен выключатель уведомлений: переключатель в профиле и команды в переписке с ботом. Пересобран состав у 4071 рецепта: починены буква ё, короткие названия, обратный порядок слов и доверие к синонимам справочника. Проверена кнопка «Сделать карточку» на одном рецепте, картинка вышла верная. 302 теста проходят, всё выкачено.
→ Осталось: шаблоны карточек satori+resvg для блюд без фото, vision-проверка результата, управление в админке (снять блюдо, погасить правило), Sentry и дашборд расходов, память и удержание. Массовую генерацию картинок владелец запретил, только по кнопке.
Починена мобилка: причина была в кэше разметки при переименовании файлов сборки. Добавлен раздел «Блюда» с поиском, метками и постановкой блюда на сегодня. Починена проверка совпадений продуктов (буква ё, короткие слова, обратный порядок), добавлено 8 продуктов и синонимы; идёт пересборка состава у 5900 загруженных рецептов с пересчётом калорий. Картинки только по кнопке на рецепте, пачкой не генерятся. 298 тестов проходят, всё выкачено и проверено на живом.
→ Дождаться конца пересборки состава. Спрошено разрешение на один платный тест кнопки «Сделать карточку» (3-5 руб). Дальше: админка управления, тёмная тема на живом телефоне, Sentry и дашборд расходов.
Выкачено на 24стол.рф: вход по почте и паролю работает вживую (регистрация отдаёт токен, чужой пароль 401), лендинг показывает 6154 рецепта с сервера. Попутно на живой странице нашлись и починены две вещи: скрипт лендинга падал на имени top (оно занято окном), из-за чего шапка при прокрутке не меняла вид, и значки приложения искались по старому адресу /stol/app/ с 404. Консоль чистая.
→ Личный кабинет под десктоп широкой раскладкой, раздел выбрать блюдо на сегодня с фильтром и поиском, картинки для загруженных блюд, дополнить справочник продуктов (нет индейки, фенхеля, сухариков).
Каталог вырос с 421 до 6291 блюда загрузкой с открытых источников: парсер шагов с нормализацией под наше обращение на ты, разбор состава с количествами, привязка к справочнику, калории считает наш код. Ни одного платного вызова модели. Вход на сайте переведён на почту и пароль (scrypt из Node), Telegram остался запасным входом: его блокируют в РФ, а на десктопе переход в мессенджер закрывал вкладку. Лендинг берёт число рецептов с сервера через новый /public/stats. 286 тестов проходят.
→ Не задеплоено на 24стол.рф: код в main (коммит 4733295), ждёт подтверждения владельца. Дальше: личный кабинет под десктоп широкой раскладкой, раздел выбрать блюдо на сегодня с фильтром и поиском, картинки для загруженных блюд.
Закрыты все задачи из очереди: дизайн приложения (нейтральная тёмная тема вместо коричневой, градиентные кнопки, панель убрана из знакомства), мобильная вёрстка сайта, каталог с 11.4 до 5.8 процента замечаний, фавиконка, переезд на 24стол.рф с сертификатом и переключением вебхука, воркер BullMQ и нагрузочный тест на 500 человек. Тестов 269.
→ От владельца ждём: номер счётчика Метрики, телефон психологической помощи, проверку тёмной темы и лендинга на телефоне. По проекту остались: Sentry (нужен внешний аккаунт), картинки блюд С9 (упираются в деньги на генерацию), остаток каталога около 6 процентов, управление из админки. MAX и платежи отложены владельцем.
Продукт переехал на собственный домен 24стол.рф: сертификат, nginx с пуникодом, сайт в корне, приложение в /app/, вебхук переключён, старые адреса редиректят. Каталог дотянут с 11.4 до 5.8 процента замечаний. Приложение подтянуто к сайту по дизайну: нейтральная тёмная тема вместо коричневой, градиентные кнопки, панель разделов убрана из знакомства. Сделана фавиконка. Починен перелив сайта вбок на телефоне: размытые пятна фона торчали за край и полагались на обрезку родителем, а на iOS так не работает.
→ Осталось: воркер BullMQ (сборка плана крутится в процессе API), нагрузочный тест, Sentry (нужен внешний аккаунт), картинки блюд С9, номер счётчика Метрики и проверка на телефоне от владельца. MAX и платежи отложены.
Довёл сайт до вида продукта: логотип, широкий кадр с борщом, четыре фото в блоки, галерея из восьми настоящих карточек рецептов, карточка рецепта целиком, раздел «кому подойдёт» (семьям с детьми, худеющим, спортсменам, с ограничениями). Потрачено 20 рублей из выданных 30. Починил три бага, которые нашёл владелец: невидимое содержимое ниже обложки (класс появления держал прозрачность нулём в покое), коричневая тёмная тема (поверхности стали нейтральным углём), пробел в слове «Стол» (флекс разносил текстовый узел и span) и чёрный логотип на тёмной шапке (добавлена светлая версия через picture). Убрал внутреннюю кухню из текстов: «калории считает код» заменено на выгоду для человека.
→ Сайт по картинкам закрыт, осталось 10 рублей из бюджета. Написан скил landing-page, чтобы не объяснять заново: структура, дизайн-система, ловушка с невидимым содержимым, смета на генерацию, правила текста, обработка картинок. Дальше возвращаемся к приложению: владелец сказал, что дизайн приложения тоже надо менять. Также висят: номер счётчика Метрики, проверка на телефоне, воркер BullMQ, картинки блюд С9, каталог 13 процентов.
Переделал сайт из текстовой справки в нормальный лендинг: градиентные небеса, крупная типографика, парящий телефон с карточкой дня, шаги, чередующиеся блоки, плитки блюд, раскрывающиеся вопросы, появление при прокрутке. Палитра тёплая и съедобная, а не неоново-техническая. Всё на CSS без библиотек анимации: страница 26 кб. Юридические страницы приведены к тому же виду.
→ Ждёт решения владельца: настоящие фотографии еды на лендинг. Предложено начать с четырёх штук за 14 рублей (одна широкая 2K и три плитки 1K), посмотреть и решить про остальные. Видео отдельно и заметно дороже. Также нужен номер счётчика Метрики и проверка на телефоне.
Сделан веб-сайт: статический лендинг и юридические страницы на /stol/, приложение уехало на /stol/app/, вход в браузере через подтверждение в боте. Реквизиты взяты из Контент Завода по просьбе владельца. По дороге нашёл, что имя бота в лендинге я написал придуманное: настоящее Life_gamers_bot. Убрал значение по умолчанию у настройки имени бота, теперь его обязательно задать. Тестов 266.
→ Осталось по сайту: номер счётчика Метрики от владельца и проверка на реальном телефоне (браузер был занят). Дальше по проекту: воркер BullMQ и нагрузочный тест из С15, Sentry, картинки С9, каталог 13 процентов.
Большой заход: дневник еды по фото (модель называет, калории считает код, кэш по хэшу, поиск блюд каталога по вхождению слов), чат с помощником через дешёвый классификатор намерения, продакшн-обвес (своя база тестам, ограничитель частоты, бэкапы с проверкой восстановления, алерты в Telegram), плюс мелочи: план собирается сразу после онбординга, итог недели и письмо вернувшимся, кнопки управления в админке. Тестов 266. Потрачено за проверки 5.5 копейки: фото 4.5, сообщение чата 1, классификатор 0.2.
→ Осталось: веб-сайт С13 целиком, воркер BullMQ и нагрузочный тест из С15, Sentry (нужен внешний аккаунт), картинки С9 (упираются в деньги на генерацию), каталог 13 процентов. MAX и платежи отложены по решению владельца. Нужен проверенный телефон помощи для HELPLINE_PHONE.
Бот перестал быть кнопкой «открыть приложение». Сделаны рассылки (утро, вечер, воскресенье) со временем по поясу человека, оценка блюда прямо из переписки, защита по признакам нездорового отношения к еде. Починен баг: на код привязки бот отвечал «аккаунты связаны», не связывая ничего. Логика связывания и вкусов вынесена в пакеты @menu/accounts и @menu/tastes, чтобы бот и API не разъехались. Поймал в четвёртый раз беду с границей слова: в файле лежал настоящий байт-забой, правило про калории не работало, теперь это ищет отдельная проверка. Тестов 260.
→ Утренняя карточка проверена живьём, вечерний вопрос и воскресный план сработают по расписанию сами, посмотреть их можно завтра. HELPLINE_PHONE на сервере не задан намеренно, нужен проверенный номер от владельца. Дальше по С10 остаются чат в приложении со стримом и обработка фото, они идут вместе с дневником еды.
Разобрал вопрос владельца «откуда 657 семей и 8 человек». Живой человек в базе ровно один. Остальные семь учёток и все 656 брошенных кухонь это следы автотестов: тесты удаляли пользователя, но не заведённую им кухню. Сделал общую уборку и подключил во все десять тестов, проверил измерением до и после полного прогона: рост прекратился. Админку починил: людей, едоков и планы считает только по живым кухням, брошенные показывает отдельной строкой с кнопкой удаления.
→ Кнопка уборки 656 брошенных кухонь ждёт владельца в админке, сам не удалял. Корень проблемы шире: тесты ходят в ту же базу, что и прод, отдельная тестовая база это С15. Дальше по плану бот с утренней карточкой дня.
Завёл спринт С11 «Админка» и сделал семь задач из восьми: серверный гейт по флагу в базе, сводка, деньги по задачам и моделям, каталог с качеством шагов и списком худших рецептов, база семей, лента задач, экран в мини-аппе. Проверка шагов переехала в @menu/shared, чтобы сид и админка мерили одной линейкой. Все числа считает код. Тестов стало 223.
→ Админка сразу показала мусор: 641 семья при восьми живых людях, 633 осиротевших без участников (следы автотестов), из них 31 с планами. Чистку не делал, это удаление данных, нужен ваш ответ. Не доделано управление из интерфейса: кнопки «снять блюдо» и «погасить правило» на сервере есть, в экране нет.
Дописал недостающие блюда каталога (оливье, винегрет, шуба, мимоза, шницель, бургер, лагман — 20 вариантов, 0 отбраковок) и замкнул главную цепочку вариантов: выбор человека теперь доходит до сборки плана, а не просто хранится. Починил две придирки валидатора шагов. Дизайн-проход: шапки экранов, тихая заметка вместо стены текста, значки вкладок, монограммы вместо обрезанных слов, движение, покраска рамки мессенджера. Бандл разрезан: 110 кб на первый экран вместо 348. Нашёл и починил настоящий баг: «Сегодня» показывало первый день плана, а не сегодняшний день.
→ Остановился на том, что тёмную тему надо посмотреть глазами в самом Telegram на телефоне. Дальше по каталогу: около 13 процентов шагов ещё без признаков готовности под конкретную технику. Из невыполненного по С9.5 остаются задачи про дневник еды и фото. Деньги за сессию не тратились: каталог и парсер писались руками, платных вызовов не было.
Каталог дотянут до стандарта: 52 процента стали 87. Переписывать 1779 шагов руками не понадобилось, 995 провалов из 1012 были механическими: количества уже лежали в составе, силу огня видно по действию. Руками написано знание (какое действие на каком огне, как склоняются названия продуктов), подстановка это код. Пришлось написать модуль склонения: первая версия давала «400 мл молоко» и «щепотку соль соль». Каталог перезалит, количества в шагах с 6 до 35 процентов. Варианты блюда доведены от схемы до экрана: заливка блюд, ручки, список вариантов в карточке рецепта с отметкой кто что ест. Проверено на проде ровно на примере владельца: Аня на уксусе, Игорь на квасе. Валидатор дважды отклонил мои же варианты окрошки и оба раза был прав.
→ Осталось из плана: массовый сбор фактов по списку блюд (парсер готов, прогона не было) и дизайн, планка «будто разработала Apple». Плюс переписать оставшиеся 13 процентов каталога, которые механикой не чинятся.
Владелец забраковал комбинаторное перемножение осей: оно даёт правдоподобные сочетания, а не блюда, которые люди едят. Плюс наши шаги бесполезны для новичка, «обжарь морковь на сильном огне» не говорит ни сколько, ни как понять что готово. Сделано: письменный стандарт рецепта с зафиксированным читателем (парень, впервые вставший к плите), эталонная карбонара по стандарту, валидатор годности шагов, модель вариантов блюда в схеме, окрошка с четырьмя настоящими вариантами, парсер фактов из открытых источников. Честные цифры качества: эталон и окрошка 100 процентов, сетка по курице 87, рукописный каталог 52. Валидатор дважды показывал мне завышенные цифры из-за в регулярке: на кириллице она не работает, а один раз вообще превратилась в управляющий символ внутри файла. Сначала было «100 процентов качества» там, где реально 52. Это третий раз за проект на тех же граблях, записано в память.
→ Переписать 48 процентов каталога под стандарт, сделать экран выбора варианта блюда, прогнать массовый сбор фактов по списку блюд. Отдельной веткой ждёт дизайн: планка задана как «будто разработала Apple», сейчас есть только палитра и шрифты.
Профиль вынесен отдельной вкладкой внизу. Раньше семья и выученное открывались кнопками внутри «Сегодня», хотя настройки семьи не часть сегодняшнего плана. Теперь пятый раздел: кто ест со сводкой ограничений по каждому человеку, вход в карточку, «Что я о вас понял» со счётчиком запомненного, время на готовку. Добавление едока переехало в профиль, удаление в карточку человека, где видно, кого именно убираешь. Экран «Сегодня» остался только планом. Выложено и проверено в собранном бандле на проде.
→ Ждёт решения владельца по расширению каталога сеткой (отруб × способ × соус), прикидка 100 рублей. Остальные хвосты С10: шторка причины у оценки на экране рецепта, живая проверка разбора свободного текста моделью.