惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
Malwarebytes
Malwarebytes
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cybersecurity and Infrastructure Security Agency CISA
F
Future of Privacy Forum
C
Cisco Blogs
T
The Exploit Database - CXSecurity.com
A
Arctic Wolf
S
Securelist
K
Kaspersky official blog
S
Schneier on Security
T
ThreatConnect
T
Tenable Blog
Spread Privacy
Spread Privacy
T
True Tiger Recordings
AWS News Blog
AWS News Blog
F
Fox-IT International blog
量子位
T
Threatpost
V
Vulnerabilities – Threatpost
C
CERT Recently Published Vulnerability Notes
Cisco Talos Blog
Cisco Talos Blog
GbyAI
GbyAI
宝玉的分享
宝玉的分享
腾讯CDC
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
U
Unit 42
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
O
OpenAI News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
The Register - Security
The Register - Security
MyScale Blog
MyScale Blog
小众软件
小众软件
A
About on SuperTechFans
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
博客园 - 三生石上(FineUI控件)
美团技术团队
Google Online Security Blog
Google Online Security Blog
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog

Все публикации подряд на Хабре

«Ща будет шрифт»: история одного русского embedded‑шрифта Как аквариум на подоконнике превратился в full-stack платформу с AI Пиратство, копирайт и DMCA: как Napster, The Pirate Bay и YouTube изменили закон. Часть II Как найти внутренние резервы для развития предприятия Как один французский чиновник от безысходности начал платил зарплаты картами и практически изобрёл банкноты RAG в энтерпрайзе: почему демо работает, а прод нет AI-агент для финансовых процессов: как мы научили ИИ считать числа из базе данных без галлюцинаций Автопостинг на 8 платформах: архитектура waterfall, custom publisher'ы и API-ловушки Кинетика против бронзы: Почему Голиаф был обречен в дуэли с Давидом [Перевод] Масштабирование LLM: от одного чипа до ЦОДа. Глава 2. Шардинг LLM не работает за вас. Она работает с вами Чем лучше защищает минеральный SPF, тем страшнее он выглядит Стимпанк как часть жизни. История паровых двигателей и место, которое они занимали в мире в XIX-XX веках. Часть 1 Гастарбайтеры ворвались в IT и зарабатывают на рекламе: тут вам не снег лопатой кидать Новые методы и инструменты: как мы обновили курсы по тестированию в Яндекс Практикуме Java 21 в стиле «клятый энтерпрайз» на одноплатном компьютере возрастом 13 лет Ваши секреты внутри LLM. Куда уходят промпты и чего стоит опасаться? 10× труда. 10% к бонусу. Главный риск AI-эпохи — это сениор AI-инженер, который умеет считать Сапожник с сапогами Минимум, который удержит тебя на плаву в период дедлайнов Как без проблем переносить курсы между платформами? Обзор формата SCORM Когда Claude Code ошибается не по своей вине: документационный долг в соло-проектах 70% кода с AI — и ни на день быстрее qrrot — база данных со встроенным ИИ Шахматные программы V. Оценочная функция Восстание масс в обществе спектакля и отчуждение труда в царстве количества: что делать во времена всеобщего упадка? Не умеешь работать с ИИ? Тебя заменит тот, кто умеет Как интеллект становится уязвимостью под давлением Не надо так: три типичные ошибки, которые приводят ко взлому Заметки про код-стайл в C++ Забытый мультиколор (часть 1) Культура ест стратегию на завтрак: почему не работает долгосрочное планирование Советское ИИ: Забытые гении Как оплатить iCloud в России в 2026 году без смены региона Apple ID Глубокая интеграция месседжинга с бизнес процессами в фреймворке NodaLogic Контекстные менеджеры в Python за пределами with open(): пишем свои и упрощаем код Пароль против уборщицы Выяснились детали мега-IPO SpaceX, а также первый прибыльный квартал Anthropic Люди с психическими расстройствами – новая нефть? Когда нейросети перестанут галлюцинировать? И почему на «что за дичь» они несут ещё большую дичь? Мессенджер HalChat теперь в Google Play: 3 года разработки, ИИ в браузере и квест с модерацией Реверс-инжиниринг Xiaomi Smart Band 10 Когда памяти мало Среда повседневности как объект проектирования: что общего у горца, серотониновой ямы и митохондрий AGENTS.md создавали, чтобы помогать агентам. Я использую его, чтобы их вычислять Почему устанавливают join_collapse_limit = 20 Почему устанавливают join_collapse_limit = 20 Эрик Рис, автор Lean Startup: Почему хорошие компании становятся плохими после IPO Context-driven Reusable Form Pattern: Масштабируемая архитектура для Create / Edit / Create-from-Source Пузырьковая сетка, кошачья стая и не только — неожиданные источники вдохновения для QoS-алгоритмов ___, или «Заголовок намеренно оставлен пустым» ИИ-боты сканируют даже логи TLS-сертификатов. Любая информация используется для обучения LLM Нейросеть оживить фото ИИ: Как оживить фото нейросетью в 2026 году? Разбираемся в ML без воды: от базы до Attention. Часть 5: Метрики качества В поисках «кофейного Грааля». Как человечество пытается сварить идеальный кофе и какие рецепты предлагают…математики Программатик: Часть 2 — OpenRTB Интернет до бесконечных лент: каким был 2010 год Перезапуск TrueIndex: что изменилось в рейтинге языков программирования Проектный холст: как менеджеру подбирать «краски» управления под разные команды «Метафизика в формулах: математическое ядро «Веры Паломника — Исход» Java и постквантовый TLS Marcli: Markdown Терминал Кнопочный смартфон с 5G за 2800 рублей — разбираем и изучаем китайскую диковинку Где неприятности — там и жизнь Разворачивайте платформы: stackfile Мой путь в Microsoft Мобильная разработка за неделю #631 (18 — 24 мая) Что не так с Mixtape, и почему не все довольны новой игрой? Стоматология каменного века. Как неандертальцы лечили зубы 59 тысяч лет назад Почему классическое управление проектами часто не работает в IT-продуктах Строительство Саркофага. Часть 2. Бетонные реки и стальные берега РАЗРАБОТКА ПАРАМЕТРИЗИРУЕМОГО МОДУЛЯ CORDIC-АЛГОРИТМА НА SYSTEM VERILOG Вариационное исчисление как метафора свободы выбора: от градиентного спуска к онтологии пути Ekahau Sidekick и RSSI‑offset: физические ограничения метода и пять независимых причин неточности клиентской модели Колесо потока против раскола Обзор интересных особенностей переворачивающихся при умножении чисел В С неопределённое поведение повсюду MCP-агрегатор: объединяем инструменты для LLM в один сервер Дата-центры в космосе: как Google и SpaceX готовят новую инфраструктуру для ИИ Google готовит замену Chromebook: какими будут ноутбуки Googlebook Пользователь пишет issue, агент меняет сайт. Да, я это сделал Корпоративные конфликты в ИТ-секторе: механика судебной защиты активов и субсидиарных рисков Цена одной опечатки: Как три неверные буквы сорвали киберограбление на миллиард долларов Как я победил спам в своих email аккаунтах Whitepaper Сбера «AI-Disrupt PDLC»: разбор для тех, кто пишет код RustDesk Pro в России не купить. После долгих лет администрирования мы собрали своё честное решение Не пики, а бассейны: почему эволюция — это блуждание по графу жизни Как Gemini 3.5 Flash сломали ради красивых графиков (и почему она обходит 3.1 Pro только на бумаге) Вредоносная атака на Laravel-Lang meta-attention is all you need Как перестать путаться в IP-адресах серверов Сколько стоят ошибки в арбитраже: декомпозиция ценообразования на судебные услуги в Москве Разбираемся в ML без воды: от базы до Attention. Часть 4: kNN Vortex: фреймворк для тех, кого задолбала итальянская кухня в репозитории Использование тепла ЦОД в мире и РФ Часть 4. Скорость света — технические детали Не цитируй мне нейросеть Что сейчас с Project Loom? Примеры и код Рождённые в Сумерках Meta 1 мая показала как они хранят ключи от ваших бэкапов WhatsApp. Разбираю архитектуру и сравниваю
GiftsHub — из чат-бота в полноценный backend-продукт
kira_s (Битр · 2026-05-25 · via Все публикации подряд на Хабре

Уровень сложностиПростой

Время на прочтение11 мин

Охват и читатели4

Кейс

Привет! Меня зовут Кирилл Семенко, я AQA в SDET-команде Битрикс24. Сегодня расскажу о проекте GiftsHub — веб-платформе для координации мероприятий и дней рождений, которой пользуются сотрудники компании.

С 2019 года у нас в компании проводят внутренние Битрикс-хакатоны. Эта традиция даёт возможность поработать в новых командах, узнать что-то новое и сделать уникальный и интересный проект. Для лидеров команд это ещё и шанс развить свои способности менеджера и руководителя для достижения цели командой.

На хакатоне 2024 года начался проект, о котором я рассказываю сегодня — Telegram-бот для организации подготовки к праздникам. Потом появились Telegram WebApp / MiniApp, а следом полноценная платформа: отдельный сайт, публичные ссылки, email-вход, realtime и нормальная инфраструктура вокруг backend и frontend.

Технически задача такого приложения выглядит простой: хранить вишлисты и помогать выбрать, что подарить. Самой сложной частью оказалась координация действий всех участников: кто участвует в сборе, какая сумма уже собрана, кто отвечает за покупку подарка и как сохранить сюрприз до нужного момента.

В статье расскажу про путь от быстрого bot-first MVP к самостоятельной продуктовой системе: с доменной моделью, несколькими интерфейсами, realtime и инфраструктурой вокруг backend и frontend.

Посмотреть и попробовать можно здесь

Содержание:

Откуда появилась задача

Исходная боль была жизненной и практической: организовать подарок человеку так, чтобы остальные участники успели все обсудить, собрать деньги, выбрать вариант и не раскрыть сюрприз.

До автоматизации процесс держался на переписках и памяти организатора. Где-то обсуждали идею подарка, где-то уточняли участников, где-то вспоминали, какая сумма уже собрана. Пожелания именинника могли лежать отдельно, договоренности терялись, ответственность расползалась между людьми.

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

Если такие события происходят раза в 1-2 месяца, все можно вести руками. Когда сценарий повторяется регулярно, ручная организация начинает съедать слишком много времени и внимания. В какой-то момент стало ясно, что люди готовы участвовать, но процесс слишком завязан на одном человеке и множестве мелких сообщений.

Для хакатона это была удобная задача: боль понятная, цикл проверки короткий, сценарий уже существовал в жизни. Первая версия проекта была быстрой проверкой идеи: получится ли убрать часть ручной операционки из подготовки подарков.

Почему стартовали через Telegram

Telegram выбрали как самый быстрый канал для MVP. Пользователи уже там, сценарий организации подарка похож на переписку — кого поздравляем, когда день рождения, кто участвует. Ещё бота можно добавить в группу и сразу проверить базовый путь без отдельного frontend.

Поэтому на хакатоне с Telegram было удобно: можно быстро собрать реально работающий сценарий. Команды, кнопки, callback-события и сообщения позволяли провести пользователя по шагам: добавить бота, создать группу, присоединиться, указать день рождения, начать собирать данные.

Backend на этом этапе обслуживал bot-flow. В центре были обработчики, состояния диалога и тексты сообщений. Это нормальная цена быстрого старта: сначала появляется рабочий путь, потом становится понятно, какие сущности и правила за ним стоят.

Первая версия закрывала базовые вещи: профили пользователей, группы, дни рождения, вишлисты и участников поздравления. Но уже тогда стало видно ограничение: Telegram удобен как вход и канал общения, но в его возможности не помещаются все нужные функции.

Когда одного Telegram стало недостаточно

Поворот случился из-за конкретного тупика.

Главный сценарий сервиса — подготовка подарка для конкретного человека. Остальным участникам нужно место для обсуждения деталей: что дарить, кто участвует в сборе, какая сумма уже собрана. Подготовка при этом остается скрытой от самого именинника.

В Telegram это почти решаемо: можно попробовать тред, топик или отдельное обсуждение. Но если обсуждение живет внутри общего пространства, из него нельзя аккуратно убрать одного человека: то есть человек видит обсуждение собственного подарка, и сценарий ломается.

Второе ограничение рядом: боту недоступно создание управляемого приватного чата нужного состава. То есть бот должен создать отдельный закрытый чат, добавить туда только нужных участников и исключить именинника. В Telegram это невозможно, и для безопасности мессенджера это логично, но для продукта — тупик.

После этого стало ясно, что Telegram не может быть центром модели. Он оставался полезным каналом: привести пользователя, отправить уведомление, дать быструю кнопку. Но правила сценария уже должны были жить внутри продукта: кто участник события, кто именинник, кто может присоединиться и что нужно скрыть.

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

const participants = users.filter((user) => {
  return user !== birthdayPerson;
});

const event = new EventEntity();
event.birthdayPerson = birthdayPerson;
event.participants = participants;

Этот кусок хорошо показывает переход: сначала задача звучала как "создать обсуждение без именинника". Потом она стала backend-правилом. Именинник существует в событии как birthdayPerson и остается вне обсуждения подготовки.

Telegram WebApp / MiniApp как промежуточный этап

Между ботом и полноценной платформой был важный этап — Telegram WebApp / MiniApp.

WebApp позволил оставить Telegram входной точкой, но вынести сложный интерфейс туда, где уже можно нормально управлять состоянием, навигацией, событиями, списками и чатами.

Первая версия Telegram MiniApp

Первая версия Telegram MiniApp

3 февраля 2025 рядом с ботом вышло в релиз наше приложение Telegram WebApp, которое открывался прямо из Telegram. Внутри уже были NestJS, Angular, Postgres, Socket.IO и JWT. Часть функций оставалась в боте, часть переезжала на frontend.

WebApp закрыл то, что плохо помещалось в формат команд и сообщений: просмотр хотелок, личные списки, обсуждение подарка во внутреннем чате. Там, где бот превращался бы в длинную цепочку кнопок, WebApp давал нормальный экран.

Авторизация тоже стала переходной. Пользователь приходит из Telegram, backend проверяет initData, дальше выдает access и refresh JWT в cookie. Вход еще был завязан на Telegram-контекст, но приложение уже работало как web-клиент с собственной сессией.

if (this.authService.validateInitData(body.initData, body.hash)) {
  const user = await this.createUserIfNotExists(body.initData, body.userId);
  const accessToken = this.authService.generateAccessToken(user.id, user.tokenVersion, user.role);
  const refreshToken = this.authService.generateRefreshToken(user.id, user.tokenVersion, user.role);
  AuthService.setTokensCookie(res, { accessToken, refreshToken });
}

На этом этапе проект получил два слоя взаимодействия: Telegram приводил пользователя и отправлял уведомления, WebApp забирал на себя продуктовый интерфейс.

Что на самом деле делает продукт

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

Первый сценарий — вишлист. Это список желаний, у которых есть название, ссылка, описание, цена и картинка. В подарочной логике есть важная деталь: участвующие в поздравлении могут забронировать пункт из вишлиста, который решили купить. Тогда несколько человек не купят случайно одно и то же. Сам владелец wishlist не видит, что кто-то забронировал в его вишлисте один из подарков.

Эту логику держит API. Когда wishlist смотрит владелец, backend скрывает данные бронирования.

if (isOwner) {
  dto.isLocked = false;
  dto.lockedBy = null;
} else if (dto.lockedBy && dto.lockedBy.id !== req.userId) {
  dto.lockedBy = null;
}

Одна и та же запись выглядит по-разному для разных пользователей:

  • Для владельца это просто пункт его вишлиста.

  • Для участника подготовки — подарок, который можно забронировать или увидеть как занятый.

  • Для пользователя, который забронировал желание — его ответственность.

Второй сценарий — группы и события. Это пространства подготовки подарка: участники, обсуждение, именинник, invite-ссылка, ответственный за сбор суммы на подарок и правила доступа. И ещё публичность: если пользователь не зарегистрирован на платформе и ему скинули ссылку на вишлист пользователя, ссылка откроется без авторизации.

Третий сценарий — внутренний чат события. Telegram не дал управляемое пространство для приватного обсуждения подарка, поэтому обсуждение переехало внутрь продукта.

В WebSocket-слое тоже есть проверка доступа на основе встроенной механики room. Пользователь не может подключиться к комнате события, если он не участник.

const hasAccess = user?.events?.some((event) => {
  return event.id.toString() === payload.room.toString();
});

if (!hasAccess) {
  return;
}

client.join(payload.room);

Чтобы участники не возвращались к обсуждению в обычных чатах, внутренний чат должен закрывать привычные сценарии: показывать не прочитанные сообщения, поддерживать реакции, ответы на конкретные сообщения. Тогда обсуждение подарка остается удобным внутри события, и договоренности не расползаются обратно по личным сообщениям и отдельным чатам.

Четвертый сценарий — сбор суммы на подарок. В раннем посте это была одна из главных болей: нужно понимать, кто участвует в сборе и какая сумма уже собрана. В текущей системе у события есть ответственный за сбор, собранная сумма, платежные данные и отдельная логика платежей.

В итоге сервис занимается не хранением данных о подарках, а координирует подготовку: кто участвует в сборе, что обсуждают, какая сумма уже собрана и кто отвечает за покупку подарка.

Почему backend стал центром

Когда был только бот, часть логики можно было держать в обработчиках. Пользователь нажал кнопку, бот ответил, состояние изменилось. То есть backend был, но только в роли сервера для Telegram-бота: принимал события из Telegram и отвечает на них.

Когда появились Telegram WebApp, отдельный сайт, публичные ссылки, email-вход, realtime и админские сценарии, такая схема перестала работать. Один и тот же пользователь может прийти из MiniApp, зайти через браузер, открыть публичный wishlist или попасть в событие через invite. Во всех случаях система должна точно понимать, кто он и что ему можно делать.

Так backend перестал быть службой при боте. Он стал местом, где живут правила: доступ к событиям, состав участников, скрытие бронирований, авторизация. A Telegram — один из клиентов рядом с web, публичными страницами и realtime.

Frontend здесь тоже важен: WebApp и отдельный сайт сделали продукт понятным для пользователя. Backend держит правила, но ценность видна через интерфейсы: список желаний, карточки событий, чат, публичные страницы, регистрацию, invite-ссылки и нормальную навигацию.

Когда проект вышел за пределы Telegram

Следующий большой шаг — отдельный сайт и публичные сценарии.

До этого Telegram все еще оставался обязательным контекстом. Даже с WebApp-интерфейсом регистрация была возможна только через бот. Это удобно для старта, но ограничивает продукт. Поэтому понадобилась вторая точка входа.

Публичные wishlist-страницы поменяли модель и стали первым сценарием, где Telegram больше не нужен: пользователь может открыть ссылку вида /u/:username и посмотреть желания человека, если тот дал на это согласие.

В backend появился публичный контроллер, который отдает wishlist по username, но не раскрывает лишнего. В публичной выдаче остаются только данные, которые можно показывать внешнему пользователю.

return {
  name: dto.name,
  description: dto.description,
  link: dto.link,
  price: dto.price,
  image: dto.image,
  isGifted: dto.isGifted,
};

Во frontend под это есть отдельный route без авторизации.

{
  path: 'u/:username',
  children: [ ... ]
}

Похожая история с invite flow. Событие можно открыть по токену, посмотреть базовую информацию и присоединиться, если правила это позволяют. Канал входа меняется, правила сценария остаются общими.

Позже появилась email-регистрация. Она сняла обязательную привязку к Telegram, который перестал быть условием существования пользователя в системе.

Изначально Telegram-группы помогали управлять составом внутренних групп событий: через них добавляли и исключали пользователей. Сейчас Telegram можно подключить как канал уведомлений о новых событиях, назначенных ответственных и днях рождения в календаре Ещё авторизованным через Telegram пользователям приходят личные уведомления через бота.

На этом этапе проект стал платформой с несколькими точками входа: Telegram MiniApp, отдельный сайт, публичные ссылки, email-аккаунт. Все они обращаются к одной продуктовой модели.

Инфраструктура как следствие боли

Инфраструктура обычно появляется, когда менять проект становится страшно.

Пока проект был ботом, многое можно было проверить руками: поправить обработчик, нажать пару кнопок, посмотреть ответ Telegram. Для MVP терпимо.

Когда один backend обслуживает Telegram, MiniApp, отдельный web, публичные страницы, realtime, фоновые задачи и уведомления, цена ошибки возрастает. Одно изменение может сломать авторизацию, чат, деплой.

Отсюда вырос отдельный orchestration-слой. Он собирает вокруг продукта backend, frontend, nginx, Redis, docker-compose, CI/CD и Makefile-команды. Этот слой не виден пользователю, зато продукт удобнее развивать и выкатывать.

В docker-compose видно, что система живет как набор связанных сервисов.

services:
  nginx:
    depends_on:
      backend:
        condition: service_healthy

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]

  backend:
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:${APP_PORT}/api/health || exit 1"]

