Портал на Payload

Личный кабинет или портал заявок на Payload CMS 3 собирается из штатных механизмов: коллекция пользователей с авторизацией, правила доступа на коллекциях и полях, хуки для статусов и писем, поля загрузки файлов. Партнёр видит только свои заявки, менеджер все, заявку без обязательных фото нельзя отправить, переписка идёт внутри заявки, а письма уходят с вашей почты. Всё это описано кодом в одном приложении Next.js, без второго бэкенда и сторонних плагинов. Так устроен портал гарантийных заявок ДС Энерджи, который мы запустили в сентябре 2026 года, ниже по частям, как это собирается.

Кабинет в админке или отдельный фронт

Первое решение: где будут работать пользователи.

ВариантКогда подходитЧто получаете
Админка PayloadРабочие порталы: партнёры, дилеры, сервисные центры, сотрудникиГотовые списки, фильтры, формы, загрузка файлов, адаптив. Настраиваются колонки, названия, свои компоненты
Свой фронт на Next.jsКабинет клиента с брендовым дизайном, много неподготовленных пользователейЛюбой интерфейс, данные через Local API на сервере или REST
СмешанныйПартнёры в админке, клиенты на сайтеОдна база и одни правила доступа на оба интерфейса

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

Роли и доступ

Пользователи хранятся в коллекции с auth: true, роль это обычное поле select. Права описываются функциями доступа на каждую операцию коллекции: create, read, update, delete и admin (пускать ли в админку). Функция может вернуть true, false или условие выборки, и тогда пользователь видит только подходящие записи. Отдельно работают права на уровне полей: create, read, update для каждого поля.

Пример для портала гарантийных заявок:

ЧтоСервисный центрПартнёр (дилер)Менеджер производителя
Создать заявкуДаДаДа
Видеть заявкиТолько своиСвоей сетиВсе
Менять данные заявкиПока статус черновик или доработкаНетДа
Поле суммы к оплатеВидит, не меняетНе видитМеняет
Внутренний комментарийНе видитНе видитВидит и меняет
Менять статусОтправить, вернуть после доработкиНетВсе переходы
ПользователиСвой профильСвой профильЗаводит и блокирует

Главное свойство: правила живут в схеме коллекции, а не во фронте. Payload применяет их одинаково в админке, REST, GraphQL и Local API. Если поле скрыто от роли, оно не придёт и в ответе API, спрятать его только в интерфейсе не получится. Файлы из коллекции загрузок отдаются через Payload с проверкой тех же прав, поэтому фото чужой заявки по прямой ссылке не откроется.

Статусы и переходы

Статус заявки это поле select, а порядок переходов проверяется в хуке beforeChange коллекции. Хук получает новое значение в data и прежнее в originalDoc, знает пользователя из req и отклоняет запрещённый переход с понятной ошибкой.

Из статусаВ статусКто может
ЧерновикОтправленаСервисный центр, если приложены обязательные файлы
ОтправленаНа проверкеМенеджер
На проверкеНужна доработкаМенеджер, с комментарием
Нужна доработкаОтправленаСервисный центр
На проверкеОдобрена или ОтклоненаМенеджер
ОдобренаОплаченаМенеджер

В хуке afterChange сравниваем doc.status с previousDoc.status и при смене статуса отправляем письмо нужной стороне. Там же пишем запись в журнал: кто, когда, из какого статуса в какой. Если нужна полная история всех правок, включаем у коллекции версии, и в админке появится вкладка с каждым сохранённым состоянием заявки.

Обязательные файлы

