Skip to content

#76 As a teacher, so I can plan my curriculum, I want to organise exercises by modules and units #299

@mnmin

Description

@mnmin

User Story

  • A module is a "chapter" of a curriculum, e.g. "User Interfaces", "Programming Fundamentals"
  • A module should have a name, description and list of learning objectives
  • A unit is a "sub-chapter" of a module, e.g. "React.js", "Javascript", "Object Oriented Programming"
  • A unit should have a name, description and a list of learning objectives
  • A module should be composed of multiple units.
  • A unit should be composed of multiple lessons.

A lesson should have a day number (not a date, more like a number to represent where it is in the delivery sequence). This can't be an ID as lessons might be re-ordered

  • A lesson should have a list of learning objectives and a lesson plan

  • A lesson plan must be stored as Markdown so it can be formatted with things like headers, bullet points and code snippets

  • We should be able to connect exercises to a lesson

  • When creating a lesson, we should be able to create new exercises as part of the process

Teachers should be able to see a high-level view of all modules. Clicking a module should show its data and a list of its units. Clicking a unit should show its data and a list of its lessons. Clicking a lesson should show its data and a list of its exercises.

Tasks

SERVER SIDE

Check List

Overview

  1. Create Prisma Schema
  2. Create methods in the seed file
  3. Create modules for routes and controllers with methods
  4. Add event emitters to all methods

1 - Create Prisma Schema

Use Prisma Schema Documentation to create: Curriculum, Module, Unit, Lessons, Lesson Plan: https://www.prisma.io/docs/concepts/components/prisma-client/crud

Prisma Schema For Curriculum

2 - Create methods in the seed file

Overview
In Seed.js

  1. Create a curriculum
  2. Create two modules
  3. Create two units for each module
  4. Create two lessons for each unit
  5. Create one lesson plan for each lesson

1 - Create a curriculum

  const newCurriculum = await prisma.curriculum.create({
    data: {
      content: ''
    }
  })

2 - Create n seeds for each component

const iterator = 2
const iterator = 2

  const curriculums = []
  const createCurriculum = async () => {
    const newCurriculum = await prisma.curriculum.create({
      data: {
        name: 'Javascript',
        description:
          'Learn the JavaScript fundamentals you will need for front-end or back-end development'
      }
    })
    curriculums.push(newCurriculum)
  }

for (let i = 1; i <= iterator; i++) {
    await createCurriculum()
  }

