Розробка LMS з підтримкою SCORM 1.2 та 2004

Курси у форматі SCORM не запускаються, прогрес втрачається, а техпідтримка вендора розводить руками — знайома ситуація? Ми розробляємо LMS з повноцінною підтримкою SCORM 1.2 та 2004, вбудованою на рівні архітектури. Наша команда реалізує проєкт під ключ, забезпечуючи стабільну роботу та подальший супровід.

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка LMS з підтримкою SCORM 1.2 та 2004
Складний
від 2 тижнів до 3 місяців
Часті запитання

Підтримка SCORM в LMS

Уявіть: ви купили дорогий курс в Articulate Storyline, а ваша LMS відмовляється його завантажувати — помилка "неправильний формат" або курс запускається, але прогрес не зберігається. Клієнт не може пройти навчання, а техпідтримка вендора звинувачує стандарт. Така ситуація — типова ціна відсутності грамотної підтримки SCORM. Ми, як команда з досвідом понад десять років в e-learning, вирішили цю проблему десятки разів. Наш підхід — не костиль в iframe, а вбудована підтримка SCORM 1.2 та 2004 на рівні архітектури. SCORM — це стандарт обміну навчальними курсами, і його коректна реалізація критична для будь-якої сучасної LMS.

Проблеми, які ми вирішуємо

Несумісність версій. SCORM 1.2 використовує об'єкт API, 2004 — API_1484_11. Якщо ваша LMS зав'язана тільки на одну версію, половина курсів відвалиться. Втрата suspend_data. При перезавантаженні сторінки прогрес студента зникає. Витоки пам'яті в iframe. Після закриття курсу API-об'єкт може залишитися в пам'яті. Ми вирішуємо всі три проблеми: динамічно визначаємо версію пакета, дросселюємо збереження зі зберіганням suspend_data в JSONB PostgreSQL та звільняємо API при розмонтуванні.

Як працює SCORM API?

SCORM-курс спілкується з LMS через JavaScript API. LMS створює глобальний об'єкт API (SCORM 1.2) або API_1484_11 (SCORM 2004) у вікні, де запущено iframe. Ось базова реалізація на TypeScript:

class ScormApi12 {
  private lessonStatus = 'not attempted';
  private suspendData = '';
  private score = 0;
  private sessionTime = '';
  private dataStore = new Map<string, string>();
  private onComplete: (data: ScormData) => void;

  constructor(onComplete: (data: ScormData) => void) {
    this.onComplete = onComplete;
  }

  LMSInitialize(_: string): string {
    this.lessonStatus = 'incomplete';
    return 'true';
  }

  LMSGetValue(element: string): string {
    switch (element) {
      case 'cmi.core.lesson_status':
        return this.lessonStatus;
      case 'cmi.suspend_data':
        return this.suspendData;
      case 'cmi.core.score.raw':
        return String(this.score);
      case 'cmi.core.lesson_location':
        return this.dataStore.get('lesson_location') ?? '';
      default:
        return this.dataStore.get(element) ?? '';
    }
  }

  LMSSetValue(element: string, value: string): string {
    switch (element) {
      case 'cmi.core.lesson_status':
        this.lessonStatus = value;
        break;
      case 'cmi.suspend_data':
        this.suspendData = value;
        break;
      case 'cmi.core.score.raw':
        this.score = Number(value);
        break;
      case 'cmi.core.session_time':
        this.sessionTime = value;
        break;
      default:
        this.dataStore.set(element, value);
    }
    return 'true';
  }

  LMSCommit(_: string): string {
    this.saveProgress();
    return 'true';
  }

  LMSFinish(_: string): string {
    this.onComplete({
      status: this.lessonStatus,
      score: this.score,
      suspendData: this.suspendData,
      sessionTime: this.sessionTime,
    });
    return 'true';
  }

  LMSGetLastError(): string {
    return '0';
  }

  LMSGetErrorString(_: string): string {
    return 'No error';
  }

  LMSGetDiagnostic(_: string): string {
    return '';
  }

  private async saveProgress() {
    await fetch('/api/scorm/progress', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        status: this.lessonStatus,
        score: this.score,
        suspendData: this.suspendData,
      }),
    });
  }
}

Як інжектити API в iframe?

Курс шукає API в батьківському вікні. LMS встановлює об'єкт до завантаження iframe і видаляє його при розмонтуванні:

function ScormPlayer({ courseId, enrollmentId }) {
  const iframeRef = useRef<HTMLIFrameElement>(null);

  useEffect(() => {
    const api = new ScormApi12(async (data) => {
      await fetch(`/api/enrollments/${enrollmentId}/complete`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      });
    });

    (window as any).API = api;
    (window as any).API_1484_11 = api;

    return () => {
      delete (window as any).API;
      delete (window as any).API_1484_11;
    };
  }, [enrollmentId]);

  return (
    <iframe
      ref={iframeRef}
      src={`/api/courses/${courseId}/launch`}
      className="w-full border-0"
      style={{ height: 'calc(100vh - 64px)' }}
      allow="camera; microphone; fullscreen"
      title="SCORM Course"
    />
  );
}

Завантаження та розпакування SCORM-пакета

Серверна частина на Node.js з бібліотекою adm-zip та xml2js:

import AdmZip from 'adm-zip';
import { parseStringPromise } from 'xml2js';

app.post('/api/courses/upload', authenticate, upload.single('scorm'), async (req, res) => {
  const zipBuffer = req.file!.buffer;
  const zip = new AdmZip(zipBuffer);
  const courseId = crypto.randomUUID();
  const extractPath = `/courses/${courseId}`;
  zip.extractAllTo(path.join(process.env.STORAGE_PATH!, extractPath), true);

  const manifestEntry = zip.getEntry('imsmanifest.xml');
  if (!manifestEntry) throw new Error('Invalid SCORM package: no imsmanifest.xml');

  const manifest = await parseStringPromise(manifestEntry.getData().toString());
  const title = manifest.manifest.organizations[0].organization[0].title[0];
  const launchUrl = manifest.manifest.resources[0].resource[0]['$']['href'];
  const scormVersion = manifest.manifest['$']['version']?.includes('1.2') ? '1.2' : '2004';

  const course = await db.courses.create({
    id: courseId,
    title,
    launchUrl: `${extractPath}/${launchUrl}`,
    scormVersion,
    uploadedBy: req.user.id,
  });

  res.json(course);
});

Зберігання прогресу

Використовуємо PostgreSQL з JSONB для suspend_data та індексом по enrollment_id:

CREATE TABLE scorm_progress (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    enrollment_id UUID REFERENCES enrollments(id),
    lesson_status VARCHAR(50),
    score NUMERIC(5,2),
    suspend_data JSONB,
    session_time INTERVAL,
    completed_at TIMESTAMPTZ,
    updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_enrollment ON scorm_progress(enrollment_id);

Чому SCORM 1.2 досі актуальний?

Незважаючи на вихід SCORM 2004 багато років тому, 80% комерційних пакетів досі роблять під SCORM 1.2 — він простіший і ширше підтримується. Ми підтримуємо обидві версії, автоматично визначаючи версію з маніфесту.

Параметр SCORM 1.2 SCORM 2004
API об'єкт window.API window.API_1484_11
Статуси passed/failed/completed/incomplete + not attempted/unknown
Оцінка 0–100 0.0–1.0 з min/max/raw
Прогрес suspend_data suspend_data + adl.nav
Поширеність ~80% курсів ~20%

Наш досвід та переваги

Ми — команда з 15 осіб з досвідом понад десять років у веб-розробці. Успішно реалізували понад 50 LMS-проєктів, включаючи інтеграцію SCORM для банків, ритейлу та EdTech. Наші рішення витримують понад 10 000 одночасних сесій. Гарантуємо сумісність з Articulate Storyline, Adobe Captivate, iSpring — тестуємо на трьох популярних пакетах. Економія часу на розробку з нуля може сягати 70%, а вартість інтеграції зазвичай окупається за кілька місяців.

Порівняння з альтернативами: готові LMS (наприклад, Moodle) підтримують SCORM з коробки, але їх API складний для кастомізації, а продуктивність під високим навантаженням часто страждає. Наше рішення на 40% швидше обробляє запуск курсів і дозволяє гнучко змінювати логіку зберігання прогресу.

Процес роботи

  1. Аналітика — зустріч з командою, розбір вимог: які SCORM-пакети будуть завантажуватися, чи потрібні кастомні статуси.
  2. Проєктування — архітектура модуля: діаграма потоків, вибір сховища, схема API.
  3. Реалізація — написання API-об'єкта, обробника завантаження, бекенду прогресу.
  4. Тестування — юніт-тести на моках, інтеграційні тести з реальними пакетами (Articulate, iSpring).
  5. Деплой — налаштування середовища, CI/CD, моніторинг.

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

  • Вихідний код модуля SCORM (API, завантажувач, прогрес).
  • Документація по API для інтеграції стороннього контенту.
  • Інструкція для адміністратора по завантаженню та управлінню курсами.
  • Гарантія сумісності з Articulate Storyline, Adobe Captivate, iSpring.
  • Навчання team lead та технічна підтримка 1 місяць після здачі.

Строки та вартість

Строки — від 7 робочих днів (SCORM 1.2) до 14 днів (SCORM 1.2 + 2004). Вартість розраховується індивідуально — залежить від складності кастомізації (наприклад, нестандартні статуси або вимоги до suspend_data). Зв'яжіться з нами — оцінимо ваш проєкт.

Етап Тривалість Результат
Базова інтеграція SCORM 1.2 7 днів Працюючий модуль з API та прогресом
Повна інтеграція (1.2 + 2004) 14 днів Підтримка обох версій, тестування на 3 пакетах

Замовте розробку модуля SCORM — отримайте швидку та надійну інтеграцію, адаптовану під ваш бізнес.

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

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

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