Фото и документы хранятся в коллекции с upload: true, в заявке это поля типа upload со связью на неё. Обязательность задаётся на уровне схемы: required: true у поля или своя функция validate, если правило сложнее, например "не меньше двух фото шильдика" или "акт нужен только для платного ремонта". Опция mimeTypes ограничивает типы файлов (image/*, application/pdf), imageSizes делает уменьшенные копии для быстрого просмотра.

На портале ДС Энерджи к каждой заявке нужны гарантийный талон, акт и фото шильдика котла. Без них заявку нельзя отправить, и проверка работает на сервере, поэтому никакой фронт её не обойдёт. Большие объёмы файлов лучше хранить в S3-совместимом хранилище российского провайдера через официальный адаптер @payloadcms/storage-s3.

Переписка по заявке

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

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

Вход, пароли и письма

Коллекция пользователей с auth даёт из коробки вход по email и паролю, выход, сброс пароля, получение текущего пользователя и обновление токена. В браузере Payload держит сессию в HTTP-only cookie, недоступной скриптам на странице, а мобильному приложению или интеграции отдаёт JWT. Штатные опции, которые мы настраиваем почти всегда:

Письма отправляются через адаптер @payloadcms/email-nodemailer по SMTP с ящика на вашем домене. Отдельно настраиваем SPF, DKIM и DMARC, иначе корпоративные почты партнёров будут складывать письма в спам. На переезде ДС Энерджи именно доставка писем была одной из причин уйти с Firebase: письма сброса пароля от Google доходили не до всех.

Телефон и камера

Админка Payload адаптивная, списки и формы нормально работают на экране телефона. Поле загрузки файла на телефоне предлагает выбрать снимок из галереи или сразу снять камерой. Писать для этого отдельное приложение не нужно. Для сервисного инженера, который оформляет заявку у котла, это оказалось самой полезной частью портала.

Как мы делали портал ДС Энерджи

ДС Энерджи производит котельное оборудование. Сервисные центры заводят гарантийные заявки с фото, производитель проверяет их и оплачивает работы. Портал раньше работал на Firebase, в 2026 году мы перевезли его на Payload, подробно про сам переезд на странице переезд с Firebase.

Сверх переноса данных портал получил:

Пользователи вошли на новый портал со старыми паролями. После тестового периода боевое переключение прошло 17 сентября 2026 года. Дальше в планах автопроверка гарантийного срока, контроль повторных серийных номеров, реестр на оплату и дашборд, и всё это ложится в ту же схему хуками и новыми коллекциями.

Что нужно от вас

Этапы

  1. Разбираем процесс и фиксируем роли, статусы, поля и письма в одной таблице.
  2. Схема коллекций и права доступа, первая версия в админке на тестовом сервере.
  3. Вы с парой реальных пользователей работаете на тесте, мы правим поля и переходы.
  4. Письма, перенос данных из старой системы, если он нужен.
  5. Запуск на вашем сервере и две недели наблюдения за логами.

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

Сколько стоит

Считаем по часам после просмотра задачи. На цену влияют число ролей и статусов, сложность правил проверки, объём переноса, количество писем и внешних интеграций, нужен ли отдельный фронт вместо админки. Хостинг после запуска это обычный VPS в России с Docker и PostgreSQL, оплата хостеру в рублях. Про выбор базы подробнее в статье Postgres или MongoDB для Payload.

Опишите, кто работает с заявками сейчас и как они движутся, можно прямо в виде таблицы Excel или скриншотов старой системы. Разберём процесс и на следующий день пришлём список работ, срок и сумму.

Частые вопросы

Можно ли сделать личный кабинет прямо в админке Payload?

Да, и для рабочих порталов это самый быстрый путь. Админка Payload показывает каждому пользователю только те коллекции, записи и поля, которые разрешены его роли, поэтому партнёр видит свои заявки, а менеджер все. Если нужен отдельный кабинет со своим дизайном, его делают на Next.js в том же приложении, правила доступа остаются те же.

Как партнёр увидит только свои заявки?

Функция доступа read в коллекции заявок возвращает не да или нет, а условие выборки: заявки, где поле организации совпадает с организацией пользователя. Payload применяет это условие везде: в админке, в REST, GraphQL и Local API. Обойти его запросом с фронта нельзя.

Будет ли кабинет работать с телефона?

Да, админка Payload адаптивная из коробки, а поле загрузки файла на телефоне предлагает снять фото камерой. Сервисные центры ДС Энерджи заполняют заявки с телефона прямо у котла.

Как работает сброс пароля и откуда приходят письма?

Сброс пароля встроен в коллекцию пользователей с auth. Письма уходят через почтовый адаптер @payloadcms/email-nodemailer по SMTP с вашего ящика на вашем домене. Текст письма свой, на русском.

Можно ли подключить к порталу мобильное приложение или 1С?

Да. У каждой коллекции есть REST и GraphQL API, вход по JWT, а для интеграций ключи API на пользователя (опция useAPIKey). Правила доступа действуют и там.

Сколько стоит портал заявок на Payload?

Считаем по часам после просмотра задачи: сколько ролей, статусов, типов документов, писем и интеграций. Оценку и срок называем на следующий день.

Обсудим ваш проект

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