Готовый рецепт интерактивного обучающего курса в одном файле


Внутреннее обучение без бюджета, без серверов и без "запишитесь на вебинар". Один html-файл на ~118 Кб, который открывается двойным кликом, работает без интернета, помнит прогресс и выдает сертификат. Внутри: 7 модулей, 15 интерактивных схем, 21 вопрос, полезный чек-лист, игровые баллы, глоссарий и сертификат на выходе. Без библиотек, сборщиков и бэкенда. Открывается двойным кликом, прогресс хранится в браузере. Разберу архитектуру и дам промпт, чтобы собрать такой же под свою тему. Готовый рецепт, который сэкономит время, если вдруг возникла такая задача.
Откуда взялась задача
Иногда я работаю с руководителями проектов или напрямую с владельцами данных, которые отлично управляют сроками, бюджетом и людьми, но бывает теряются, когда речь заходит о данных. Но так как РП, чаще всего "на острие" всех процессов, посвятила курс именно им. Хотя, полезен он будет очень многим участникам процесса работы с данными, ведь целью курса является не проверка знаний, а попытка взглянуть со стороны на ожидания друг друга, дать всем участникам процесса общую карту и словарь, немного поиграть + открыть для себя что-то новое.
Сложности чаще всего возникают когда задача аналитику или инженеру звучит как "выгрузите заявления" и переделывается потом по несколько раз. Или "просто выгрузить" совершенно новые данные без описания оценивается в полчаса, а занимает три дня.
Ограничения, в результате которых появился именно один html-файл: ноль бюджета, работа во внутренней сети без интернета, прогресс не должен теряться при закрытии вкладки, интерактив, чтобы это не превратилось в очередную презентацию, которую все успешно забудут через час, максимально просто и под свои задачи. Корпоративные LMS требуют бюджета и интеграций, видеокурс это недели на производство.
Что внутри
7 модулей по ~ 90 минут каждый (с учетом практических заданий):
В каждом модуле: 3 коротких темы, 2-3 интерактивных схемы, практическое задание и по 3 вопроса с мгновенной проверкой. Глоссарий в 3-х разрезах: Excel / аналитика / инженерия данных, итоговый чек-лист из 10 пунктов, XP баллы и бейджи, конфетти при прохождении квиза и сертификат с распечаткой, и сохранением в PDF. Все примеры из нашей предметной области. Это осознанный выбор, так как абстрактные "заказы" и "клиенты" не цепляют.

Зачем геймификация
XP, бейджи и конфетти это не про контроль, так как нет никакой централизованной статистики "кто прошел" и на какие баллы, прогресс лежит в браузере конкретного человека, курс совершенно добровольный. Игровые элементы решают другие задачи:
Вовлечение. Курс проходят в свободное время, по кусочкам. Заполняющийся прогресс-бар, "пройдено 3 из 7" и серый бейдж, который хочется раскрасить, это дешевый способ вернуть человека к модулю через неделю.
Запоминание. Вопросы после модуля нужны не для оценки, а для закрепления: человек прочитал про медиану, тут же применил, сразу увидел, прав или нет и получил пояснение. Кнопка "Дальше" заблокирована, пока не все ответы верны. Никаких "двоек": неверные ответы можно пересдать отдельно, верные сохраняются.
Интерактивные схемы позволяют приобрести импровизированный практический опыт, что очень улучшает запоминание. Одно дело прочитать "среднее чувствительно к выбросам", а другое самому нажать кнопку и добавить заявление, застрявшее на 250 дней и увидеть, как среднее улетает 14 до 44 дней.

Устройство файла - три слоя
Весь курс - это три слоя в одном файле: данные, движок и интерактивные схемы. Такое разделение и позволяет переделать курс на другую тему, не трогая движок. Связка: HTML5 (каркас) + чистый CSS3 без препроцессоров + JavaScript (без импортов и библиотек) + SVG. Эмодзи, тоже обычные символы Unicode, без загрузки.

