From e49d0d59ae0d261753f0cff78bed583f80e7b013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20H=C3=BCrten?= Date: Thu, 26 Jun 2025 12:18:06 +0200 Subject: [PATCH 1/3] Enhance JSON schema for MOOC providers: add Type MicroDegree, add CourseReference definition and refine relationships for courses and programs. --- moochub-schema.json | 566 ++++++++++++++++++++++++++------------------ 1 file changed, 331 insertions(+), 235 deletions(-) diff --git a/moochub-schema.json b/moochub-schema.json index 60a6c3f..fb1c6ff 100644 --- a/moochub-schema.json +++ b/moochub-schema.json @@ -4,6 +4,36 @@ "title": "JSON schema for MOOC providers integrated into moochub.org", "description": "This schema specifies the JSON format each MOOC provider must offer in order to be integrated into moochub.org", "type": "object", + "$defs": { + "CourseReference": { + "title": "CourseReference", + "type": "object", + "description": "Reference to a course or program.", + "properties": { + "url": { + "type": "string", + "description": "An IRI pointing at the course or program.", + "format": "iri" + }, + "type": { + "type": "string", + "description": "The type of the referenced object.", + "enum": [ + "Program", + "Course" + ] + }, + "title": { + "type": "string", + "description": "The title or name of the course program this course is part of." + } + }, + "required": [ + "url", + "type" + ] + } + }, "properties": { "links": { "title": "Links", @@ -64,9 +94,10 @@ }, "type": { "type": "string", - "description": "Type of the object.", + "description": "Type of the object. 'Course' for individual courses, 'Program' for microdegrees and course programs.", "enum": [ - "Course" + "Course", + "Program" ] }, "attributes": { @@ -2841,208 +2872,115 @@ }, "hasPart": { "type": "array", - "description": "A list of the learning items like videos, lectures, quizzes, ... in the course.", + "description": "For regular courses: learning items like videos, lectures, quizzes. For programs: the courses that make up the program (both mandatory and elective).", "uniqueItems": true, "items": { - "title": "LearningItem", - "type": "object", - "description": "This schema describes the attributes of a learning item.", - "properties": { - "type": { - "type": "string", - "description": "The type of the object.", - "enum": [ - "Video", - "Quiz", - "Test", - "Podcast", - "Exercise", - "Text", - "other" - ] - }, - "identifier": { - "type": "string", - "format": "iri", - "description": "An IRI pointing at the learning item.", - "example": "https://open.hpi.de/courses/confidentialcommunication2022/items/1uDqDl23eu0i2h6jrGR49p" - }, - "name": { - "type": [ - "string", - "null" - ], - "description": "The name of the learning item.", - "example": "2.9 Certificate Standards" - }, - "duration": { - "type": [ - "string", - "null" - ], - "pattern": "^P(?!$)(\\d+(?:\\.\\d+)?Y)?(\\d+(?:\\.\\d+)?M)?(\\d+(?:\\.\\d+)?W)?(\\d+(?:\\.\\d+)?D)?(T(?=\\d)(\\d+(?:\\.\\d+)?H)?(\\d+(?:\\.\\d+)?M)?(\\d+(?:\\.\\d+)?S)?)?$", - "description": "ISO 8601 encoded duration.", - "example": "PT19M21S" - }, - "competencyRequired": { - "type": "array", - "description": "A list of competencies that are required to successfully complete this item. This includes skills, certificated, (high) school degrees, other courses", - "items": { - "anyOf": [ - { - "type": "object", - "description": "This schema describes the attributes of a course id. It is used to point at a specific course.", - "properties": { - "name": { - "type": "array", - "description": "List of names of the course. This array allows localized strings. A name and a language have to be given in the respective element.", - "items": { - "type": "object", - "properties": { - "inLanguage": { - "type": "string", - "description": "The language the name is given in. Has to be a shortcode according to BCP 47.", - "example": "en" - }, - "name": { - "type": "string", - "description": "The name of the course in the given language by the \"inLanguage\" attribute.", - "example": "HPI Academy: Leading Digital Transformation and Innovation - Fall 2020" + "oneOf": [ + { + "title": "LearningItem", + "type": "object", + "description": "This schema describes the attributes of a learning item.", + "properties": { + "type": { + "type": "string", + "description": "The type of the object.", + "enum": [ + "Video", + "Quiz", + "Test", + "Podcast", + "Exercise", + "Text", + "other" + ] + }, + "identifier": { + "type": "string", + "format": "iri", + "description": "An IRI pointing at the learning item.", + "example": "https://open.hpi.de/courses/confidentialcommunication2022/items/1uDqDl23eu0i2h6jrGR49p" + }, + "name": { + "type": [ + "string", + "null" + ], + "description": "The name of the learning item.", + "example": "2.9 Certificate Standards" + }, + "duration": { + "type": [ + "string", + "null" + ], + "pattern": "^P(?!$)(\\d+(?:\\.\\d+)?Y)?(\\d+(?:\\.\\d+)?M)?(\\d+(?:\\.\\d+)?W)?(\\d+(?:\\.\\d+)?D)?(T(?=\\d)(\\d+(?:\\.\\d+)?H)?(\\d+(?:\\.\\d+)?M)?(\\d+(?:\\.\\d+)?S)?)?$", + "description": "ISO 8601 encoded duration.", + "example": "PT19M21S" + }, + "competencyRequired": { + "type": "array", + "description": "A list of competencies that are required to successfully complete this item. This includes skills, certificated, (high) school degrees, other courses", + "items": { + "anyOf": [ + { + "type": "object", + "description": "This schema describes the attributes of a course id. It is used to point at a specific course.", + "properties": { + "name": { + "type": "array", + "description": "List of names of the course. This array allows localized strings. A name and a language have to be given in the respective element.", + "items": { + "type": "object", + "properties": { + "inLanguage": { + "type": "string", + "description": "The language the name is given in. Has to be a shortcode according to BCP 47.", + "example": "en" + }, + "name": { + "type": "string", + "description": "The name of the course in the given language by the \"inLanguage\" attribute.", + "example": "HPI Academy: Leading Digital Transformation and Innovation - Fall 2020" + } + }, + "required": [ + "inLanguage", + "name" + ] } }, - "required": [ - "inLanguage", - "name" - ] - } - }, - "educationalFramework": { - "type": "string", - "description": "This labels the object as a link to a course. It is needed to be compliant with a \"Skill\" ", - "enum": [ - "Course_ID" - ] - }, - "educationalFrameworkVersion": { - "type": "string", - "description": "This labels the object as a link to a course. It is needed to be compliant with a \"Skill\" ", - "example": "Fall 2020" - }, - "targetUrl": { - "type": "string", - "description": "An IRI pointing at a course.", - "example": "https://open.hpi.de/courses/digitrans2020-1" - } - }, - "required": [ - "name", - "educationalFramework", - "educationalFrameworkVersion" - ] - }, - { - "title": "Skill", - "type": "object", - "description": "This schema describes the attributes of a skill.", - "properties": { - "name": { - "type": "array", - "description": "List of names of the skill. This array allows localized strings. A name and a language have to be given in the respective element.", - "items": { - "type": "object", - "properties": { - "inLanguage": { - "type": "string", - "description": "The language the name is given in. Has to be a shortcode according to BCP 47.", - "example": "en" - }, - "name": { - "type": "string", - "description": "The name of the skill in the given language by the \"inLanguage\" attribute.", - "example": "PROTECTING PERSONAL DATA AND PRIVACY" - } + "educationalFramework": { + "type": "string", + "description": "This labels the object as a link to a course. It is needed to be compliant with a \"Skill\" ", + "enum": [ + "Course_ID" + ] }, - "required": [ - "inLanguage", - "name" - ] - } - }, - "alternateName": { - "type": [ - "array", - "null" - ], - "description": "A list of alternative names for the skill.", - "example": [ - "Understand Personal Privacy", - "Use Privacy Policy" - ], - "items": { - "type": "string" - } - }, - "shortCode": { - "type": "string", - "description": "The short code of the skill if the used framework provides one.", - "example": "4.2" - }, - "description": { - "type": [ - "string", - "null" - ], - "description": "A short description of the skill. Should be based on the framework used.", - "example": "To protect personal data and privacy in digital environments. To understand how to use and share personally identifiable information while being able to protect oneself and others from damages. To understand that digital services use a \"Privacy policy\" to inform how personal data is used." - }, - "educationalFramework": { - "type": "string", - "description": "The name of the educational framework that describes the skill.", - "enum": [ - "ESCO", - "DigComp", - "GRETA" + "educationalFrameworkVersion": { + "type": "string", + "description": "This labels the object as a link to a course. It is needed to be compliant with a \"Skill\" ", + "example": "Fall 2020" + }, + "targetUrl": { + "type": "string", + "description": "An IRI pointing at a course.", + "example": "https://open.hpi.de/courses/digitrans2020-1" + } + }, + "required": [ + "name", + "educationalFramework", + "educationalFrameworkVersion" ] }, - "educationalFrameworkVersion": { - "type": "string", - "description": "The version of the educational framework that describes the skill. Can also be the year the framework was released/published.", - "example": "2.2" - }, - "url": { - "type": [ - "string", - "null" - ], - "description": "An IRI pointing at the document which describes the educational framework.", - "format": "iri", - "example": "https://publications.jrc.ec.europa.eu/repository/bitstream/JRC128415/JRC128415_01.pdf" - }, - "targetUrl": { - "type": [ - "string", - "null" - ], - "format": "iri", - "description": "An IRI pointing at the framework node of the skill.", - "example": null - }, - "educationalLevel": { - "title": "EducationalLevel", + { + "title": "Skill", "type": "object", - "description": "This schema describes the attributes of an educational level.", + "description": "This schema describes the attributes of a skill.", "properties": { - "description": { - "type": [ - "string", - "null" - ], - "description": "A short description of the educational level. Should be based on the framework used.", - "example": "Independently, according to my own needs, and solving well-defined and non-routine problems, I can: - discuss ways to protect my personal data and privacy in digital environments, and - discuss ways to use and share personally identifiable information while protecting myself and others from damages. - indicate privacy policy statements of how personal data is used in digital services." - }, "name": { "type": "array", - "description": "List of names of the educational level. This array allows localized strings. A name and a language have to be given in the respective field.", + "description": "List of names of the skill. This array allows localized strings. A name and a language have to be given in the respective element.", "items": { "type": "object", "properties": { @@ -3053,8 +2991,8 @@ }, "name": { "type": "string", - "description": "The name of the educational level in the given language by the \"inLanguage\" attribute.", - "example": "INTERMEDIATE" + "description": "The name of the skill in the given language by the \"inLanguage\" attribute.", + "example": "PROTECTING PERSONAL DATA AND PRIVACY" } }, "required": [ @@ -3068,10 +3006,10 @@ "array", "null" ], - "description": "A list of alternative names for the educational level.", + "description": "A list of alternative names for the skill.", "example": [ - "independent use of concept", - "use of concept for oneself" + "Understand Personal Privacy", + "Use Privacy Policy" ], "items": { "type": "string" @@ -3079,12 +3017,20 @@ }, "shortCode": { "type": "string", - "example": "4", - "description": "A short code for the educational level if it is provided by the used framework." + "description": "The short code of the skill if the used framework provides one.", + "example": "4.2" + }, + "description": { + "type": [ + "string", + "null" + ], + "description": "A short description of the skill. Should be based on the framework used.", + "example": "To protect personal data and privacy in digital environments. To understand how to use and share personally identifiable information while being able to protect oneself and others from damages. To understand that digital services use a \"Privacy policy\" to inform how personal data is used." }, "educationalFramework": { "type": "string", - "description": "The name of the educational framework that describes the educational level.", + "description": "The name of the educational framework that describes the skill.", "enum": [ "ESCO", "DigComp", @@ -3101,8 +3047,8 @@ "string", "null" ], - "format": "iri", "description": "An IRI pointing at the document which describes the educational framework.", + "format": "iri", "example": "https://publications.jrc.ec.europa.eu/repository/bitstream/JRC128415/JRC128415_01.pdf" }, "targetUrl": { @@ -3111,73 +3057,223 @@ "null" ], "format": "iri", - "description": "An IRI pointing at the framework node of the educational level.", + "description": "An IRI pointing at the framework node of the skill.", "example": null }, - "type": { - "type": "string", - "description": "The type of the object.", - "enum": [ - "EducationalLevel" + "educationalLevel": { + "title": "EducationalLevel", + "type": "object", + "description": "This schema describes the attributes of an educational level.", + "properties": { + "description": { + "type": [ + "string", + "null" + ], + "description": "A short description of the educational level. Should be based on the framework used.", + "example": "Independently, according to my own needs, and solving well-defined and non-routine problems, I can: - discuss ways to protect my personal data and privacy in digital environments, and - discuss ways to use and share personally identifiable information while protecting myself and others from damages. - indicate privacy policy statements of how personal data is used in digital services." + }, + "name": { + "type": "array", + "description": "List of names of the educational level. This array allows localized strings. A name and a language have to be given in the respective field.", + "items": { + "type": "object", + "properties": { + "inLanguage": { + "type": "string", + "description": "The language the name is given in. Has to be a shortcode according to BCP 47.", + "example": "en" + }, + "name": { + "type": "string", + "description": "The name of the educational level in the given language by the \"inLanguage\" attribute.", + "example": "INTERMEDIATE" + } + }, + "required": [ + "inLanguage", + "name" + ] + } + }, + "alternateName": { + "type": [ + "array", + "null" + ], + "description": "A list of alternative names for the educational level.", + "example": [ + "independent use of concept", + "use of concept for oneself" + ], + "items": { + "type": "string" + } + }, + "shortCode": { + "type": "string", + "example": "4", + "description": "A short code for the educational level if it is provided by the used framework." + }, + "educationalFramework": { + "type": "string", + "description": "The name of the educational framework that describes the educational level.", + "enum": [ + "ESCO", + "DigComp", + "GRETA" + ] + }, + "educationalFrameworkVersion": { + "type": "string", + "description": "The version of the educational framework that describes the skill. Can also be the year the framework was released/published.", + "example": "2.2" + }, + "url": { + "type": [ + "string", + "null" + ], + "format": "iri", + "description": "An IRI pointing at the document which describes the educational framework.", + "example": "https://publications.jrc.ec.europa.eu/repository/bitstream/JRC128415/JRC128415_01.pdf" + }, + "targetUrl": { + "type": [ + "string", + "null" + ], + "format": "iri", + "description": "An IRI pointing at the framework node of the educational level.", + "example": null + }, + "type": { + "type": "string", + "description": "The type of the object.", + "enum": [ + "EducationalLevel" + ] + } + }, + "required": [ + "name", + "educationalFramework", + "educationalFrameworkVersion", + "type" ] } }, "required": [ "name", "educationalFramework", - "educationalFrameworkVersion", - "type" + "educationalFrameworkVersion" ] } - }, - "required": [ - "name", - "educationalFramework", - "educationalFrameworkVersion" ] } - ] - } + } + }, + "required": [ + "type", + "identifier" + ] + }, + { + "allOf": [ + { + "$ref": "#/$defs/CourseReference" + } + ], + "properties": { + "url": true, + "type": true, + "requirementLevel": { + "type": "string", + "description": "The level of requirement for this course in the context of the parent course. Can be 'mandatory' or 'elective'.", + "enum": [ + "mandatory", + "elective" + ], + "example": "mandatory" + } + }, + "required": [ + "url", + "type", + "requirementLevel" + ] } - }, - "required": [ - "type", - "identifier" ] } }, "isPartOf": { "type": "array", - "description": "A list of programs (preferable EducationalOccupationalPrograms) this course is part of. The given metadata shall at least contain a link to the program.", + "description": "A list of courses or programs (preferable EducationalOccupationalPrograms) this course is part of. The given metadata shall at least contain a link to the program.", "uniqueItems": true, "example": null, "items": { - "title": "Program", + "$ref": "#/$defs/CourseReference" + } + }, + "relatedTo": { + "type": [ + "array", + "null" + ], + "description": "A list of relationships this course has with other courses. Uses a simple 2-dimensional approach: sequence type (prequel/sequel/complementary) combined with requirement level (mandatory/recommended). This enables defining course pathways and learning sequences.", + "uniqueItems": true, + "items": { + "title": "CourseRelationship", "type": "object", - "description": "This schema describes the attributes of a course program to an extend that it links to a EducationalOccupationalProgram.", + "description": "Defines a relationship between this course and another course, including the type of relationship and reference to the related course.", "properties": { - "url": { - "type": "string", - "description": "An IRI pointing at the course program or a homepage of the program, ... etc.", - "format": "iri" + "course": { + "$ref": "#/$defs/CourseReference" }, "type": { "type": "string", - "description": "The type of the object.", + "description": "The type of relationship between this course and the related course. Uses a 2-dimensional approach combining sequence (foundation/continuation/complementary/elective) with requirement level (mandatory/recommended).", "enum": [ - "Program" + "foundation_mandatory", + "foundation_recommended", + "continuation_mandatory", + "continuation_recommended", + "complementary_mandatory", + "complementary_recommended" ] - }, - "title": { - "type": "string", - "description": "The title or name of the course program this course is part of." } }, "required": [ - "identifier", + "course", "type" ] } + }, + "programRequirements": { + "type": [ + "object", + "null" + ], + "description": "For program-type courses (microdegrees), defines program-specific requirements. If null, this is a simple course.", + "properties": { + "description": { + "type": "string", + "description": "General description of the program requirements and structure.", + "example": "This program requires completion of 5 mandatory courses (24 ECTS) and 2 elective courses from the specialization tracks (6 ECTS minimum)." + }, + "minimumElectiveCredits": { + "type": [ + "number", + "null" + ], + "description": "Minimum ECTS from elective courses required for the program. If null or 0, no electives are required.", + "minimum": 0, + "example": 6 + } + }, + "required": [ + "description" + ] } } } From 01a4b8fe227028186138bf35b7ffe671f567c7a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20H=C3=BCrten?= Date: Thu, 26 Jun 2025 15:13:57 +0200 Subject: [PATCH 2/3] Simplify enum values for course relationship type --- moochub-schema.json | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/moochub-schema.json b/moochub-schema.json index fb1c6ff..bfc4694 100644 --- a/moochub-schema.json +++ b/moochub-schema.json @@ -3232,14 +3232,11 @@ }, "type": { "type": "string", - "description": "The type of relationship between this course and the related course. Uses a 2-dimensional approach combining sequence (foundation/continuation/complementary/elective) with requirement level (mandatory/recommended).", + "description": "The type of relationship between this course and the related course. Defines the nature of the relationship, such as whether it is a prerequisite, a follow-up, or complementary.", "enum": [ - "foundation_mandatory", - "foundation_recommended", - "continuation_mandatory", - "continuation_recommended", - "complementary_mandatory", - "complementary_recommended" + "foundation", + "continuation", + "complementary" ] } }, From 48b0c9ba06b5f17ad361569d7504e8e9bfa3ab2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20H=C3=BCrten?= Date: Thu, 2 Oct 2025 16:57:54 +0200 Subject: [PATCH 3/3] Rename Course reference property name to title so its compatible to the old schema isPartOf --- moochub-schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moochub-schema.json b/moochub-schema.json index 7d65b5b..5492937 100644 --- a/moochub-schema.json +++ b/moochub-schema.json @@ -575,7 +575,7 @@ "type": "object", "description": "This schema describes the attributes of a course id. It is used to point at a specific course.", "properties": { - "name": { + "title": { "type": "string", "description": "The name of the course.", "example": "HPI Academy: Leading Digital Transformation and Innovation - Fall 2020" @@ -595,7 +595,7 @@ } }, "required": [ - "name", + "title", "url", "type" ]