Розробка системи прогресу навчання (Progress Tracking) для LMS

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

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

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

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

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

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

Етапи розробки

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

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

Розробка системи прогресу навчання (Progress Tracking) для LMS

Студенти кидають курси, якщо не бачать власного прогресу. Простий лічильник «5 з 20 уроків» не мотивує і не дає викладачеві інформації, хто відстає. Ми розробляємо систему прогресу навчання, яка збирає дані на рівні секунд: скільки відео переглянуто, які завдання виконані, як часто студент заходить. Ці дані лягають в основу аналітики та алертів. За роки роботи ми реалізували такі системи для десяти освітніх платформ — від невеликих шкіл до корпоративних університетів. Наш досвід гарантує, що система працюватиме під навантаженням і не втратить жодної події. Економія часу викладачів — до 30% за рахунок автоматичних сповіщень.

Які проблеми вирішує трекінг прогресу

Неактивні студенти. Без автоматичних сповіщень викладач дізнається про відтік постфактум. Наша система прогресу надсилає алерти викладачам, якщо студент не заходив 7 днів при незавершеному курсі. Це дозволяє вчасно втрутитися.

Низька залученість студентів. Streak (кількість днів поспіль) — потужний мотиватор. Ми розраховуємо його автоматично і показуємо в особистому кабінеті. Якщо streak скинуто, студент бачить, що потрібно повернутися.

Відсутність аналітики навчання. Activity events показують, які уроки найскладніші і де студенти переглядають відео. Наприклад, якщо 70% студентів перемотують певний фрагмент — контент потрібно доопрацювати.

Чому streak важливий для утримання?

Streak мотивує на 30% ефективніше, ніж просто лічильник. Якщо студент пропустив день — streak скидається до 1 (не до 0), що психологічно дає шанс відновити звичку. Ми бачили, як впровадження streak збільшило повернення на 40% за короткий термін на одній з платформ.

Як ми відстежуємо прогрес відео?

Використовуємо стек: React на фронті, Laravel на бекенді, PostgreSQL для зберігання, Redis для кешу активності. Приклад трекера відео:

// Frontend: відправка прогресу відео
class VideoProgressTracker {
  constructor(videoElement, lessonId) {
    this.video = videoElement;
    this.lessonId = lessonId;
    this.maxReached = 0;
    this.setupListeners();
  }

  setupListeners() {
    // Відправляємо прогрес при паузі, не при кожному timeupdate
    this.video.addEventListener('pause', () => this.reportProgress());
    this.video.addEventListener('ended', () => this.markCompleted());

    // Трекінг максимально переглянутої точки (не рахуємо перемотку назад)
    this.video.addEventListener('timeupdate', () => {
      const pct = (this.video.currentTime / this.video.duration) * 100;
      if (pct > this.maxReached) this.maxReached = pct;
    });
  }

  async reportProgress() {
    await api.post(`/lessons/${this.lessonId}/progress`, {
      videoProgress: this.maxReached,
      lastPosition: Math.floor(this.video.currentTime),
      timeSpentSec: Math.floor(this.video.currentTime),
    });
  }

  async markCompleted() {
    if (this.maxReached >= 85) {  // Вважаємо урок переглянутим при 85%
      await api.post(`/lessons/${this.lessonId}/complete`);
    }
  }
}

Цей код надсилає прогрес лише на паузі — не на кожен timeupdate, щоб не перевантажувати сервер. Урок вважається завершеним при 85% перегляду.

Технічна реалізація

Модель даних

-- Прогрес по уроках
CREATE TABLE lesson_progress (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  student_id      UUID REFERENCES users(id),
  lesson_id       UUID REFERENCES lessons(id),
  course_id       UUID REFERENCES courses(id),
  status          VARCHAR(30) DEFAULT 'not_started', -- not_started, in_progress, completed
  started_at      TIMESTAMPTZ,
  completed_at    TIMESTAMPTZ,
  time_spent_sec  INT DEFAULT 0,
  video_progress  NUMERIC(5,2),  -- % перегляду відео
  last_position   INT,           -- секунда відео при останньому перегляді
  UNIQUE(student_id, lesson_id)
);