Nginx ждет здоровый backend, Redis поднимается отдельно, backend имеет healthcheck, frontend собирается своим слоем. На этом этапе продукт уже нужно собирать, выкатывать и проверять как систему.

CI/CD закрепил ту же логику. В pipeline появились стадии validate, prepare, build, deploy, verify. Makefile закрыл повторяемые команды: деплой всего продукта, отдельно frontend, отдельно backend, dev-ветка, проверки статуса и синхронизация submodules.

Redis здесь тоже появился из практической нагрузки: Telegram-сессии, throttling, rate limiting и кеширование tokenVersion для auth-запросов. Он снижает лишние обращения к базе и убирает часть состояния из памяти процесса.

Текущая форма продукта

К этому этапу система уже объединяла вишлисты, события, участников, обсуждения, бронирования, сбор суммы, уведомления и публичные ссылки. Telegram MiniApp и бот остались удобными точками входа, а общая логика переехала в backend и frontend.

Пользователь может:

  • Прийти через Telegram, открыть MiniApp и работать внутри привычного мессенджера.

  • Зайти на сайт. 

  • Зарегистрироваться по email. 

  • Поделиться публичной ссылкой на wishlist. 

  • Попасть в событие через invite. 

Для продукта это разные входы в одну и ту же модель.

В отчетном посте на апрель 2026 уже было 455 человек — без дополнительного привлечения и рекламы. Для pet/side/hackathon-проекта это хороший сигнал: сценарий не был выдуманным. Людям действительно нужен способ проще координировать подарки и не держать все в чатах.

