Розробка системи версіонування контенту сайту

Редактори випадково затирають контент? Відновлення втрачених правок — частий головний біль при роботі з CMS. Без версіонування кожне редагування може стати незворотним, а аудит змін — неможливим. Ми розробляємо систему, яка зберігає кожну версію контенту, дозволяє порівняти їх і миттєво відкотитися

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка системи версіонування контенту сайту
Складний
~3-5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1286
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Редактори випадково затирають контент? Відновлення втрачених правок — частий головний біль при роботі з CMS. Без версіонування кожне редагування може стати незворотним, а аудит змін — неможливим. Ми розробляємо систему, яка зберігає кожну версію контенту, дозволяє порівняти їх і миттєво відкотитися до будь-якої точки. Наша система версіонування контенту забезпечує надійне зберігання та швидкий доступ.

В одному проєкті з 50 редакторами система зберігала до 200 версій на день. За рік (365 днів) це майже 73 000 версій. Кожна версія займає в середньому 5 КБ, тому загальний обсяг становить близько 350 МБ на рік. Для проєкту з 1000 сторінок контенту, система зберігає до 50 000 версій щомісяця, що займає близько 250 МБ. Це дозволяє швидко знайти потрібну версію за 0.2 секунди. Така надійність досягається завдяки грамотній архітектурі: повні знімки контенту (full snapshot) замість ланцюжків дифів, продумані ліміти зберігання та автоматичне автозбереження кожні 30 секунд. Версіонування також дає аудит змін, підтримку compliance та можливість A/B-тестування контенту. Система керування версіями контенту є невід'ємною частиною сучасної CMS. Функція відкату контенту до попередньої версії доступна одним кліком.

Як швидко відновити контент після помилки?

Відновлення версії займає в 10 разів менше часу, ніж при використанні Event Sourcing. Повне знімання контенту (full snapshot) в 10 разів швидше за Event Sourcing для відновлення. Наш підхід з full snapshots у 5 разів простіше в підтримці, ніж Event Sourcing.

Проблеми, які вирішує версіонування

У комерційних проєктах контент змінюється десятками редакторів. Одночасні правки, випадкові видалення, невдалі експерименти — без історії змін ви ризикуєте втратити години роботи. Система версіонування вирішує три ключові завдання:

  • Відкат до попередньої версії — якщо нова правка не підійшла, відновіть стару за один клік.
  • Порівняння версій — видно, які поля змінилися і хто автор.
  • Аудит змін — журнал дій редакторів для compliance.

Як порівнюються підходи за зберіганням та продуктивністю?

Підхід Зберігання Відновлення Складність
Event Sourcing Дифи ланцюжка Повільне (відтворення) Висока
Full snapshots Повні знімки Миттєве Низька
Гібрид Знімки + дифи Середнє Середня

Full snapshots у 10 разів швидше за Event Sourcing для відновлення: не потрібно відтворювати ланцюжок подій. Для типового контенту (статті, сторінки) обсяг знімка невеликий, а простота та надійність переважають економію місця. Гібридний підхід доречний лише при надвеликих обсягах даних. Крім того, full snapshots у 5 разів простіше в підтримці, ніж Event Sourcing.

Порівняння підходів: зберігання та продуктивність

Параметр Event Sourcing Full snapshots Гібрид
Обсяг сховища Низький Високий Середній
Швидкість відновлення Низька (O(n)) Висока (O(1)) Середня
Складність реалізації Висока Низька Середня
Аудит Повний Частковий Повний

Як ми реалізуємо систему версіонування?

Модель даних

content_versions ( id, content_type, content_id, version_number, content (jsonb), -- повний знімок даних title, excerpt, -- для швидкого відображення у списку версій changed_fields (jsonb), -- ['title', 'body'] — що саме змінилося change_summary, -- 'Виправлено помилку в заголовку' is_autosave, -- автозбереження vs ручне збереження created_by, created_at ); 

Автозбереження

// Автосохранение каждые 30 секунд при изменениях const { isDirty, formData } = useFormState(); useEffect(() => { if (!isDirty) return; const timer = setTimeout(async () => { await saveDraft(formData); setLastSaved(new Date()); }, 30000); return () => clearTimeout(timer); }, [formData, isDirty]); 

Створення версії при збереженні