console.log(
    'Curriculums, curriculums)

3 - Sample API response

curriculum, module, unit, lesson, exercise, lessonPlan {
  id: 1,
  name: 'Javascript',
  description: 'Learn the JavaScript fundamentals you will need for front-end or back-end development',
  createdAt: 2022-10-05T12:09:21.370Z,
  updatedAt: 2022-10-05T12:09:21.370Z
} {
  id: 1,
  name: 'Module 1',
  description: 'Description for Module-1',
  objectives: [
    'Objective 1 for module-1 Curriculum-1',
    'Objective 2 for module-1 Curriculum-1',
    'Objective 2 for module-1 Curriculum-1',
    'Objective 2 for module-1 Curriculum-1',
    'Objective 2 for module-1 Curriculum-1'
  ],
  createdAt: 2022-10-05T12:09:21.716Z,
  updatedAt: 2022-10-05T12:09:21.717Z
} {
  id: 1,
  name: 'Unit 1',
  description: 'Description for Unit-1',
  objectives: [
    'Objective 1 for Unit-1 Module-1 Curriculum-1',
    'Objective 1 for Unit-1 Module-1 Curriculum-1',
    'Objective 1 for Unit-1 Module-1 Curriculum-1',
    'Objective 1 for Unit-1 Module-1 Curriculum-1',
    'Objective 1 for Unit-1 Module-1 Curriculum-1'
  ],
  moduleId: 1,
  createdAt: 2022-10-05T12:09:22.284Z,
  updatedAt: 2022-10-05T12:09:22.285Z
} {
  id: 1,
  dayNumber: 1,
  name: 'Lesson 1',
  description: 'Lesson description for 1',
  objectives: [
    'Objective 1 for lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 2 for lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 3 for lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 4 for lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 5 for lesson-1 Unit-1 Module-1 Curriculum-1'
  ],
  unitId: 1,
  createdAt: 2022-10-05T12:09:22.632Z,
  updatedAt: 2022-10-05T12:09:22.632Z
} {
  id: 3,
  name: 'Exercise 1',
  gitHubUrl: 'https://github.com/boolean-uk/html-scientific-paper',
  readMeUrl: 'https://raw.githubusercontent.com/boolean-uk/html-scientific-paper/main/README.md',  
  objectives: [
    'Objective 1 for exercise 1 lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 2 for exercise 1 lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 3 for exercise 1 lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 4 for exercise 1 lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 5 for exercise 1 lesson-1 Unit-1 Module-1 Curriculum-1'
  ],
  createdAt: 2022-10-05T12:09:22.972Z,
  updatedAt: 2022-10-05T12:09:22.973Z
} {
  id: 1,
  name: 'Lesson Plan 1',
  description: 'Lesson plan description for 1',
  objectives: [
    'Objective 1 for  lesson plan-1 lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 2 for lesson plan-1 lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 3 for lesson plan-1 lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 4 for lesson plan-1 lesson-1 Unit-1 Module-1 Curriculum-1',
    'Objective 5 for lesson plan-1 lesson-1 Unit-1 Module-1 Curriculum-1'
  ],
  lessonId: 1,
  createdById: 1,
  createdForId: 4,
  createdAt: 2022-10-05T12:09:23.539Z,
  updatedAt: 2022-10-05T12:09:23.540Z
}

3 - Create modules for routes and controllers with methods

  1. Create a new route for curriculum in index.js
 app.use(/curriculum’, curriculumRouter)
  1. In routes folder create curriculum.js file and import this file in index.js. Add the following routers

Routers --> routers folder --> curriculum.js
CURRICULUM - routers

  1. post --> router.post(‘/’, validateAuthentication, createCurriculum)
  2. get --> router.get(‘/’, validateAuthentication, getAllCurriculums)
  3. put --> router.put(‘/:id’, validateAuthentication, updateCurriculumById)
  4. delete --> router.delete(‘/:id’, validateAuthentication, deleteCurriculumById)

MODULE - routers

  1. post --> router.post(‘/:id/module’, validateAuthentication, createModule)
  2. get --> router.get(‘/:id/module’, validateAuthentication, getAllModules)
  3. get --> router.get('/:id/module/:moduleId', validateAuthentication, getModuleById)
  4. put --> router.put(‘/:id/module/:moduleId’, validateAuthentication, updateModuleById)
  5. delete --> router.delete(‘/:id/module/:moduleId’, validateAuthentication, deleteModuleById)

UNIT - routers

  1. post --> router.post(‘/:id/module/:moduleId/unit’, validateAuthentication, createUnit)
  2. get --> router.get(‘/:id/module/:moduleId/unit, validateAuthentication, getAllUnits)
  3. get --> router.get(‘/:id/module/:moduleId/unit/:unitId’, validateAuthentication, getUnitById)
  4. put --> router.put(‘/:id/module/:moduleId/unit/:unitId’, validateAuthentication, updateUnitById)
  5. delete --> router.delete(‘/:id/module/:moduleId/unit/:unitId’, validateAuthentication, deleteUnitById)

LESSON - routers

  1. post --> router.post(‘/:id/module/:moduleId/unit/:unitId/lesson’, validateAuthentication, createLesson)
  2. get --> router.get(‘/:id/module/:moduleId/unit/:unitId/lesson', validateAuthentication, getAllLessons)
  3. get --> router.get(‘/:id/module/:moduleId/unit/:unitId/lesson/:lessonId’, validateAuthentication, getLessonById)
  4. put --> router.put(‘/:id/module/:moduleId/unit/:unitId/lesson/:lessonId’, validateAuthentication, updateLessonById)
  5. delete --> router.delete(‘/:id/module/:moduleId/unit/:unitId/lesson/:lessonId’, validateAuthentication, deleteLessonById)

LESSON PLAN - routers

  1. post -->
    router.post(‘/:id/module/:moduleId/unit/:unitId/lesson/:lessonId/lessonPlan’, validateAuthentication, createLessonPlan)
  2. get --> router.get(‘/:id/module/:moduleId/unit/:unitId/lesson/:lessonId/lessonPlan, validateAuthentication, getLessonPlan)
  3. put -->
    router.put(‘/:id/module/:moduleId/unit/:unitId/lesson/:lessonId/lessonPlan’, validateAuthentication, updateLessonPlan)
  4. delete -->
    router.delete(‘/:id/module/:moduleId/unit/:unitId/lesson/:lessonId/lessonPlan’, validateAuthentication, deleteLessonPlan)

CREATE METHODS FOR CONTROLLER
Create the following methods in controllers folder --> curriculum.js

Curriculum
createCurriculum()
getAllCurriculums()
updateCurriculumById()
deleteCurriculumById()

Module
createModule()
getAllModules()
getModuleById()
updateModuleById()
deleteModuleById()

Unit
createUnit()
getAllUnits()
getUnitById()
updateUnitById()
deleteUnitById()

Lesson
createLesson()
getAllLessons()
getLessonById()
updateLessonById()
deleteLessonById()

LessonPlan
createLessonPlan()
getLessonPlan()
updateLessonPlan()
deleteLessonPlan()

Sample API response structures:

CREATE
return sendDataResponse(res, 201, module)
return sendMessageResponse(res, 400, 'Must provide content')
GET ALL
```js
return sendDataResponse(res, 200, module)
GET BY ID
return sendDataResponse(res, 200, { module: foundModule })
return sendMessageResponse(res, 404, 'module not found')

UPDATE BY ID

4 - Add event emitters to all methods

Overview
In eventEmitter --> utils.js
Add event emitters only for important user actions

  1. Add 3 methods for Curriculum --> create, delete, update
  2. Add 3 methods for module --> create, delete, update
  3. Add 3 methods for unit --> create, delete, update
  4. Add 3 methods for lesson --> create, delete, update
  5. Add 3 methods for lessonPlan --> create, delete, update
  • add methods if necessary

-Example only for batabase error createModuleCreatedEvent

export const createModuleCreatedEvent = async (module, user) => {
  try {
    await dbClient.event.create({
      data: {
        type: 'MODULE',
        topic: 'create',
        createdById: user.id,
        moduleId: module.id,
        createdAt: module.createdAt
      }
    })
  } catch (err) {
    const error = new CreateEventError(user, 'create-module')
    myEmitter.emit('error', error)
    throw err
  }
}

Use classes in eventEmitter folder --> utils.js file to record important events.

In eventEmitter --> index.js

Add event listeners for each important user action, follow the existing naming convention for events eg:

myEmitter.on('create-module', (module, user) =>
  createModuleCreatedEvent(module, user)
)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions