Creating Courses

course.yml Reference

The top-level course.yml file defines course metadata and references child content by path. The CLI recognizes the fields below; unknown YAML keys are ignored by its YAML decoder.

Full Example

slug: "kubernetes-fundamentals"
title: "Kubernetes Fundamentals"
description: "Learn the core concepts of Kubernetes container orchestration"
category: "DevOps"
difficulty: "intermediate"        # beginner | intermediate | advanced
estimatedTime: 180                # Optional seed; computed from loaded content when available

instructors:
  - "Jane Doe"
instructorEmails:
  - "[email protected]"
owner: "pov-demo"

teaser: "Master Kubernetes fundamentals through hands-on exercises"
icon: "kubernetes"
tags:
  - "kubernetes"
  - "containers"
  - "devops"

prerequisites:
  - "Basic understanding of containers and Docker"
  - "Command line familiarity"

sections:
  - id: "introduction"
    title: "Introduction to Kubernetes"
    description: "Understanding the fundamentals"
    order: 1
    contentItems:
      - path: "sections/01-introduction/01-what-is-kubernetes"
        order: 1
      - path: "sections/01-introduction/02-kubernetes-quiz-1"
        order: 2

  - id: "core-concepts"
    title: "Core Kubernetes Concepts"
    order: 2
    contentItems:
      - path: "sections/02-core-concepts/01-pods-and-containers"
        order: 1

accessTier: "free"
freePreview: false
comingSoon: false
isBeta: false

This example contains only fields that the current pov push-course request preserves. It intentionally omits CLI-bundle-only metadata.

Required Fields

FieldTypeDescription
slugstringRequired non-empty identifier. The CLI does not enforce uniqueness or a URL-safe format.
titlestringDisplay name shown to learners.
categorystringCourse category. The validator requires a non-empty value.
difficultystringbeginner, intermediate, or advanced (lowercase, exact).
sectionsarrayAt least one section is required; each must have a title and at least one loadable content item.

CLI Bundle Fields and Current Push

The CLI sends the bundle as JSON, but the current course API stores only its matching request fields. “Persisted” below means the current pov push-course path retains it.

FieldTypeDescription
description, teaser, icon, subcategory, owner, ownerEmailstringAccepted without a validator requirement and persisted by the current push API.
tags, prerequisites, instructors, instructorEmailsstring[]Accepted without a validator requirement and persisted by the current push API.
accessTier, freePreview, comingSoon, isBetamixedAccepted without a validator requirement and persisted by the current push API.
estimatedTimenumberContent-derived time replaces the initial value when positive; the resulting value is persisted by the current push API.
imagestringAccepted into the CLI bundle as JSON image, but the current API accepts imageUrl instead. The current push path discards image.
learningObjectives, skillsGained, structuredPrerequisites, tier, ribbonmixedAccepted into the CLI bundle, but the current course API has no matching create-request field, so the current push path discards them.

Computed and Ignored Fields

FieldTypeDescription
totalLessons, totalQuizzes, totalLabscomputedCreated from loaded child content. The current course API does not store these bundle counters.
totalContentunsupportedA runtime model field, but the modular course loader does not read or populate it.
published, featured, createdAt, updatedAt, versionignoredThe modular loader accepts these keys but does not copy them into the course bundle; do not rely on them for publishing or versioning.

Sections Structure

Each entry in sections has:

FieldDescription
idAccepted identifier; no uniqueness or format rule is enforced here.
titleRequired non-empty display name.
description, isOptionalOptional section metadata.
orderAccepted integer passed through to the section; no sequencing rule is enforced.
contentItems[].pathA path to a directory containing lesson.yml, quiz.yml, or lab.yml; loading fails if none exists.
contentItems[].orderAccepted integer passed to the loaded item; no sequencing rule is enforced.

Do Not Use These Loader Keys

FieldStatusDescription
published, featuredignoredAccepted by the modular YAML struct, then discarded when the course bundle is created.
createdAt, updatedAt, versionignoredAccepted by the modular YAML struct, then discarded when the course bundle is created.