Прочитанную книгу нельзя оставлять пылиться.
Социальная платформа для обмена бумажными книгами с соседями, коллегами и друзьями. Компьютерное зрение, интерактивные карты, real-time-база данных и живое invite-only-сообщество — спроектировано, написано и развёрнуто в одиночку.
«Книжная полка» превращает вашу личную библиотеку в общую. Никаких магазинов, посредников и рекламы — только живой обмен книгами между людьми, которые рядом. Это про чтение, общение и экологичное потребление: одна бумажная книга проживает много жизней вместо того, чтобы пылиться на полке.
Сообщество закрытое, invite-only — так между участниками сохраняется высокий уровень доверия. Вы делитесь книгами с теми, кого пригласили, и с теми, кто пригласил их.
Весь продукт построен вокруг одного бесшовного сценария. От добавления книги до передачи из рук в руки — шесть шагов, и контакты открываются только тогда, когда это действительно нужно.
Каждая функция — это отдельный инженерный вызов: от компьютерного зрения до атомарных операций в облачной базе. Ниже — интерактивные демонстрации. Попробуйте сами.
Пользователи отмечают на карте удобную точку для встреч — кафе или коворкинг — не раскрывая домашний адрес. Поиск учитывает геолокацию: вы видите книги в радиусе 3 км, а расстояние считается по формуле гаверсинусов прямо на клиенте.
Наведите камеру на обложку. Снимок уходит в Google Gemini через официальный GenAI SDK — модель мгновенно распознаёт название и автора по изображению с точностью до 98% и сама заполняет форму добавления.
При ручном вводе приложение в реальном времени обращается к Gemini за релевантными подсказками. Чтобы не жечь токены и не подвешивать интерфейс, запрос уходит через debounce 300 мс и только после 3 символов.
Как только известны название и автор, приложение обращается к Open Library API и подтягивает официальную обложку книги. Полка выглядит красиво без единого действия пользователя.
Система достижений за приглашения, добавленные книги и обмены — с эффектной анимацией разблокировки на Framer Motion. А ещё по экрану бегает интерактивный кролик и съедает случайно появляющиеся цветы 🌸. Маленькая радость, которая делает продукт живым.
Telegram-юзернейм скрыт и открывается только после того, как обе стороны подтвердили обмен. Никакого спама и случайных сообщений — доверие встроено в саму механику.
Тонкий React-клиент напрямую работает с облачными сервисами Firebase и внешними API, а лёгкий Node-сервер за Nginx раздаёт статику в продакшене. Наведите на узел, чтобы подсветить связи.
Firestore спроектирован документоориентированно и денормализованно — ради минимальных задержек и работы real-time-слушателей. Координаты встречи копируются в документ книги, чтобы гео-запросы были мгновенными.
Три задачи, которые отличают учебный проект от продакшена — и как они были решены.
VPS имеет всего 1 ГБ памяти и ноль swap-пространства. Запуск сборки vite build прямо на сервере мгновенно ронял его: OOM-киллер Linux убивал процесс и сбрасывал SSH-соединение.
Сборка фронтенда вынесена на локальную машину. Готовый оптимизированный бандл из dist/ копируется на сервер через scp -r. Express под PM2 в режиме NODE_ENV=production раздаёт статику, потребляя всего ~25 МБ — сервер стабилен.
При обмене статус книги, статистика владельца и получателя должны обновляться мгновенно у всех — без ручного обновления страницы.
Слушатели onSnapshot на коллекциях книг и пользователей. При подтверждении обмена статус транзакционно меняется на booked, а счётчики растут через атомарный increment(). Клиенты получают обновления «по воздуху» и перерисовывают интерфейс сами.
Запрос к ИИ на каждую введённую букву означал бы огромный расход токенов и зависания интерфейса в ожидании сети.
Механизм debounce на 300 мс: запрос уходит, только когда пользователь остановился. Плюс минимум 3 символа и graceful fallback — при ошибке сети или превышении лимитов подсказки бесшовно скрываются, не мешая ручному вводу.
Идея, UX, код и деплой — в одиночку. Посмотрите, как это работает вживую.