Корпоративні портали: CRM, ERP, LMS, Intranet, HR
Корпоративний портал — це не сайт. Це внутрішня система із сотнями бізнес-правил, матрицями рольового доступу, інтеграціями з системами автентифікації та користувачами, які працюють у ній вісім годин на день. Якщо додаток повільний або незручний — продуктивність падає вимірюваного.
Де починаються справжні складності
Публічний сайт можна запустити без детального проектування — ітеративно виправляти по фідбеку. З корпоративним порталом так не працює: вартість виправлення архітектурних рішень після запуску на 200 користувачів несумірна.
Три зони, де найчастіше приймаються погані рішення:
Модель прав доступу. «Менеджер бачить тільки своїх клієнтів, керівник відділу — весь відділ, директор — всю компанію, але фінансові дані — тільки фінансовий директор та вище». Це не три ролі — це матриця ролей, дозволів, організаційних одиниць та володіння записами. Якщо це реалізувати через if ($user->role === 'manager') у контролерах — через пів року код стане непідтримуваним.
Правильний підхід: Spatie Laravel Permission для базової ролевої моделі + Policy класи для object-level permission (can('view', $deal) перевіряє не тільки роль, але й володіння). Для складних ієрархічних структур — ABAC (Attribute-Based Access Control) замість RBAC.
Продуктивність на великих даних. CRM із 500 000 контактів, фільтрація за 10 полями, сортування за активністю — завдання, де наївна реалізація видає 15-секундні запити. Composite indexes, денормалізація агрегатів (last_activity_at на самому записі замість MAX по пов'язаній таблиці), Elasticsearch для full-text пошуку контактів.
Real-time оновлення. Кілька працівників працюють із одним документом або завданням. Без WebSocket — постійні setInterval с polling кожні 5 секунд, зайве навантаження, затримка оновлень. Laravel Broadcasting + Pusher/Soketi або власний WebSocket сервер на Node.js — для сповіщень та real-time змін.
CRM-системи
Типовий набір: контакти, компанії, угоди, активності, воронка продаж, звіти. Технічно це не складно. Складність — в деталях.
Pipeline з кастомними стадіями. Кожна компанія хоче свою воронку. Стадії повинні бути налаштовуваними без розгортання. Таблиця pipeline_stages з position, color, is_final, probability — та drag-and-drop для зміни порядку на UI (React DnD або dnd-kit).
Історія змін. Хто та коли змінив статус угоди, переніс відповідального, додав нотатку. Audit log через Observer або spatie/laravel-activitylog. На UI — timeline з фільтрацією за типом активності.
Інтеграція з поштою. IMAP/SMTP для підключення корпоративного ящика, автоматичне прив'язування вхідних листів до контактів за email-адресою. Це надійно працює тільки при правильній обробці bounce, spam, автовідповідей — потрібна фільтрація.
ERP-системи
ERP — це коли CRM, склад, виробництво, бухгалтерія та HR об'єднані в єдину систему. Повний ERP з нуля — рідке завдання (зазвичай інтегруються з існуючими системами), але модульні системи під конкретний бізнес — регулярні.
Ключовий принцип: фінансові операції повинні бути незмінюваними. Не UPDATE orders SET status = 'cancelled' — а створення нового запису order_cancellations з посиланням на вихідне замовлення. Це принцип immutable ledger, який спрощує аудит та reconciliation.
Інтеграція з 1С — майже завжди частина ERP-проекту. Двостороння синхронізація: з 1С в портал (довідники, остатки, ціни) та з порталу в 1С (замовлення, документи). RabbitMQ як шина подій між системами надійніша за прямого HTTP-взаємодії — у випадку недоступності 1С повідомлення чекають у черзі.
LMS: платформи навчання
Learning Management System — курси, модулі, уроки, тести, сертифікати, прогрес користувачів.
Відео-контент — найнавантажена частина LMS. Зберігати відео на власному серверу та видавати через Nginx — погана ідея: дорого, повільно, немає адаптивного бітрейту. Правильно: загрузка в S3/Cloudflare R2, транскодування через AWS Elemental MediaConvert або Mux, HLS-плейлист для адаптивного стрімінгу через Video.js або Plyr.
Прогрес переглядання — через періодичну відправку watch_position з фронтенду (кожні 10–30 секунд), зберігання в Redis із періодичною синхронізацією в PostgreSQL. Не зберігайте кожну секунду в БД — це вб'є продуктивність.
SCORM-сумісність — якщо потрібна інтеграція з корпоративними навчальними матеріалами. Окремий модуль, існують готові бібліотеки (scorm-again).
Intranet та HR-портали
Корпоративний інтранет: новини, документи, оргструктура, HR-процеси (відпустки, заявки, KPI).
Оргструктура в базі даних — це ієрархічна структура. Adjacency list (parent_id на кожному записі) простий у реалізації, повільний при рекурсивних запитах. Nested Sets або Closure Table швидші для читання ієрархії, складніші при змінах. У PostgreSQL — рекурсивні CTE (WITH RECURSIVE) з adjacency list — баланс між простотою та продуктивністю.
Узгодження документів та заявок — workflow engine. Прості лінійні узгодження (працівник → менеджер → HR → бухгалтер) можна зробити без спеціального движка. Нелінійні (паралельні гілки, умовні переходи, делегування) — варто розглянути готові рішення: Temporal.io для workflow orchestration або власний finite state machine на базі state-machine паттерну.
Технічний стек для портальів
| Шар | Інструменти |
|---|---|
| Backend | Laravel 10/11 + PostgreSQL |
| Frontend | React + TypeScript (Inertia.js або окремий SPA) |
| Real-time | Laravel Echo + Soketi / Pusher |
| Пошук | Meilisearch (швидкий старт) або Elasticsearch (обсяг) |
| Черги | Laravel Queue + Redis |
| Файли | S3-compatible (MinIO self-hosted або AWS S3) |
| Моніторинг | Sentry + Telescope (dev) |
Орієнтири за термінами
| Тип порталу | Термін |
|---|---|
| CRM (базовий) | 10–16 тижнів |
| LMS (курси + відео + тести) | 14–22 тижні |
| HR-портал (відпустки, KPI, оргструктура) | 12–20 тижнів |
| Корпоративний ERP (модульний) | 24–52 тижні |
Вартість залежить від кількості ролей, інтеграцій із зовнішніми системами та обсягу бізнес-правил. Завжди розраховується після детальної аналітики вимог.







