ПроектыПроект для клиента

SetHub CRM — операционная система съёмочной студии

Веб-CRM, в которой студия из Даунтауна Лос-Анджелеса ведёт всё: брони с четырёх каналов, запросы, задачи команды, деньги, переписку с гостями и девятнадцать календарей. Письма площадок, оплаты Stripe и сообщения в Telegram сами становятся записями, обычный текст разбирается без ИИ, а ChatGPT и Claude работают с данными по тем же правам, что и люди.

  • Next.js 16 · React 19
  • TypeScript strict
  • PostgreSQL 16 · Prisma 6 · pg_trgm
  • Stripe · Gmail · Google Calendar
  • MCP · OAuth 2.1

В цифрах

43таблицы и 50 миграций — от брони и выплаты площадки до записи встречи
836автотестов в 74 файлах: каждая функция проверяется на временной базе Postgres
26команд для ChatGPT и Claude по MCP — и ни одна ничего не удаляет
1292строки словаря интерфейса: вся CRM на английском и русском

Задача

До CRM студия жила в таблице и в почте. Брони Peerspace и Giggster приходили письмами, оплаты сайта — в Stripe, прямые брони — сообщениями менеджеру, запросы — в Instagram. Чтобы ответить, свободен ли Victorian Set в субботу, нужно было открыть четыре места. Деньги сводились в конце месяца руками, личные траты владельца смешивались с расходами бизнеса, задачи терялись в чатах, а сроки сдвигались молча. Цена ошибки здесь — не опечатка, а две съёмочные группы у одной двери и деньги, которые никто не заметил.

Что внутри

Дашборд владельца: безубыточность в реальном времени

Главный экран показывает, сколько студия заработала в этом месяце против расходов бизнеса и где проходит линия безубыточности. Выручка — только состоявшиеся брони; подтверждённые будущие идут отдельной строкой «забронировано вперёд», чтобы не выдавать желаемое за заработанное. Личные траты владельца хранятся с отдельным флагом и в P&L бизнеса не попадают — их видит только он. Ниже — итог по месяцам, загрузка и выручка каждого из 19 мест, доли каналов.

Накладка — это отказ, а не предупреждение

Пересечение броней проверяет одна функция для всех входов: форма, «Захват», приложение, письма площадок и команды ИИ. Вся студия закрывает 16 сетов внутри неё, любой сет закрывает студию, а крыша и площадка с машиной — только себя. Сознательная накладка возможна только кнопкой «Сохранить всё равно», и форма при этом не теряет набранное. Уже стоящие пересечения собираются красным блоком над списком броней. Оплата меняется отдельными кнопками — депозит, остаток, возврат, — а «Сохранить» её не трогает.

«Захват»: любое сообщение — черновик записи

Текст, фото чека, PDF, голосовое, файл Word — одно окно на всех. Обычный текст разбирают правила, без ИИ: дату, время, сумму и депозит, контакты, площадку, источник, сотрудника, известного клиента; угаданное подсвечивается, уверенность показана в процентах. Модель нужна только тому, чего нет текстом: голосу, снимкам и сканам. То же сообщение от того же человека в течение десяти минут вернёт уже заведённое, а не создаст дубль. Ничего не записывается, пока человек не подтвердит.

Рабочее место менеджера: что сделать прямо сейчас

Запрос получает номер SH-xxxx и идёт по этапам: новый, в разговоре, ждём депозит, подтверждён, завершён или потерян. Уровень внимания не хранится, а вычисляется: клиент ответил — «ответьте», депозит просрочен на два дня, нет следующего шага — всё красным и наверх очереди. Тем же правилом считается число в меню, поэтому оно никогда не расходится со списком. Для обзора — доска с перетаскиванием карточек между этапами.

Задачи, чьи сроки не сдвигаются молча

Срок и исполнителя ставят владелец и менеджер; сотрудник срок не правит, а просит перенос с новой датой и причиной — запрет стоит на сервере, а не в форме. У задачи есть чекпоинты: менеджер отмечает их выполненными или пропущенными, исполнитель пишет объяснение, и отмеченное уже не правится. Напоминания приходят за час до срока, при просрочке и каждое утро с 9 до 20 по часам студии. Люди различаются цветом, задачи группируются по исполнителю со счётом «в работе · готово».

Поиск с опечатками за десятые доли секунды

⌘K ищет сразу по клиентам, броням, запросам, задачам и расходам: начало слова, вхождение и триграммное сходство pg_trgm — «victorain» найдёт Victorian. Телефон находится по цифрам в любом формате, дата — в любом виде: «11/5», «5 ноя», «Nov 5», сумма — с долларом и без. Результат открывается окном поверх страницы: правка сохраняется на месте, набранное в форме под окном не пропадает, а права те же, что у страницы.

