Кейсы 6 мин чтения

База знаний с собственной CMS: кейс разработки под ключ

Заказчику нужна была живая база знаний для своего онлайн-сервиса, которую сотрудники могли бы редактировать сами, без разработчика. Я собрал справочный портал с собственной CMS, ролями доступа и санитайзингом ввода поверх зафиксированного дизайна.

база знанийсправочный порталCMSдокументациябезопасность
TL;DR: Собрал онлайн-справку для SaaS-платформы с собственной CMS: публичная страница — это зафиксированный дизайн-shell, а тексты (около сотни ключей, несколько языков) хранятся отдельно и правятся через простой редактор без участия разработчика. Заложил роли доступа, санитайзинг ввода, автоматические бэкапы и SEO-разметку инструкции.

Ко мне пришёл заказчик с работающим онлайн-сервисом и типичной болью: руководство пользователя лежало в виде статичной страницы, которую при любом изменении текста нужно было чинить через разработчика. Правки копились неделями, документация отставала от продукта, а простую опечатку или новый абзац нельзя было поправить без правки кода. Задача — дать заказчику полноценную базу знаний, которую он сможет вести сам, безопасно, без риска сломать дизайн или открыть дыру в безопасности.

Коротко: для онлайн-сервиса нужна была документация, которую нетехнические сотрудники правят сами. Я построил справочный портал с собственной CMS: дизайн зафиксирован в коде, тексты хранятся в базе как набор ключей, редактор работает «как в Тильде». В результате инструкция обновляется в день изменения продукта, без разработчика и без риска сломать вёрстку.

Проблема: документация, которая живёт только у разработчика

У заказчика был готовый продукт и внешний реверс-прокси — своего сервера для новой страницы не было, только точка входа под доменом основного сервиса. Требовалось разместить справочный раздел так, чтобы он воспринимался как часть продукта, а не отдельный сайт на стороне.

Ключевая боль была не техническая, а организационная: тексты руководства меняются часто и мелкими порциями — переименовали кнопку, добавили шаг в инструкцию, поправили формулировку. При обычном подходе «страница = HTML-файл в репозитории» каждое такое изменение — это заявка разработчику, деплой, ожидание. Заказчику нужно было убрать разработчика из этой цепочки полностью.

Что былоЧто сделаноРезультат
Статичная страница-справка, любую правку делает разработчикСобственная CMS: тексты вынесены в базу как набор ключейСотрудники правят контент сами, без деплоя и ожидания
Правка текста рискует сломать вёрсткуЗафиксированный дизайн-shell отдельно от контентаДизайн не «съезжает» при любых изменениях текста
Ручная разметка HTML отпугивает нетехнических людейБогатый редактор с загрузкой картинок «как в Тильде»Порог входа снят, документация реально обновляется
Открытый ввод — риск XSS и порчи страницыСанитайзинг по белому списку тегов, запрет опасных файловВвод десятков сотрудников безопасен по умолчанию
Нет своего сервера, только внешний проксиКомпактный бэкенд, отдача через реверс-прокси заказчикаПортал под адресом продукта без новой инфраструктуры

Идея архитектуры: дизайн отдельно, тексты отдельно

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

  • Около сотни текстовых ключей покрывают всю страницу — от заголовка до последнего абзаца FAQ.
  • Каждый ключ существует в нескольких языковых версиях, поэтому мультиязычность не требует отдельного шаблона.
  • Правка в админке — это смена значения ключа, а не правка вёрстки: дизайн просто не может «съехать» от того, что кто-то отредактировал текст.

Такой разрыв между «формой» и «содержанием» — это и есть суть кейса. Заказчик получает свободу редактировать контент, а я как разработчик сохраняю контроль над тем, как страница выглядит и работает.

Редактор для нетехнических сотрудников

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

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

Роли и доступы

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

Здесь я заложил инвариант, который защищает заказчика от собственной ошибки: в системе всегда должен оставаться хотя бы один суперадмин. Последнего суперадмина нельзя удалить и нельзя понизить в правах — ни случайно, ни через API. Без этого правила один неаккуратный клик мог бы оставить всю базу знаний без единого человека, способного управлять доступами.

Безопасность: санитайзинг и защита от XSS

Раз тексты редактируют десятки нетехнических сотрудников через богатый редактор, это открытая дверь для XSS, если не закрыть её на сервере. Я сделал так, чтобы весь пользовательский ввод проходил через санитайзинг по белому списку тегов: разрешены только те HTML-элементы и атрибуты, которые нужны редактору (жирный, курсив, ссылка, изображение, абзацы), всё остальное — включая скрипты, обработчики событий и произвольную разметку — вырезается перед сохранением.

Это защищает сразу от двух вещей: от внедрения вредоносного кода через форму редактирования и от случайной поломки страницы, если кто-то вставит текст с «мусорной» разметкой из другого источника. Дизайн-shell при этом остаётся неприкосновенным — санитайзинг работает на уровне контента, а не вёрстки.

Витрина, SEO и мультиязык

Публичная часть сделана как полноценная витрина, а не «служебная» страница: светлая и тёмная тема, адаптация под мобильные экраны, аккуратные SVG-иконки вместо эмодзи, скриншоты интерфейса прямо в разделах инструкции. Добавлены Open Graph и Twitter-карточка, чтобы ссылка на инструкцию красиво разворачивалась при пересылке в мессенджерах и соцсетях.