Слой 1. Данные
Курс как массив объектов. Каждый модуль это обычный JS-объект в массиве MODULES:
var MODULES=[
{num:1, short:'Карта мира данных',
title:'Карта мира данных: кто есть кто в команде', dur:'90 мин',
goal:'Понять, кто есть кто в команде данных, и научиться формулировать задачи…',
topics:[
{t:'Три роли в команде данных', d:'Команда данных это разные профессии…'},
{t:'Место РП в цепочке', d:'РП это заказчик и переводчик…'},
{t:'Формула постановки задачи', d:'Хорошая задача аналитику пишется по формуле…'}
],
practice:'Возьмите одну реальную задачу на ближайшую неделю…',
quiz:[
{q:'Кому в команде данных поставить задачу "настроить ежедневную автоматическую выгрузку…"?',
o:['Аналитику данных','Дата-инженеру','Владельцу данных','Руководителю проекта самому, в Excel'],
a:1,
e:'Автоматизация потоков данных это зона ответственности дата-инженера…'}
]},
// … ещё 6 модулей
];q - вопрос, o - варианты, a - индекс верного, e - пояснение, которое показывается после ответа. Глоссарий и чек-лист тоже просто массивы:
var GLOSSARY=[
['Связь таблиц','ВПР / XLOOKUP','merge, join','JOIN в SQL'],
['Пропуски','Пустые ячейки','NaN, missing values','NULL'],
// …
];
var CHECK=[
'Задача сформулирована через управленческий вопрос, а не "выгрузку"',
// …
];Рядом лежат палитра PAL, цвета модулей HUES/HUESBG и иконки MICO. Если нужно добавить модуль или поменять вопрос, то редактируйте объект в текстовом редакторе и перезагружаете страницу. Никакого GUI и LMS.
Слой 2. Движок
Рендер, квизы и прогресс. Движок это набор функций, которые проходят по массивам и строят страницы. Навигация это массив ключей страниц, который собирается из MODULES, так что количество модулей нигде не захардкожено.
var N_MOD=MODULES.length;
var ORDER=['home'].concat(MODULES.map(function(m,i){return 'm'+i;}))
.concat(['gloss','check','cert']);
function render(){
if(current==='home')renderHome();
else if(current==='gloss')renderGlossary();
else if(current==='check')renderChecklist();
else if(current==='cert')renderCert();
else renderModule(+current.slice(1));
window.scrollTo(0,0);
}Все состояние это один объект, который сериализуется в localStorage:
var KEY='pmDataCourseUrbanV1';
var state={done:{},quiz:{},check:{},practice:{},certName:''};
try{
var s=localStorage.getItem(KEY);
if(s){var loaded=JSON.parse(s);for(var k in loaded)state[k]=loaded[k];}
}catch(e){}
function save(){try{localStorage.setItem(KEY,JSON.stringify(state));}catch(e){}}Поэтому курс можно проходить по частям. Закрыли файл, открыли через неделю и вы там же где остановились. Данные крошечные, сложных запросов нет, так что IndexedDB избыточен.
Вентиль прохождения это три строки:
function allCorrect(mi){
var m=MODULES[mi];
return m.quiz.every(function(q,qi){var a=state.quiz[mi+'-'+qi];return a&&a.ok;});
}Ответ фиксируется сразу и навсегда до пересдачи. За верные ответы начисляется XP, за чек в практике тоже, за пройденный модуль - бейдж:
function getXP(){
var xp=0;
MODULES.forEach(function(m,i){
m.quiz.forEach(function(q,qi){var a=state.quiz[i+'-'+qi];if(a&&a.ok)xp+=10;});
if(state.done['m'+i])xp+=40;
if(state.practice[i])xp+=10;
});
return xp;
}Слой 3. Интерактивные схемы
Реестр SCHEMES.
Каждая интерактивная вставка это функция, которая строит себя внутри пустой карточки. Реестр привязывает схему к модулю и позиции темы:
var SCHEMES={
0:[ // модуль 1
{pos:0, build:function(el){ // после первой темы
el.innerHTML=vizHead('👥',PAL.blueBg,'Кто за что отвечает','Нажмите на роль…')+
'<div class="viz-body"><div class="role-grid" id="rg"></div>'+
'<div class="viz-panel" id="rp"></div></div>';
var R=[{n:'Аналитик данных',q:'"Что происходит и почему?"',z:'…',w:'…'}, /* … */];
// строим карточки, вешаем обработчики, первую кликаем сами
}},
{pos:2, build:function(el){ /* формула задачи */ }}
],
1:[ /* модуль 2: слои данных, четыре проверки качества */ ],
// …
};При рендере модуля движок вставляет пустые карточки в нужные места и вызывает build:
m.topics.forEach(function(t,ti){
h+='<div class="topic">…</div>';
(SCHEMES[i]||[]).filter(function(s){return s.pos===ti;})
.forEach(function(s){h+='<div class="viz-card" id="viz-'+i+'-'+ti+'"></div>';});
});
main.innerHTML=h;
(SCHEMES[i]||[]).forEach(function(s){
var el=document.getElementById('viz-'+i+'-'+s.pos); if(el)s.build(el);
});Всего 16 схем (15 интерактивных и одна статичная), все на чистом DOM и inline-SVG.


