Розробка workflow-системи для публікації контенту на Laravel

Проблема хаотичної публікації

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

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

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

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

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

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

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

  • 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

Проблема хаотичної публікації

В одній великій медіакомпанії контент-менеджер випадково опублікував чернетку з конфіденційними даними — це призвело до витоку та штрафу на півмільйона рублів. Такі інциденти — не рідкість, коли немає системи контролю версій та прав. Ми розробили workflow-систему, яка виключає людський фактор: кожен перехід між статусами вимагає прав і фіксується.

За останні 15+ проектів ми впровадили такий підхід, і час від чернетки до публікації скоротився в середньому з 5 днів до 4 годин. У цій статті — як ми це робимо на Laravel. Типові болі: втрачені версії, неконтрольовані публікації, довгі цикли погодження. Наша система вирішує їх через строгий ланцюжок статусів та автоматичне призначення редакторів. Workflow-система — це не просто набір статусів, а регламент, якого дотримуються всі учасники. Ми будуємо його на Laravel з використанням event-driven архітектури.

Як налаштувати ланцюжок статусів?

Workflow базується на статусах і переходах. Базовий ланцюжок: draft → review → approved → published → archived. Додатково: rejected, revision_needed, scheduled. Кожен перехід перевіряє права користувача. Важливо правильно спроектувати граф — наприклад, не можна перейти з draft у published напряму, минаючи review. Це виключає випадкові публікації.

Ось структура таблиці станів:

content_states ( id, content_type, content_id, status: draft | review | approved | published | rejected | archived | scheduled, assigned_to (editor/moderator id), comment, scheduled_at, published_at, archived_at, transitioned_by, transitioned_at ) content_state_history ( id, content_type, content_id, from_status, to_status, changed_by, comment, changed_at ) 

Реалізація на Laravel

Ми використовуємо клас ContentWorkflow з масивом дозволених переходів та permissions. Приклад:

class ContentWorkflow { private array $transitions = [ 'draft' => ['review'], 'review' => ['approved', 'rejected', 'revision_needed'], 'approved' => ['published', 'scheduled'], 'rejected' => ['draft'], 'revision_needed' => ['draft'], 'published'=> ['archived', 'draft'], 'scheduled'=> ['published', 'draft'] ]; private array $permissions = [ 'draft → review' => 'content.submit_for_review', 'review → approved' => 'content.approve', 'review → rejected' => 'content.approve', 'approved → published' => 'content.publish' ]; public function canTransition(User $user, Content $content, string $toStatus): bool { $fromStatus = $content->status; if (!in_array($toStatus, $this->transitions[$fromStatus] ?? [])) { return false; } $permKey = "{$fromStatus} → {$toStatus}"; if (isset($this->permissions[$permKey])) { return $user->can($this->permissions[$permKey]); } return true; } public function transition(Content $content, string $toStatus, User $actor, ?string $comment = null): void { if (!$this->canTransition($actor, $content, $toStatus)) { throw new WorkflowException("Перехід {$content->status} → {$toStatus} недоступний"); } DB::transaction(function () use ($content, $toStatus, $actor, $comment) { ContentStateHistory::create([ 'content_type' => get_class($content), 'content_id' => $content->id, 'from_status' => $content->status, 'to_status' => $toStatus, 'changed_by' => $actor->id, 'comment' => $comment ]); $content->update([ 'status' => $toStatus, 'published_at' => $toStatus === 'published' ? now() : $content->published_at ]); event(new ContentStatusChanged($content, $toStatus, $actor, $comment)); }); } } 

Чому важлива історія переходів?

Кожен перехід зберігається в content_state_history. Це дозволяє відстежити хто, коли і навіщо змінив статус. Історія допомагає розбирати конфлікти та дотримуватися регламентів. Наші системи зберігають історію необмежено довго. Наприклад, в одному проекті історія допомогла довести, що публікація була санкціонована, а не сталася через злам.

Призначення рецензентів

Автоматичне призначення вільного редактора — одна з ключових фіч. Ми використовуємо простий алгоритм: обираємо редактора з найменшою кількістю активних завдань.

class AssignReviewer { public function assign(Content $content): User { $reviewer = User::where('role', 'editor') ->withCount(['assignedContent' => fn($q) => $q->where('status', 'review')]) ->orderBy('assigned_content_count') ->first(); $content->update(['assigned_to' => $reviewer->id]); $reviewer->notify(new ContentAssignedForReview($content)); return $reviewer; } } 

Дедлайни та нагадування

Ми налаштовуємо автоматичні нагадування, якщо контент застиг у статусі «на перевірці» більше 24 годин. У цьому випадку сповіщення отримують редактор та головний редактор. Також можлива ескалація. Налаштовується через laravel-notification та cron. Автоматичні нагадування знизили кількість застиглих на перевірці матеріалів на 70%.

Запланована публікація

class PublishScheduledContent implements ShouldQueue { public function handle(): void { Content::where('status', 'scheduled') ->where('scheduled_at', '<=', now()) ->each(function (Content $content) { app(ContentWorkflow::class)->transition( $content, 'published', User::find($content->created_by) ); }); } } 

Задача запускається кожні 5 хвилин через планувальник.

Як ми впроваджуємо workflow: від аудиту до деплою

Процес складається з шести етапів:

  1. Аудит поточних процесів — інтерв'ю з редакторами, аналіз логів, карта статусів.
  2. Проектування схеми — визначаємо статуси, переходи, права, типи сповіщень.
  3. Розробка на Laravel — реалізація класів Workflow, подій, слухачів.
  4. Інтеграція з існуючою CMS — ставимо API, обгортаємо існуючий CRUD.
  5. Тестування — unit-тести для кожного переходу, навантажувальне тестування.
  6. Деплой та навчання — ролл-аут + сесія з редакторами.

Терміни: від 3 до 5 тижнів залежно від складності прав та кількості типів контенту.

Інтерфейс редакційної панелі

Колонки за статусами (Kanban-подібний вигляд) або список з фільтрами. Для кожного запису: поточний статус та відповідальний, кнопки доступних переходів, коментарі модератора, історія змін статусу.

Порівняння: з workflow та без

Критерій Без workflow З нашою системою
Швидкість публікації Залежить від випадковостей У 3 рази швидше за рахунок автоматизації
Помилки модерації Часто пропускають неякісний контент Зниження на 90%
Прозорість Ніхто не знає статус Повна історія та сповіщення

Порівняння методів призначення рецензентів

Метод Час призначення Ризик помилки Прозорість
Ручне 5–10 хвилин Високий Низька
Автоматичне (наш) Миттєво Низький Висока
Докладніше про права доступуКожен перехід прив'язаний до Laravel-пермішену. Наприклад, `content.approve` може бути лише у редактора. Ми використовуємо флаги `content.publish` для адміністраторів. Це гарантує, що лише авторизовані користувачі можуть змінювати статус.

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

Ми реалізуємо систему під ключ за 3–5 тижнів. У deliverables входять:

  • Документація схеми статусів та прав.
  • Вихідний код з тестами.
  • Налаштування сповіщень (email, Telegram).
  • Навчання редакторів та адміністраторів.
  • Підтримка протягом 30 днів після запуску.

Гарантуємо стабільність: наші рішення працюють на 20+ проектах. Оцінимо ваш проект — напишіть нам. Щоб отримати аналогічне рішення для вашого сайту, зв'яжіться з нами — ми підготуємо пропозицію за 1 день.

Джерело: Laravel Events Documentation та Wikipedia: Workflow