РАЗБОР ПРОЕКТАВЕБ-ПРИЛОЖЕНИЕ
Zyvra CMS — headless CMS для сайтов и приложений
Headless CMS, которую я сделал для своих проектов. Одна установка обслуживает несколько сайтов и приложений: в админке задаются типы контента, записи заполняются на нужных языках и публикуются, а сайты получают опубликованное через REST API по ключу. На Zyvra работает этот сайт: кейсы, страницы, тексты разделов и форма обратной связи ведутся в ней.
- Роль
- Автор, fullstack-разработчик
- Сроки
- 2026, октябрь

Задача
Сделать CMS, в которой структура контента описывается в админке, а не в коде, чтобы новый раздел сайта не требовал правок CMS, и довести её до продакшена: права, безопасность, тесты, Docker и резервные копии.
Что входит в решение
- Конструктор типов контента: коллекции и одиночные записи, поля-строки, тексты, числа, флажки, выбор, изображения, файлы, списки и группы полей. Языковые версии записи связаны общим slug.
- Черновики и публикация: опубликованная версия хранится отдельно от рабочей, и публичный API читает только её. Черновик можно открыть на сайте по подписанной ссылке предпросмотра.
- Страницы и статьи в визуальном редакторе на Tiptap, SEO-поля и общие настройки каждого сайта.
- Медиатека в S3-совместимом хранилище: тип файла определяется по содержимому, у картинок появляются AVIF- и WebP-копии нескольких размеров.
- Формы из конструктора: сайт рисует форму по её описанию в CMS, а CMS проверяет заявку по тому же описанию. Вложения хранятся приватно, о заявках приходят письма, в админке — фильтры, статусы и ответ через веб-почту.
- REST API для сайтов и приложений: ключи со scope у каждого приложения, CORS и лимиты запросов. Контракты описаны на Zod, по ним же генерируется OpenAPI.
- Роли администратора, редактора и наблюдателя, журнал аудита, интерфейс админки на русском и английском.
- Строгий CSP и защита от CSRF, Docker-образ без root, CLI для миграций и первого администратора, проверенное восстановление из бэкапа; unit-, интеграционные и e2e-тесты.




Собственный проект: архитектура, бэкенд, админка и деплой — мои. Скриншоты сняты с локальной копии на данных этого портфолио, заявки в них тестовые.