Для самой инструкции подключил структурированную разметку JSON-LD типа HowTo — это помогает поисковикам и нейросетевым ассистентам показывать пошаговые шаги прямо в ответе. Отдельно сделан режим печати в PDF: сотрудник службы поддержки может выгрузить нужный раздел инструкции одним кликом и отправить клиенту файлом, а не ссылкой.

Эксплуатация и бэкапы

Технически проект — компактный бэкенд на FastAPI со встроенной базой данных, авторизация с безопасным хешированием паролей и самодостаточная веб-админка, которая не требует отдельной инфраструктуры. Отдаётся всё через реверс-прокси заказчика под адресом основного продукта — своего домена или сервера для этого не понадобилось.

Чтобы правки контента не превратились в риск, настроил автоматические консистентные бэкапы базы по расписанию с ротацией: если редактор случайно испортит несколько ключей или удалит не тот раздел, откат делается за минуты, без обращения ко мне.

Отдельно стоит объяснить, почему я вообще сделал ставку на разделение дизайн-shell и контента, а не взял готовую CMS «из коробки». Универсальные системы дают редактору слишком много власти над версткой: он может поменять шрифт, сломать сетку, вставить чужой блок — и страница перестанет выглядеть как часть продукта. Мне же нужно было ровно противоположное: дать заказчику полный контроль над словами и ноль контроля над оформлением. Поэтому дизайн живёт в коде и версионируется вместе с ним, а контент — в базе, и эти два слоя не пересекаются. Побочный, но важный эффект — предсказуемость: я всегда знаю, как будет выглядеть страница при любых текстах, потому что структура блоков фиксирована, а меняется только их наполнение. Это снимает целый класс задач на поддержку, когда «после редактирования что-то поехало».

Богатый редактор с загрузкой картинок кажется мелочью, но именно на нём чаще всего спотыкаются самодельные базы знаний. Если заставить нетехнического сотрудника вручную писать HTML или возиться с загрузкой файлов через отдельный файловый менеджер, документация просто перестанет обновляться — порог входа окажется выше, чем терпение человека. Поэтому редактор ведёт себя как привычный текстовый процессор: выделил слово, нажал «жирный», вставил ссылку из буфера, перетащил изображение в нужное место абзаца. Картинка при этом сразу проходит проверку типа файла на сервере и сохраняется в предсказуемое место, а в текст подставляется корректная ссылка — сотруднику не нужно знать, где физически лежит файл. Чем меньше человек думает о технике, тем чаще он реально пишет и правит инструкцию, а именно это и было целью проекта.

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

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

Как сделать базу знаний, которую сотрудники смогут редактировать сами без разработчика? Нужно отделить контент от дизайна: вёрстка фиксируется в коде, а тексты выносятся в базу как отдельные ключи и правятся через простой редактор в админке. Тогда изменение текста не требует деплоя и не задевает оформление.

Можно ли завести справочный портал без отдельного сервера? Да, именно так и было в этом проекте — портал отдавался через уже существующий реверс-прокси заказчика под адресом основного продукта, отдельного сервера или домена не потребовалось.

Не сломает ли редактор дизайн страницы при правке текста? Нет, потому что дизайн-shell зафиксирован отдельно от контента: редактор меняет только значения текстовых ключей, а вёрстку он не видит и не трогает, поэтому сетка и стиль остаются нетронутыми.

Как защитить пользовательский ввод в CMS от XSS? Весь ввод проходит серверный санитайзинг по белому списку тегов и атрибутов: разрешено только необходимое для редактора, а скрипты, обработчики событий и произвольная разметка вырезаются перед сохранением. Опасные типы файлов при загрузке тоже запрещены.

Что если сотрудник случайно удалит важный текст или раздел? Для этого настроены автоматические бэкапы базы с ротацией по расписанию — откат к прошлой версии занимает минуты и не требует участия разработчика.

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

Коротко о главном

Хорошая база знаний — это не просто страница с текстом, а инструмент, которым заказчик может пользоваться сам, без страха что-то сломать. Разделение дизайна и контента, продуманные роли доступа, санитайзинг ввода и автоматические бэкапы вместе дают именно это: живую документацию, которая обновляется в день изменения продукта, а не через две недели после заявки разработчику.

Если у вас похожая задача — справочный раздел, руководство пользователя или внутренняя база знаний, которую должны вести сами сотрудники, — соберём под ключ.

Услуги по теме

Что я делаю под ключ

  • Базы знаний и справочные порталы
  • CMS-редактор «как в Тильде» для нетехнических людей
  • Роли, доступы и раздача прав
  • Санитайзинг ввода и защита от XSS
  • SEO, Open Graph и мультиязык
Обсудить проект

Бесплатно: чек-лист «Готов ли ваш бизнес к 152-ФЗ»

12 пунктов, которые проверяют готовность за час: данные, согласия, уведомление в РКН, локализация, защита. Отметьте, что уже сделано, и увидите дыры, за которые сейчас штрафуют.

Готовы обсудить вашу задачу?

Бесплатная консультация — разберём, как внедрить это в вашем бизнесе под ключ. Без форм, пишите напрямую.

Готовые решения под ключ 449 готовых IT-решений для бизнеса Автоматизация, боты, AI, 152-ФЗ и платформы · бесплатная консультация Смотреть каталог