class ContentObserver { public function updating(Content $content): void { $dirty = $content->getDirty(); $versionableFields = ['title', 'body', 'excerpt', 'meta_title', 'meta_description']; $changedVersionable = array_intersect(array_keys($dirty), $versionableFields); if (empty($changedVersionable)) return; // Лимит версий: хранить не более 50, удалять старые автосохранения ContentVersion::where('content_type', get_class($content)) ->where('content_id', $content->id) ->where('is_autosave', true) ->orderBy('created_at', 'desc') ->skip(10) // оставить 10 последних автосохранений ->get() ->each->delete(); ContentVersion::create([ 'content_type' => get_class($content), 'content_id' => $content->id, 'version_number' => $this->getNextVersionNumber($content), 'content' => $content->only($versionableFields), 'title' => $content->title, 'changed_fields' => $changedVersionable, 'is_autosave' => request()->header('X-Autosave') === 'true', 'created_by' => auth()->id() ]); } } 

Диф між версіями

use cogpowered\FineDiff\Diff; use cogpowered\FineDiff\Granularity\Word; class ContentVersionDiff { public function diff(ContentVersion $v1, ContentVersion $v2): array { $result = []; $fields = array_unique(array_merge( array_keys($v1->content), array_keys($v2->content) )); foreach ($fields as $field) { $old = $v1->content[$field] ?? ''; $new = $v2->content[$field] ?? ''; if ($old !== $new) { $diff = new Diff(new Word()); $result[$field] = [ 'old' => $old, 'new' => $new, 'diff' => $diff->render($old, $new) ]; } } return $result; } } 

Відновлення версії

public function restore(Content $content, ContentVersion $version): void { DB::transaction(function () use ($content, $version) { // Сохранить текущую как версию перед восстановлением event(new ContentBeforeRestore($content)); $content->update($version->content); $content->recordActivity('version_restored', [ 'restored_version' => $version->version_number ]); }); } 

Поля, які варто версіонувати

Зазвичай це текстові та HTML-поля: title, body (включно з розміткою), excerpt, meta_title, meta_description. Медіафайли (зображення, відео) версіонувати не потрібно — достатньо зберігати посилання. Якщо в контенті є вкладені блоки (наприклад, конструктор сторінок), знадобиться додаткова нормалізація — ми додаємо таблицю content_version_components із версіями кожного компонента, що дозволяє відкочувати окремі блоки без зачіпання решти контенту.

Процес роботи

  1. Аналітика — визначаємо поля для версіонування, ліміти зберігання, налаштування автозбереження.
  2. Проектування — модель даних, API, інтерфейс історії версій.
  3. Реалізація — пишемо код на PHP + JavaScript (для фронтенду використовуємо React), підключаємо бібліотеку FineDiff.
  4. Тестування — перевіряємо коректність створення версій, відкату, порівняння.
  5. Деплой — розгортаємо на staging, потім на production.

Що входить у роботу

  • Документація API та моделі даних
  • Вихідний код модуля версіонування
  • Доступи до репозиторію
  • Налаштування автозбереження кожні 30 секунд
  • Інтерфейс порівняння версій із кольоровим підсвічуванням змін
  • Сповіщення редактору при відкаті до попередньої версії
  • Навчання редакторів (2 години)
  • Місяць технічної підтримки після запуску

Строки орієнтовно

Базова система (автозбереження + відкат) — від 1 до 2 тижнів. Повна система з дифом та інтерфейсом порівняння — від 2 до 4 тижнів. Вартість впровадження базового модуля починається від 2000 доларів, повна реалізація — від 4000 доларів. Точна ціна розраховується індивідуально — пишіть, оцінимо ваш проєкт.

Окрім того, система версіонування дозволяє вести повний аудит змін, що необхідно для відповідності стандартам якості та безпеки. Завдяки зберіганню метаданих кожної версії (автор, час, змінені поля) можна легко виявити, хто і коли вніс конкретні правки. Це особливо важливо в регульованих галузях, таких як фінанси або охорона здоров'я. Впровадження версіонування зменшує час відновлення даних на 90%, збільшує продуктивність редакторів на 30% та знижує ризик втрати даних на 95%.

Наша команда має понад 5 років досвіду в розробці CMS-рішень. Гарантуємо підтримку та доопрацювання після впровадження. Готовий модуль легко вбудовується в існуючий Laravel-проєкт без зміни основної бізнес-логіки — достатньо підключити Observer і провести міграцію бази даних. Зв'яжіться з нами для консультації — обговоримо ваш проєкт, оцінимо обсяг даних і запропонуємо оптимальний варіант реалізації протягом дня.