Итоговая схема: Telegram остался каналом входа и уведомлений. MiniApp дал удобный интерфейс внутри Telegram. Отдельный сайт убрал обязательную зависимость от Telegram. Backend стал местом, где живут правила продукта. Realtime закрыл обсуждения событий. Инфраструктура сделала все это сопровождаемым.

Что я бы сделал раньше

Старт через Telegram был правильным решением для первой проверки идеи. Пользователи уже были в мессенджере, сценарий был разговорным, а бот позволял быстро собрать рабочий путь без большого frontend.

Но границу между каналом и продуктовой моделью я бы провел раньше.

Удачный старт легко спутать с удачной долгосрочной архитектурой. Telegram помог быстро появиться, но потом начал диктовать ограничения там, где продукту уже нужны были собственные правила: приватность обсуждений, роли участников, события, бронирования, invite-ссылки и разные точки входа.

Backend быстро выходит за рамки CRUD, если продукт не просто хранит данные, а координирует действия нескольких людей. Пользователь участвует в процессе: обсуждает, бронирует, присоединяется, участвует в сборе, получает уведомления, видит одну часть информации и не видит другую.

Инфраструктуру лучше не откладывать до момента, когда менять уже страшно. Миграции, health checks, CI/CD, Redis, воспроизводимое окружение и нормальная схема деплоя выглядят избыточно, пока проект маленький. Потом внезапно оказывается, что без них каждое изменение превращается в маленькое гадание.

Ссылка на текущую версию приложения: https://gifth.ru/ 

Если сжать весь путь проекта до одной мысли, она будет такой: быстрый внешний канал помогает стартовать, но продукт должен вовремя стать самостоятельной системой.

Проект перерос Telegram по простой причине: реальный сценарий организации подарков потребовал собственной модели приватности, ролей, событий, обсуждений и точек входа.