A course is an application, not a row in a database
Courses are not uploaded as files into a content system. Each one is built and deployed as its own small application on its own hostname, and elmo is the authority it consults. That is what lets a course carry interactive material, its own search index and its own video without any of it becoming the platform's problem.
Its own application, on its own hostname
A course is built and deployed the way a small web application is. It has its own hostname, its own build, its own release history. Nothing about one course can break another, and nothing about a course can break the platform — the blast radius of a bad publish is one course.
Gated at its own edge
The check sits in front of the course, not inside its pages, so it cannot be forgotten on page 40 of 300. An unauthenticated request is redirected to sign in; an authenticated one without access is refused outright. The course's search index is behind the same gate as the pages, because an index of a course is the course.
Searchable across the whole catalogue
Each course also publishes an index of its lessons, quizzes and videos to the platform, so "which of our courses covers this" is answerable across everything at once — in Turkish and English, each ranked with the right language rules rather than as undifferentiated text. Answer keys are never part of what is published.
Subject groups are what visibility is written in
Courses are filed into groups an administrator manages, and a visibility allow-list is written as individual courses, whole groups, or everything. Several add up. It limits what a person may see and request; it is deliberately not the access check, so getting it wrong hides a course rather than opening one.
A real table of contents, and a real content date
Each course publishes the pages it contains, in reading order, and the date its content actually last changed — taken from the course's own history rather than from the day its catalogue row was touched. That is the denominator every completion figure is measured against, and the second date is the one that answers "has this moved since I last looked".
Video does not travel inside the course
A course with hours of recordings would otherwise be a multi-gigabyte image that every node has to pull. Video is served from shared storage instead, behind the same session check as the pages — so a recording is not a public URL that happens to be hard to guess.
Two languages, one course
A course can be published twice under separate names when the two editions should have separate enrolments and separate completion — or once, serving both languages on the same URLs, when they are one course in two languages. The second shape means switching language never costs a learner their progress, because the address of a page does not change with it.
Whatever the material needs
Because a course is an application rather than an upload, it can carry the things training material actually needs: runnable code cells, graded question banks, diagrams that follow the reader's theme, captured device output. None of that has to become a feature request against the platform first.
Delivering courses this way has a real cost, and it is worth naming: a course is something you deploy, not something you upload in a browser. In exchange, a course can be anything that serves HTTP, and publishing one never means releasing the platform.