Площадки и оплаты — без участия человека

Скрипт в почте студии раз в пять минут присылает письма Peerspace и Giggster: «забронировано» становится оплаченной бронью с комиссией площадки и выплатой студии, перенос двигает уже заведённую, отмена снимает, выплата сверяется по гостю и сумме. Сама записывается только бронь из письма, которое прошло проверку DMARC и прочитано целиком. Оплата Stripe приходит вебхуком с проверкой подписи HMAC и становится бронью со строками счёта — за что именно заплатил гость.

Оповещения: каждому — своё, на его языке

Каждое действие пишется в журнал и превращается в строки оповещений для тех, кому они нужны по роли: менеджеру — новые запросы, исполнителю — его задачи, владельцу — всё, кроме собственных действий. Строки копятся минуту тишины и уходят одним письмом; push в браузер шифруется по стандарту Web Push без сторонних библиотек; Telegram — одним сообщением с кнопкой. Язык по умолчанию — английский, русский — по выбору человека.

ИИ-помощники по MCP — с правами человека

ChatGPT и Claude подключаются к CRM как к серверу MCP со входом по OAuth 2.1: PKCE S256, белый список адресов возврата, ротация ключей обновления, а повтор уже заменённого ключа считается кражей и гасит доступ целиком. 26 команд — брони, задачи, клиенты, запросы, расходы — проверяют те же роли, что страницы, и удаления нет ни в одной. Смена пароля, роли или выключение учётной записи гасит сессии браузера, ключи телефонов и доступы ИИ.

Экраны

Дашборд владельца: прибыль месяца против линии безубыточности и итог по месяцам
Дашборд владельца: прибыль месяца против линии безубыточности и итог по месяцам
Календарь месяца по всем 19 местам: точки — брони дня, справа — расписание выбранного дня
Календарь месяца по всем 19 местам: точки — брони дня, справа — расписание выбранного дня
Очередь менеджера: внимание вычисляется — «клиент ответил», «депозит просрочен», «нет следующего шага»
Очередь менеджера: внимание вычисляется — «клиент ответил», «депозит просрочен», «нет следующего шага»
Доска запросов: карточки переходят между этапами перетаскиванием, сумма и следующий шаг на виду
Доска запросов: карточки переходят между этапами перетаскиванием, сумма и следующий шаг на виду
Заявка из Instagram стала черновиком брони: поля разобрали правила, без ИИ
Заявка из Instagram стала черновиком брони: поля разобрали правила, без ИИ
Задачи по людям и категориям: просрочка красным, следующий чекпоинт прямо в строке
Задачи по людям и категориям: просрочка красным, следующий чекпоинт прямо в строке
⌘K: клиенты и брони по одному запросу, совпадение подсвечено
⌘K: клиенты и брони по одному запросу, совпадение подсвечено
Бронь открыта окном поверх дашборда: правка без перехода и без потери набранного
Бронь открыта окном поверх дашборда: правка без перехода и без потери набранного
Переписка с гостем: ответ уходит ему письмом через пару минут тишины
Переписка с гостем: ответ уходит ему письмом через пару минут тишины

Технологии

Next.js 16 на App Router и серверных действиях, React 19, TypeScript в строгом режиме — около 60 тысяч строк вместе с приложениями. PostgreSQL 16 через Prisma 6: 43 таблицы, 50 миграций, каждая выкладка применяет их при старте, а перед любой миграцией снимается копия базы с проверкой восстановлением. Поиск — расширение pg_trgm и запросы на сыром SQL с весами полей. Время везде хранится «по часам студии» и сравнивается со «сейчас» Лос-Анджелеса, а не сервера: брони, сроки и границы месяца не съезжают при переводе часов.

Все 836 автотестов поднимают временную базу Postgres и проверяют функцию целиком — от записи до оповещения. Права живут в одном модуле ролей, который используют страницы, действия сервера, 73 маршрута API и команды ИИ: спрятанная кнопка защитой не считается. Почта, календари и платежи подключены без посредников: скрипт Google в ящике студии, календари Google через служебную учётную запись, вебхук Stripe с проверкой подписи. Видео на главной сайта студия меняет сама: ролик сжимается в браузере в H.264, сервер проверяет файл по байтам.

Нужна CRM под ваш процесс?

Расскажите, откуда приходят заказы и где они теряются. Начнём с одного узкого места — у Set Hub это были письма площадок, — а остальное вырастет вокруг.

WhatsApp