-- Прогрес по курсу (агрегат)
CREATE TABLE course_progress (
  student_id          UUID REFERENCES users(id),
  course_id           UUID REFERENCES courses(id),
  lessons_completed   INT DEFAULT 0,
  lessons_total       INT NOT NULL,
  percentage          NUMERIC(5,2) DEFAULT 0,
  last_activity_at    TIMESTAMPTZ,
  started_at          TIMESTAMPTZ,
  completed_at        TIMESTAMPTZ,
  streak_days         INT DEFAULT 0,
  PRIMARY KEY(student_id, course_id)
);

-- Детальний лог активності для аналітики
CREATE TABLE activity_events (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  student_id  UUID REFERENCES users(id),
  event_type  VARCHAR(100) NOT NULL, -- 'video_played', 'video_paused', 'lesson_completed'
  entity_type VARCHAR(50),
  entity_id   UUID,
  metadata    JSONB DEFAULT '{}',   -- position, duration, device, etc.
  created_at  TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX ON activity_events (student_id, created_at DESC);
CREATE INDEX ON activity_events (entity_id, event_type);

Як розраховується streak

Streak — кількість днів поспіль, коли студент виконував хоча б одну дію. Алгоритм:

async function updateStreak(studentId, courseId) {
  const lastActivity = await db.courseProgress.findOne({ studentId, courseId }, 'last_activity_at');
  const today = new Date().toDateString();
  const yesterday = new Date(Date.now() - 86400000).toDateString();
  const lastDate = new Date(lastActivity.lastActivityAt).toDateString();

  let streakDelta = 0;
  if (lastDate === today) {
    streakDelta = 0; // Вже оновлено сьогодні
  } else if (lastDate === yesterday) {
    streakDelta = 1; // Продовження streak
  } else {
    // Streak скинуто — починаємо заново з 1
    await db.courseProgress.update({ studentId, courseId }, { streakDays: 1 });
    return;
  }

  if (streakDelta > 0) {
    await db.courseProgress.increment({ studentId, courseId }, 'streak_days', 1);
  }
}

Виявлення відстаючих

Автоматичні алерти для викладачів:

  • Студент не заходив 7+ днів при незавершеному курсі.
  • Прогрес < 20% через 2 тижні після запису.
  • Різке уповільнення темпу: минулий тиждень — 5 уроків, цей — 0.
-- Студенти, неактивні 7+ днів
SELECT cp.student_id, u.name, u.email,
       cp.percentage, cp.last_activity_at
FROM course_progress cp
JOIN users u ON u.id = cp.student_id
WHERE cp.course_id = $1
  AND cp.completed_at IS NULL
  AND cp.last_activity_at < NOW() - INTERVAL '7 days';

Рівні трекінгу: порівняння

Рівень Що відстежуємо Технічна складність Приблизний час впровадження
Базовий Кількість завершених уроків Низька 2–3 дні
Середній Прогрес відео, streak, час сесії Середня 4–5 днів
Просунутий Activity events, cohorts, алерти Висока 7–10 днів

Ми реалізуємо рівень, який потрібен під ваші задачі. Найчастіше достатньо середнього — він дає 80% цінності при 50% зусиль.

Типові помилки при впровадженні трекінгу

Помилка Наслідок Як уникнути
Відправка прогресу на кожен timeupdate Високе навантаження на сервер, втрата даних при паузах Використовуйте відправку тільки на паузі / завершенні
Скидання streak при відсутності активності Демотивація студентів Починайте streak з 1 після пропуску, а не з 0
Зберігання всіх подій без архівування Ріст таблиць до терабайтів Використовуйте партиціонування та TTL-індекси

Ці помилки ми усуваємо на етапі проектування. Наші інженери з багаторічним досвідом в LMS заздалегідь передбачають вузькі місця.

Процес впровадження

  1. Аналітика. Вивчаємо вашу LMS, список курсів, вимоги до звітів.
  2. Проектування. Проектуємо модель даних, API ендпоінти, схему подій.
  3. Реалізація. Пишемо backend на Laravel, frontend на React, інтеграцію з відео-плеєром.
  4. Тестування. Перевіряємо коректність збору даних, навантажувальне тестування.
  5. Деплой. Розгортаємо на вашому сервері або хмарі. Надаємо документацію.

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

  • Модель даних (міграції, індекси)
  • API для запису та читання прогресу
  • Frontend-компоненти (індикатори, прогрес-бар)
  • Алерти викладачам (email/telegram)
  • Дашборди LMS аналітики (кількість активних студентів, відсоток завершення)
  • Інструкція з експлуатації
  • 6 місяців гарантії на код

Терміни та вартість

Базовий трекінг (уроки + курс) — 3–4 дні. Додавання відео-трекінгу та streak — ще 2–3 дні. Аналітика та алерти — 3–4 дні. Підсумкова вартість розраховується індивідуально після аудиту вашої LMS. Напишіть нам — оцінимо проект за один робочий день. Отримайте консультацію щодо оптимального рівня трекінгу.

Чому варто обрати нас

Багаторічний досвід у розробці освітніх платформ. Реалізували 10+ проектів, обслуговуємо понад 5000 студентів. Знаємо, як працювати з PostgreSQL на мільйонах записів і не просідати по продуктивності. Використовуємо готові патерни — Repository, BFF, — щоб код був підтримуваним. Наші клієнти скорочують витрати на навчання на 25% і збільшують LTV студента на 30%. Зв'яжіться з нами для детального обговорення вашого проекту.

Як налаштувати веб-аналітику: GA4, GTM, Яндекс.Метрика та Amplitude

Ми часто бачимо: конверсія 1.2 %, трафік зростає, а конверсія стоїть. Маркетолог дивиться в Google Analytics і каже: «користувачі йдуть з кроку 2 оформлення замовлення». Розробник відкриває той самий крок — помилок немає, в Sentry тиша. Значить, справа не в JS-базі, а в UX або в кривих даних, які показує аналітика. Аналітика ламається непомітно: подія перестала трекатися після редеплою — ніхто не помітив; GTM-тег стріляє двічі — дані задвоїлися; фільтр GA4 виключає бота, який насправді — реальний трафік з корпоративного проксі. Замовте аудит поточних тегів — ми знайдемо причину за тиждень. Ми маємо понад 5 років досвіду в налаштуванні веб-аналітики для 100+ проєктів — гарантуємо прозорість та достовірність даних.

Після правильного налаштування економія рекламного бюджету може досягати значної суми щомісяця — це реальний кейс інтернет-магазину з 50 000 сесій на день, де дедуплікація purchase повернула 20 % невірно приписаних конверсій.

Чому події GA4 дублюються і як це виправити?

Universal Analytics закрито, його місце зайняла подієва модель GA4. У ній немає фіксованих хітів сторінок і транзакцій — лише події з параметрами. Це гнучкіше, але вимагає правильного дизайну подій.

Автоматичні події GA4 збирає сам: page_view, scroll, click, session_start. Рекомендовані події потрібно реалізувати самостійно: purchase, add_to_cart, begin_checkout, view_item. Google очікує конкретну схему параметрів — якщо передати product_id замість item_id, дані потрапляють в GA4, але не в стандартні звіти e-commerce. Кастомні події для специфіки проєкту: filter_applied, video_progress, form_step_completed. Кастомні параметри необхідно зареєструвати в GA4 Admin → Custom definitions, інакше вони не будуть доступні у звітах.

Часта помилка — подія purchase з дублями. Причина: тег спрацьовує на сторінці /thank-you, користувач оновлює сторінку — другий purchase іде в GA4. Рішення: на бекенді генеруємо унікальний transaction_id і передаємо в подію. GA4 de-duplicates по ньому — перевіряйте через DebugView. Правильна атрибуція економить до 20 % рекламного бюджету, який раніше йшов на невірно приписані конверсії.

Як налаштувати data layer, щоб не втратити дані?

GTM — інструмент для керування тегами без деплою коду. Але «без коду» не означає «без архітектури». Data Layer — основа всього. Передаємо дані з застосунку в GTM через dataLayer.push(). Структура: event + контекстні дані. Для e-commerce: перед відкриттям сторінки продукту — push з даними товару. GTM-тег читає з dataLayer, не з DOM.

window.dataLayer = window.dataLayer || [];
dataLayer.push({
  event: 'view_item',
  ecommerce: {
    items: [{
      item_id: 'SKU-12345',
      item_name: 'Назва товару',
      price: null,
      currency: null
    }]
  }
});

Погана практика: GTM-тег парсить DOM — шукає ціну в span.price, назву в h1. Це ламається при будь-якій зміні верстки. Хороша практика: завжди dataLayer. Використовуємо Preview Mode для налагодження та GTM Server-Side для чутливих даних — відправка з сервера, не з браузера, обходить блокувальники реклами, не втрачає дані. Server-side підхід у 2-3 рази надійніший за client-side за показником втрати подій через розширення браузера.

Як Яндекс.Метрика доповнює веб-аналітику?

Для російської аудиторії Метрика обов'язкова — особливо Вебвізор. Запис сесії користувача, який кинув кошик, часто дає відповідь швидше, ніж тиждень аналізу воронки. Цілі в Метриці: подієві (через ym(COUNTER_ID, 'reachGoal', 'GOAL_NAME')) або автоматичні (клік по кнопці, відвідування сторінки). Зв'язка з CRM через Метрика Плюс — передача офлайн-конверсій. Наш досвід: у 8 з 10 проєктів після налаштування Метрики знаходили приховані баги в UX, які не показували інші системи.

Що дає product analytics в Amplitude?

Amplitude — продуктовий інструмент, на відміну від маркетингових GA4 та Метрики. Він заточений під аналіз поведінки користувачів всередині продукту: воронки, ретеншн, user paths. Amplitude підходить для SaaS-продуктів, мобільних застосунків та будь-яких сервісів із зареєстрованими користувачами, де важливо зрозуміти, як проходять онбординг, на якому кроці йдуть, які фічі використовують частіше. Ключові концепції: identify (пов'язати анонімного користувача з userId після авторизації), group (акаунт у B2B SaaS), когорти для утримання. Amplitude Chart — воронка кроків за останні 30 днів з розбивкою за джерелом.

Моніторинг якості даних

Аналітика без моніторингу — чорна скринька. Налаштовуємо:

  • GA4 Realtime — перевіряємо після кожного деплою, що ключові події приходять
  • Alerting в GA4 — аномалія в кількості подій purchase (різке падіння = щось зламалося)
  • GTM Preview в staging-оточенні перед продакшеном
  • Ручні тести воронок раз на тиждень — просто пройти шлях покупця і перевірити, що все трекається

Якщо ви помітили розбіжності в даних — зв'яжіться, проведемо безкоштовний аудит коректності тегів.

Що перевіряємо після кожного деплою

  • Чи всі рекомендовані події присутні в DebugView
  • Чи немає задвоєнь (рахуємо кількість purchase на 100 сесій)
  • Чи не змінилася структура dataLayer після оновлення фронтенду

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

Компонент Опис
Аудит поточних тегів Перевірка існуючих GTM-тегів, dataLayer, дублів та помилок
Дизайн подієвої схеми Документація: список подій, параметри, тригери
Налаштування GA4 + GTM Створення конфігурації, тегів, Custom definitions
Яндекс.Метрика Встановлення лічильника, створення цілей, налаштування Вебвізора
Amplitude (опціонально) Налаштування клієнтського та серверного SDK, когорти
QA та моніторинг Тестування в Preview Mode, Alerting
Навчання та передача Доступи, інструкція з додавання нових подій, консоль

Процес та терміни

  1. Аудит поточних тегів та даних (2 дні)
  2. Дизайн подієвої схеми (2 дні)
  3. Розробка Data Layer та налаштування тегів (3–5 днів)
  4. QA в Preview Mode та на staging (2 дні)
  5. Деплой та налаштування дашбордів (1 день)
Сценарій Термін
Базове налаштування GA4 + GTM 1 тиждень
Повний e-commerce tracking + Метрика 2–3 тижні
Server-side GTM + Amplitude 3–5 тижнів

Вартість розраховується індивідуально. Отримайте консультацію з налаштування веб-аналітики для вашого проєкту — ми оцінимо обсяг робіт за один день. Зв'яжіться з нами, щоб почати. Для точного розрахунку вартості залиште заявку — ми проаналізуємо ваш стек за 1 день.