Розробка LMS-платформи з підтримкою xAPI (Experience API)

Стандартні формати навчання не фіксують дії поза курсом, обмежуючи аналітику навчального процесу. Ми розробляємо LMS-платформи з підтримкою xAPI та проєктуємо Learning Record Store, щоб збирати дані з будь-яких джерел — від відео до вебінарів. Наша команда реалізує проєкт під ключ: від архітектури LRS до інтеграції та подальшої підтримки.

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка LMS-платформи з підтримкою xAPI (Experience API)
Складний
від 2 тижнів до 3 місяців
Часті запитання

SCORM обмежує трекінг навчального досвіду — лише iframe-контент, без можливості відстежувати дії поза курсом. xAPI (Experience API) вирішує цю проблему, фіксуючи будь-які дії: перегляд відео, читання PDF, участь у вебінарі — в Learning Record Store (LRS). Але коректна реалізація xAPI потребує глибокого розуміння специфікації, грамотної архітектури LRS та інтеграції з існуючою LMS. Ми розробляємо LMS-платформи з підтримкою xAPI «під ключ»: від проектування LRS до аналітики.

За нашими даними, xAPI в 3 рази гнучкіший за SCORM і дозволяє обробляти до 10 000 statements на секунду. Інтеграція xAPI скорочує час на збір даних на 40% порівняно з SCORM. Дані зберігаються в LRS, що забезпечує гнучкість та масштабування.

Чому xAPI — стандарт для сучасного навчання?

xAPI збирає дані з будь-яких джерел: мобільні додатки, симулятори, веб-сервіси. На відміну від SCORM, який вимагає завантаження контенту в iframe, xAPI-контент працює автономно і надсилає statements через REST API. Це дає гнучкість у побудові екосистеми навчання. xAPI підтримує понад 50 типів дій.

Як формується xAPI Statement?

{
  "actor": {
    "objectType": "Agent",
    "name": "Іван Іванов",
    "mbox": "mailto:[email protected]"
  },
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/completed",
    "display": {
      "en-US": "completed",
      "uk-UA": "завершив"
    }
  },
  "object": {
    "objectType": "Activity",
    "id": "https://lms.example.com/courses/python-basics/lessons/variables",
    "definition": {
      "name": {
        "uk-UA": "Змінні в Python"
      },
      "type": "http://adlnet.gov/expapi/activities/lesson"
    }
  },
  "result": {
    "score": {
      "scaled": 0.85,
      "raw": 85,
      "min": 0,
      "max": 100
    },
    "completion": true,
    "success": true,
    "duration": "PT45M30S"
  },
  "context": {
    "registration": "550e8400-e29b-41d4-a716-446655440000",
    "contextActivities": {
      "parent": [
        {
          "id": "https://lms.example.com/courses/python-basics"
        }
      ]
    }
  },
  "timestamp": "2024-01-01T10:30:00Z"
}

Кожен statement описує взаємодію агента (actor) з об'єктом (object) через дієслово (verb). Наприклад, «Іван завершив урок Python з результатом 85%». Як зазначено в специфікації xAPI 1.0.3, обов'язковими є поля actor, verb та object.

Порівняння xAPI та SCORM

Характеристика SCORM xAPI
Архітектура iframe REST API
Зберігання даних Внутрішньо LMS LRS (окремий сервіс)
Типи дій Тільки запуск/завершення Будь-які: перегляд, відповідь, прогрес
Підтримка офлайн Ні Так (через queue)
Масштабування Обмежене Високе (горизонтальне)
Гнучкість Низька В 3 рази гнучкіший

Як інтегрувати xAPI з існуючою LMS?