Как сделать такой же под свою тематику
Руками.
Возьмите index.html из репозитория (ссылка на GitHub ниже)
Откройте в редакторе и меняйте только массивы MODULES, GLOSSARY, CHECK (и при желании MICO - иконки модулей). Движок и схемы не трогайте.
Если нужен свой интерактив, то добавьте в SCHEMES по образцу существующих: {pos: номер_темы, build: function(el){...}}.
Поменяйте KEY в localStorage, чтобы прогресс вашего курса не пересекался с этим.
Проверьте в браузере и выложите на общий диск или в wiki.
Нейросетью. Если не хочется править руками, отдайте файл нейросети (Gemini, Claude, ChatGPT...) с таким промптом:
Приложенный html-файл это интерактивный обучающий курс в одном файле.
Архитектура: массив MODULES (модули с topics, practice, quiz), массивы GLOSSARY и CHECK, движок рендера и реестр интерактивных схем SCHEMES.
Прогресс хранится в localStorage.
Задача: сделай на его основе курс на тему "[ВАША ТЕМА]" для аудитории "[КТО УЧЕНИКИ]".
Требования:
сохрани движок, стили и формат данных без изменений;
перепиши MODULES: [N] модулей, в каждом 3 темы, практика и квиз из 3-4 вопросов с пояснением к ответам (поле e);
примеры бери из контекста: [ОПИСАНИЕ ВАШЕЙ КОМПАНИИ/ПРОЦЕССОВ];
обнови GLOSSARY и CHECK под новую тему;
интерактивные схемы SCHEMES адаптируй под новые примеры, сохранив механику (кликабельные карточки, конвейер, графики);
не используй внешние библиотеки и сетевые ресурсы, файл должен работать офлайн;
поменяй KEY в localStorage и заголовки курса;
верни полный исходный код файла, готовый к сохранению.
В результате, должен получиться файл, который можно сразу открыть проверить (и конечно допилить).
Варианты развертывания
Корпоративный сервер, общий диск/wiki, Android WebView (одно Activity. HTML в assets/, включить domStorageEnabled для localStorage). Можно просто прислать коллегам.
Кому еще пригодится такой формат
"Один файл = один курс" пригодится везде, где нужно поднять базовую грамотность без LMS, описать узкий процесс или сделать интерактивную инструкцию для людей, которые сами заинтересованы в знаниях и которых не нужно контролировать:
HR - онбординг, курсы по внешним процессам и ценностям;
Юристы и комплаенс - инструктажи с тестами и сертификатом;
Финансы и бухгалтерия - разбор новых регламентов, форм отчетности, типовых ошибок;
Продажи и аккаунт-менеджеры - продуктовое обучение;
Методология и процессные офисы - внедрение процессов (вместо PDF-регламента, который скучно читать);
Информационная безопасность - фишинг, пароли, инциденты;
Преподаватели - быстрые интерактивные материалы без платформ.
Шуточный квиз - прекрасный формат на различные праздники.
В итоге, один html-файл оказался на удивление живучим форматом внутреннего обучения: его не нужно "внедрять". Геймификация в нем не про контроль, а про лучшее запоминание. И архитектура позволяет пересобрать курс под любую небольшую тему за вечер, руками или нейросетью.
Однофайловый курс отлично решает задачу "быстро и бесплатно проверить формат". Но у него есть потолок: нет обратной связи по практике. Меня же этот формат вдохновил на чуть более полную программу по работе с данными, разместила ее на courserp.ru, можно сразу "в реальности" посмотреть, как выглядит проект.
Код на GitHub https://github.com/onesmilla/courserpru - файл index.html (скачиваете и открываете).
Конечно и по визуалу, и по техническому исполнению, есть что еще улучшить, даже в таком маленьком формате. Например: добавить темную тему, аналитику и т.д.
Пишите здесь или на почту info@courserp.ru, делитесь предложениями об улучшениях или об ошибках. Или расскажите в какой теме этот небольшой проект пригодился вам.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.