Техническая документация
SaaS-платформа для создания маркетплейсов, интернет-магазинов и досок объявлений. Пользователь выбирает тип сайта, модули, тему — и получает готовую платформу за минуты.
Стек
Next.js 16 · Payload CMS 3.x · PostgreSQL · Tailwind CSS 4 · Socket.IO · TypeScript
1О проекте
MyStores — SaaS-платформа для создания маркетплейсов, интернет-магазинов и досок объявлений. Пользователь выбирает тип сайта, модули, тему — и получает готовую платформу за минуты. Каждый сайт = отдельный тенант в Payload CMS. Платформа управляет данными, медиа, заказами, отзывами и уведомлениями через единую инсталляцию Payload.
- Магазин — Каталог, корзина, оформление заказов, приём платежей
- Маркетплейс — Мультипродавцовая платформа с комиссией и рейтингами
- Доска объявлений — Публикация, модерация, категории, продвижение
3Архитектура
- Next.js 16.2.6 — App Router, Server Components, Server Actions, standalone output
- Payload CMS 3.85.x — headless CMS, PostgreSQL, REST + GraphQL API, Lexical editor
- Мультитенантность — через @payloadcms/plugin-multi-tenant (customTenantField, tenant selector в админке)
- Route Groups — (site)/ для витрины, (payload)/ для админки Payload. У каждой группы свой layout с html/body
- Изоляция данных — по tenant relationship в каждой коллекции. Доступ фильтруется через access control
- Tailwind CSS 4 — стилизация, shadcn/ui компоненты
- withPayload() — в next.config.ts, авто-генерирует importMap при build
Критичные особенности Payload 3.x
getPayload({ config }), НЕ устаревшийpayload.init()@payload-configpath alias →./payload.config.tsв корне проекта- Server Actions:
'use server'обязателен для serverFunction handleServerFunctionsиз@payloadcms/nextтребует/* webpackIgnore: true */dynamic import- RootLayout из
@payloadcms/next/layoutsрендерит свой html/body — нельзя вкладывать @payloadcms/next/cssОБЯЗАТЕЛЬНО импортировать в layout для стилей админки
4Коллекции Payload CMS
| Коллекция | Описание | Ключевые поля | Auth |
|---|---|---|---|
tenants | Тенанты/сайты | name, slug, type, modules (json), theme (json), settings (json) | — |
users | Администраторы CMS | email, role, tenants[] | Да (built-in) |
products | Товары | name, slug, price, oldPrice, category, images[], features, description, status, stock, tenant | — |
categories | Категории | name, slug, parent, image, icon, order, filters (json), tenant | — |
orders | Заказы | orderNumber, status, customer, items (json), total, shippingAddress (json), promoCode, paymentMethod, tenant | — |
reviews | Отзывы | author, rating (1-5), content, product, tenant, verified, pros, cons | — |
pages | Страницы (редактор) | title, slug, type (home/custom/category/landing), modules (json), published, tenant, seoTitle, seoDescription | — |
notifications | Уведомления | type, title, message, read, relatedId, relatedType, tenant | — |
media | Медиафайлы | url, alt, tenant | — |
listings | Объявления | title, description, price, status, images[], category, tenant | — |
sellers | Продавцы | name, description, rating, logo, tenant | — |
customers | Покупатели | email, name, phone, favorites (json), compareList (json), addresses (json), tenant | Да (useAPIKey) |
Hooks: createNotification — beforeChange hook на Orders, автоматически создаёт уведомление при новом заказе.
5Модульная система
tenant.modules — JSON-массив активных модулей. Каждый модуль управляет доступностью функционала. Хук useModule(name) проверяет наличие модуля в контексте.
| Модуль | Статус | Что включает |
|---|---|---|
catalog | Реализовано | Каталог товаров, категории, фильтрация по цене, поиск, grid/list toggle |
cart | Реализовано | Корзина, промокод, оформление заказа (гостевой чекаут), прогресс-бар, выбор доставки/оплаты |
payments | Фронтенд | Выбор способа оплаты (визуально). Бэкенд Stripe/другой будет позже |
classifieds | Реализовано | Объявления, модерация, категории |
marketplace | Реализовано | Продавцы, мультипродавцовая платформа |
search | Плагин | Поиск через @payloadcms/plugin-search (products, categories, listings) |
reviews | Реализовано | Отзывы с рейтингом, верификацией, плюсами/минусами |
email | По команде | Настройки уведомлений. Email-адаптер Resend установлен, но не активирован |
analytics | Реализовано | Дашборд аналитики с графиками выручки, заказов, топ товаров |
seo | Плагин | SEO через @payloadcms/plugin-seo (products, pages), tabbedUI, автогенерация title/description |
chat | Реализовано | Чат покупатель-продавец. Коллекции ChatRooms + Messages, API routes, UI списка чатов и переписки. Socket.IO для реалтайма (отдельный PM2 процесс siteforge-socket на порту 3011) |
notifications | Реализовано | Авто-уведомления о заказах, CRUD, страница уведомлений |
6Тематизация
tenant.theme — JSON с настройками внешнего вида. Компонент ThemeStyles инжектит CSS-переменные. Контекст TenantContext предоставляет данные через хуки useTenant() и useModule(name).
CSS-переменные
--sf-primary/--sf-secondary/--sf-accent--sf-bg/--sf-text--sf-border-radius--sf-font-heading/--sf-font-body
7-9Дорожная карта
- XSS-защита: sanitizeHtml для описаний товаров (isomorphic-dompurify)
- Страницы ошибок (error.tsx + global-error.tsx) с брендингом
- Skeleton-загрузки (loading.tsx) для лендинга и каталога
- Доступность (a11y): skip-nav, aria-labels, focus-visible
- Полное удаление dangerouslySetInnerHTML с лендинга
- Favicon + app icons, error pages для тенанта
- Skeleton-загрузки каталога/корзины
- Nginx caching _next/static (immutable)
- OG-image + улучшенный manifest
- Интерактивный переключатель на /demo
- Brotli-сжатие в Nginx (~20% меньше vs gzip)
- Rate limiting: 3 зоны (general, API, auth)
- Brotli-сжатие в Nginx
- PWA Service Worker (cache-first для статики)
- Open Graph / Twitter Cards метаданные
- Оптимизация Next.js Images (AVIF/WebP)
- Middleware: www-редирект + trailing slash
- metadataBase — исправление OG/Twitter изображений
- Notifications API — GET/PATCH/DELETE
- CDEK клиент + Delivery API (6 тарифов)
- Расширенные настройки магазина (6 секций)
- Email-уведомления (4 шаблона + API)
- Кастомная 404 для магазинов
- Shared типы Product + formatPrice + Payload конвертер
- Полноценный поиск с фильтрами и пагинацией
- Регистрация/авторизация покупателей end-to-end
- Graceful fallback для 15 пустых ENV
- Sentry конфигурация (client + server + edge)
- OAuth VK/Google — уже настроены в NextAuth
- Admin Integrations Dashboard
10.5Инфраструктурный аудит и план улучшений
По результатам комплексного аудита платформы выявлены критичные и рекомендованные улучшения. Задачи отсортированы по приоритету: от безопасности и стабильности до UX-полировки.
| Задача | Статус | Реализация |
|---|---|---|
| Security Headers в Nginx | Выполнено | X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy, Permissions-Policy, Content-Security-Policy. server_tokens off. |
| Скрыть X-Powered-By: Next.js | Выполнено | poweredHeader: false в next.config.ts + server_tokens off в Nginx. |
| Стабилизация PM2 | Выполнено | max_memory_restart 512M, listen_timeout 60s, wait_ready, logrotate 50M/7d сжатие. |
| Убрать dangerouslySetInnerHTML с лендинга | Выполнено | LandingClient.tsx переписан на безопасный React/JSX рендеринг. |
| Исправить DOM toggle мобильного меню | Выполнено | useState (mobileMenuOpen) + условный рендеринг вместо DOM-манипуляций. |
| Расширенные OG-теги и Twitter Cards | Частично | Полные Open Graph мета-теги через generateMetadata() в layout и page.tsx. |
| Sitemap.xml и robots.txt для платформы | Частично | src/app/sitemap.ts и src/app/robots.ts для индексации маркетинговых страниц. |
| Canonical URLs на всех страницах | Частично | rel=canonical через metadata.alternates.canonical в generateMetadata(). |
| Кастомная страница 404 | Выполнено | Брендированная 404 с анимированным градиентом, логотипом, полем поиска, ссылками. |
| Плавные анимации переходов | Не реализовано | CSS/Framer Motion: fade-in для секций, slide-in для карточек, hover-эффекты. |
| Улучшение секции Pricing | Выполнено | 3 тарифа, highlighted «Профи», сравнение функций, FAQ с аккордеоном, CTA. |
11Известные проблемы и решения
- PM2 частые рестарты (18+) — Решено: importMap настроен для multi-tenant, DB column tenant_id исправлен, sharp установлен.
- /admin 500 ошибка после добавления Customers — Решено: ALTER TABLE payload_preferences_rels ADD COLUMN customers_id.
- React hydration #418 — Решено через route groups: (site)/ и (payload)/ с отдельными html/body.
- Missing Payload CSS — Решено: обязательный импорт @payloadcms/next/css в (payload)/layout.tsx.
- Email пишется в консоль — Ок: нужен email-адаптер (Resend/SendGrid). Пока не критично.
- Multi-tenant plugin не настроен — Решено: плагин подключён, customTenantField настроен, DB column переименован.
12Структура ключевых файлов
src/
├── app/
│ ├── (payload)/ # Payload CMS admin + API
│ │ ├── admin/[[...segments]]/page.tsx
│ │ ├── api/[...slug]/route.ts
│ │ ├── graphql/route.ts
│ │ └── layout.tsx # RootLayout from @payloadcms/next
│ ├── (site)/ # Публичные страницы
│ │ ├── [siteId]/ # Страницы тенанта
│ │ │ ├── layout.tsx # TenantProvider + CustomerAuth + ThemeStyles
│ │ │ ├── page.tsx # Главная (Hero, категории, новинки)
│ │ │ ├── catalog/ # Каталог с фильтрами
│ │ │ ├── product/[id]/ # Карточка товара + ProductClient
│ │ │ ├── cart/ # Корзина + чекаут
│ │ │ ├── search/ # Поиск
│ │ │ ├── favorites/ # Избранное
│ │ │ ├── compare/ # Сравнение (макс 4)
│ │ │ ├── account/ # Личный кабинет
│ │ │ ├── auth/ # Логин/регистрация покупателя
│ │ │ ├── order-success/ # Подтверждение заказа
│ │ │ └── admin/ # Админ-панель тенанта
│ │ ├── onboarding/ # 5-шаговый wizard
│ │ ├── editor/ # Визуальный редактор
│ │ ├── login/ # Авторизация платформы
│ │ ├── demo/ # Демо
│ │ ├── tz/ # Эта страница
│ │ └── page.tsx # Лендинг MyStores
│ └── api/ # Custom API routes
├── components/
│ ├── tenant/ # TenantContext, ThemeStyles, CustomerAuth
│ ├── tenant-admin/ # Sidebar, Header для админки тенанта
│ └── ui/ # shadcn/ui компоненты
├── payload/
│ ├── collections/ # Tenants, Users, Sites, Media
│ ├── collections/modules/ # Products, Categories, Orders, Reviews, etc.
│ ├── hooks/ # createNotification
│ └── payload.config.ts # Основной конфиг Payload
├── themes/ # Предустановленные темы
├── views/ # View компоненты
└── modules/ # Переиспользуемые модули
13Команды для работы
# Деплой на продакшен
cd /var/www/marketplace && npm run build && pm2 restart siteforge
# Проверить статус
pm2 status siteforge
# Логи
pm2 logs siteforge --lines 50 --nostream
# Установить новый плагин Payload
cd /var/www/marketplace && npm install @payloadcms/plugin-seo
npm run build && pm2 restart siteforge
# Тест API
curl -s http://localhost:3010/api/tenants | head -200
14UX-аудит и анализ конкурентов
Подробный UX-аудит платформы, анализ мировых практик e-commerce и классифайдов, пожелания пользователей, приоритетные рекомендации (P0-P3), а также сравнительный анализ конкурентов в России и мире вынесены на отдельную страницу.