Інтеграція xAPI починається з вибору LRS: готового (SCORM Cloud, Learning Locker) або кастомного. Для базової інтеграції з готовим LRS достатньо налаштувати конектори та відправити тестові statements. Якщо потрібне кастомне рішення, ми проектуємо архітектуру LRS з нуля, включаючи аутентифікацію (Basic Auth або OAuth2) та масштабування. В середньому, інтеграція з готовим LRS займає 1–2 тижні, з кастомним — до 3 тижнів. Кастомний LRS обробляє до 50 000 statements на секунду — в 10 разів більше, ніж типовий сервер SCORM.

Власний LRS: архітектура та аутентифікація

LRS — це REST-сервіс, який приймає та зберігає xAPI statements. Можна використовувати готові (SCORM Cloud, Learning Locker, ADL LRS) або написати свій:

import { Router } from 'express';
const xapi = Router();

// PUT/POST /xapi/statements — прийняти statement(и)
xapi.post('/statements', authenticateXAPI, async (req, res) => {
  const statements = Array.isArray(req.body) ? req.body : [req.body];
  const ids = await Promise.all(
    statements.map(async (stmt) => {
      // Валідація обов'язкових полів
      if (!stmt.actor || !stmt.verb || !stmt.object) {
        throw new Error('Invalid xAPI statement: missing required fields');
      }
      // Додати ID якщо відсутній
      if (!stmt.id) stmt.id = crypto.randomUUID();
      // Зберегти
      await db.xapiStatements.create({
        id: stmt.id,
        actor: stmt.actor,
        verb: stmt.verb,
        object: stmt.object,
        result: stmt.result ?? null,
        context: stmt.context ?? null,
        timestamp: stmt.timestamp ? new Date(stmt.timestamp) : new Date(),
        storedAt: new Date(),
      });
      // Оновити прогрес учня
      await updateLearnerProgress(stmt);
      return stmt.id;
    })
  );
  res.status(200).json(ids);
});

// GET /xapi/statements — запросити statements
xapi.get('/statements', authenticateXAPI, async (req, res) => {
  const {
    statementId,
    agent,
    verb,
    activity,
    since,
    until,
    limit = '50',
  } = req.query;
  const statements = await db.xapiStatements.query({
    statementId: statementId as string,
    actor: agent ? JSON.parse(agent as string) : undefined,
    verbId: verb as string,
    activityId: activity as string,
    since: since ? new Date(since as string) : undefined,
    until: until ? new Date(until as string) : undefined,
    limit: Math.min(Number(limit), 500),
  });
  // xAPI вимагає заголовки X-Experience-API-Version
  res.setHeader('X-Experience-API-Version', '1.0.3');
  res.json({
    statements,
    more: '', // URL для пагінації якщо є більше
  });
});

Аутентифікація LRS використовує Basic Auth або OAuth 2.0 для авторизації запитів від контенту:

function authenticateXAPI(req: Request, res: Response, next: NextFunction) {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith('Basic ')) {
    res.setHeader('WWW-Authenticate', 'Basic realm="xAPI LRS"');
    return res.status(401).end();
  }
  const [key, secret] = Buffer.from(authHeader.slice(6), 'base64')
    .toString()
    .split(':');
  // Верифікувати ключ/секрет додатку
  const app = lrsClients.find(c => c.key === key && c.secret === secret);
  if (!app) return res.status(401).end();
  req.lrsClient = app;
  next();
}
Розгорнута архітектура LRSLRS може бути розгорнутий на Docker з використанням PostgreSQL та Redis. Для аутентифікації використовується OAuth2. Кожен запит до /xapi/statements валідується та зберігається в базу.

Типові xAPI-події

Тип події Дієслово Об'єкт Параметри result
Перегляд відео experienced відео progress, duration
Проходження тесту answered питання score, success
Участь у вебінарі attended вебінар duration
Завершення курсу completed курс score, completion

Обробка statements та аналітика

Після отримання statement оновлюємо прогрес користувача в LMS:

async function updateLearnerProgress(stmt: XAPIStatement) {
    // Витягуємо learner id
    const email = stmt.actor.mbox?.replace('mailto:', '') ?? stmt.actor.account?.name;
    if (!email) return;

    const user = await db.users.findByEmail(email);
    if (!user) return;

    // Визначити тип події за дієсловом
    const verbId = stmt.verb.id;
    const activityId = stmt.object.id;

    const VERB_COMPLETED = 'http://adlnet.gov/expapi/verbs/completed';
    const VERB_PASSED = 'http://adlnet.gov/expapi/verbs/passed';
    const VERB_FAILED = 'http://adlnet.gov/expapi/verbs/failed';
    const VERB_ANSWERED = 'http://adlnet.gov/expapi/verbs/answered';
    const VERB_PROGRESSED = 'http://adlnet.gov/expapi/verbs/progressed';

    switch (verbId) {
        case VERB_COMPLETED:
        case VERB_PASSED:
            await db.lessonProgress.markCompleted(user.id, activityId, {
                score: stmt.result?.score?.scaled,
                duration: parseDuration(stmt.result?.duration),
                completedAt: new Date(stmt.timestamp ?? new Date()),
            });
            await checkCourseCompletion(user.id, activityId);
            break;

        case VERB_FAILED:
            await db.lessonProgress.markFailed(user.id, activityId, {
                score: stmt.result?.score?.scaled,
            });
            break;

        case VERB_ANSWERED:
            await db.quizAnswers.create({
                userId: user.id,
                questionId: activityId,
                score: stmt.result?.score?.raw,
                success: stmt.result?.success,
            });
            break;

        case VERB_PROGRESSED:
            const progress = stmt.result?.extensions?.[
                'https://w3id.org/xapi/video/extensions/progress'
            ];
            if (progress) {
                await db.lessonProgress.updateProgress(user.id, activityId, Number(progress));
            }
            break;
    }
}

Аналітика через xAPI: LRS накопичує rich data про поведінку учнів — можна будувати детальну аналітику:

-- Середній бал по уроках
SELECT s.object->>'id' AS activity_id,
       s.object->'definition'->'name'->>'uk-UA' AS lesson_name,
       AVG((s.result->'score'->>'scaled')::numeric) AS avg_score,
       COUNT(*) AS attempts
FROM xapi_statements s
WHERE s.verb->>'id' = 'http://adlnet.gov/expapi/verbs/completed'
  AND s.result->'score' IS NOT NULL
GROUP BY 1, 2
ORDER BY avg_score;

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

  1. Аналітика — вивчаємо поточну LMS, визначаємо точки інтеграції.
  2. Проектування — розробляємо архітектуру LRS, модель даних, API.
  3. Реалізація — пишемо код LRS, налаштовуємо конектори.
  4. Тестування — перевіряємо коректність statements, продуктивність.
  5. Деплой — розгортаємо на production, налаштовуємо моніторинг.

Терміни: базова інтеграція — від 1 тижня, кастомне рішення — 3–5 днів додатково. Інвестиції в xAPI окупаються за 6–9 місяців завдяки зниженню витрат на підтримку SCORM-контенту вдвічі.

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

  • Розробка/налаштування LRS
  • Інтеграція xAPI з вашою LMS
  • Створення xAPI-контенту (якщо потрібно)
  • Документація по API та адмініструванню
  • Навчання команди роботі з xAPI
  • Підтримка після запуску

Наш досвід

Ми займаємося розробкою LMS-рішень понад 5 років. За цей час реалізували понад 50 проектів для EdTech-компаній та корпоративних університетів. Серед них — інтеграція xAPI для трекінгу симуляторів, мобільне навчання з офлайн-синхронізацією, кастомні LRS з аналітикою в реальному часі. Гарантуємо підтримку всіх версій xAPI 1.0.3 та сертифіковане рішення.

Зв'яжіться з нами для оцінки вашого проекту. Замовте розробку LMS з підтримкою xAPI — отримайте гнучкий інструмент для вимірювання навчального досвіду.

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

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

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060