Перейти к содержимому

Работы

2025

LensMap — маркетплейс фотографов

PWA-маркетплейс: поиск фотографа по карте, публичные профили, заявки и бронирование с депозитом, админ-панель, RU/EN.

Роль

  • Архитектура
  • Разработка
  • DevOps
  • SEO

Стек

  • Next.js 15
  • Supabase
  • PostgreSQL
  • Vercel
  • Stripe
  • OpenAI

Карта как основной интерфейс поиска

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

Публичные профили — поисковая поверхность продукта

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

Заявка и бронирование разведены

Заявка и оплата — два разных обязательства, и объединять их в один шаг значит терять людей, которые ещё только уточняют дату. Сначала заявка и переписка с фотографом, и только после подтверждения — депозит через Stripe. Депозит нужен именно как стоимость отмены: бронь, которая ничего не стоит, отменяется бесплатно и обесценивает календарь другой стороны.

Админ-панель под фотографа, а не под администратора

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

Авторизация живёт в базе, а не в интерфейсе

Row Level Security в Supabase означает, что правила доступа описаны в базе, а не в коде приложения: забытая проверка в UI не может показать одному фотографу заявки другого, потому что строки просто не вернутся из запроса. Цена решения — отладка политик сложнее отладки обычного if, и ошибка в политике ломает продукт целиком, а не одну страницу. На площадке, где чужие персональные данные и суммы лежат в одной таблице с вашими, это правильный размен. Вход — OAuth 2.0, плюс верификация почты и телефона.

RU/EN как две версии контента, а не два словаря

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

  • PWA
  • Маркетплейс
  • AI
  • Карты