Content Versioning System Development

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815

Content Versioning System Development

A versioning system saves change history for each page or post. Editor can compare versions, restore previous, or revert to specific point. Protects against accidental content loss and allows auditing changes.

Implementation Options

Event Sourcing — store only diff between versions. Saves space, but version restoration requires replaying change chain.

Full snapshots — store complete snapshot of each version. Simpler to implement, takes more space, instant restoration.

Hybrid — full snapshot every N versions, diff between them.

For most CMS — full snapshots: text volume is small, simplicity is more important than storage savings.

Data Model

content_versions (
  id, content_type, content_id,
  version_number,
  content (jsonb),     -- full data snapshot
  title, excerpt,      -- for quick display in version list
  changed_fields (jsonb), -- ['title', 'body'] — what changed
  change_summary,      -- 'Fixed typo in title'
  is_autosave,         -- autosave vs manual save
  created_by, created_at
)

Autosave

// Autosave every 30 seconds on changes
const { isDirty, formData } = useFormState();

useEffect(() => {
    if (!isDirty) return;

    const timer = setTimeout(async () => {
        await saveDraft(formData);
        setLastSaved(new Date());
    }, 30000);

    return () => clearTimeout(timer);
}, [formData, isDirty]);

Creating Version on Save

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;

        // Version limit: keep max 50, delete old autosaves
        ContentVersion::where('content_type', get_class($content))
            ->where('content_id', $content->id)
            ->where('is_autosave', true)
            ->orderBy('created_at', 'desc')
            ->skip(10)  // keep last 10 autosaves
            ->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()
        ]);
    }
}

Diff Between Versions

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;
    }
}

Version Restoration

public function restore(Content $content, ContentVersion $version): void
{
    DB::transaction(function () use ($content, $version) {
        // Save current as version before restoration
        event(new ContentBeforeRestore($content));

        $content->update($version->content);
        $content->recordActivity('version_restored', [
            'restored_version' => $version->version_number
        ]);
    });
}

Version History Interface

Side panel or separate page:

  • Version list: number, date, author, changed fields, type (manual/autosave)
  • Click version → preview content
  • Compare two versions: select "base" and "compare", view diff
  • "Restore" button with confirmation

Development timeline: 2–4 weeks for complete system with diff, autosave, and version comparison interface.