Home > Guides > Adaptive Follow Up (QA)
Use the following guides to QA Adaptive Follow Up.
Adaptive Follow Up (or simmply Adaptive) is a new a feature that essentially auto-generates new assignments based off of a “source” assignment.
Basically a student completes a normal assignment (the “source” assignment), and then the Aktiv system auto-generates a new assignment bassed off of this source assignment. It does this by having a look at what problems the source assignment contained and seeing how well the student performed on these problems, and then determines intelligently what problems to add to a new auto-generated “adaptive” assignment.
The system that determines what problems the adaptive assignment should contain is called the “Adaptive Engine”. This is an independent process running in API Gateway + Lambda. The code is here - Aktiv-Adaptive.
Essentially the backend Aktiv-Server system contacts the Aktiv-Adaptive (known as the “Adaptive Engine”) by providing it a source assignment and student as input, and then this responds with an output of a list of problems to use in a new “Adaptive” assignment.
There is only ever ONE adaptive assignment for a source assignment. This adaptive assignment will contain all the problems chosen for all the students. Technically each student gets a different set of problems. So each problem in this adaptive assignment is only assigned to one student.
For e.g. imagine we have StudentA and StudentB, then inside the Adaptive assignment we could have:
Technically speaking this is how they are ordered in the assignment. Of course, StudentA only ever sees Problem0 and Problem1. And StudentB only ever sees Problem2 and Problem3.
The frontend uses problemStudentView.number
to display the “effecitve” display position to the user.
Also it is possible that some students are assigned a different number of problems. So StudentA gets 5 problems and StudentB gets 6 problems etc.
The backend has an “Adaptive Scheduler” which is basically a service that is scheduled to run roughly every 1-2 minutes, which will basically check our DB for any “source” assignments that need an adaptive assignment (that hasn’t been created yet). Think of this like the backend cron job that runs in the background to create needed new adaptive assignments every couple of minutes.
The Adaptive Scheduler will look for source assignments that match the following criteria:
course.archived != true
AND course.deleted != true
).course.adaptiveEnabled = true
).course.term = thisSeasonalTerm || thisAcademicYear || previousSeasonTerm || previousAcademicYear
).course.expiration = future
).assignment.archived != true
AND assignment.deleted != true
).assignment.adaptiveEnabled = true
).assignment.states != DRAFT
).assignment.dueDate = past
).(Note that the source assignment does not have to have the sourceAssignment.adaptive
settings set to anything), as the backend will use some defaults. It just needs the assignment.adaptiveEnabled = true
.
“Current” course term is defined as any seasonal term or academic yearly term that is within date range. A term is either a seasonal term such as WINTER_2023
, or is an academic yearly term such as ACADAMIC_YEAR_2022_2023
. Each term has a start date and end date based on customer success team definitions.
WINTER
and SPRING
go from 1st of Jan to 30th of April.SUMMER
and FALL
go from 1st of May to 31st of December.ACADEMIC_YEAR_X
go from 1st of May to 30th of April (the following year).Examples:
WINTER_2021
goes from 1st of Jan 2021, to 30th of April 2021.SPRING_2021
goes from 1st of Jan 2021, to 30th of April 2021.SUMMER_2021
goes from 1st of May 2021, to 31st of December 2021.FALL_2021
goes from 1st of May 2021, to 31st of December 2021.ACADEMIC_YEAR_2021_2022
goes from 1st of May 2021, to 30th of April 2022.ACADEMIC_YEAR_2022_2023
goes from 1st of May 2022, to 30th of April 2023.“Current” Examples:
SUMMER_2021
, FALL_2021
and ACADEMIC_YEAR_2021_2022
is current.WINTER_2021
, SPRING_2021
and ACADEMIC_YEAR_2020_2021
is current.“Previous” course term is defined as any term that is before a “Current” term.
SUMMER_2022
FALL_2022
WINTER_2023
SPRING_2023
ACADEMIC_YEAR_2021_2022
ACADEMIC_YEAR_2022_2023
WINTER_2023
SPRING_2023
SUMMER_2023
FALL_2023
ACADEMIC_YEAR_2022_2023
ACADEMIC_YEAR_2023_2024
The Adaptive Scheduler after choosing the source assignments, will then look for students to generate problems for in the adaptive assignment:
student.spoofed != true
).assignment.exemptedStudentIds
).An adaptive assignment is always of type ADAPTIVE
. So you can search for adaptive assignments in the DB by { type: 'ADAPTIVE'}
.
An adaptive assignment will have a reference to the “source” assignment by the field adaptiveAssignment.sourceId
. So the adaptiveAssignment.sourceId = sourceAssignment._id
.
The source assignment will also have a reference to the adaptive assignment by field sourceAssignment.targetAdaptiveIds
.
The adaptive assignment will take general assignment “settings” from the sourceAssignment.adaptive
field. In this, the grading, start date, due date etc can be set. These will all be copied over to the adaptive assignment when it is created by the Adaptive Scheduler. If these sourceAssignment.adaptive
settings are changed AFTER the adaptive assignment is created, then these settings are still applied. The only exception is if the adaptive assignment is published, then the date assigned will not be changed.
Any time the source assignment is updated/saved (and has adaptiveEnabled=true
), the corresponding adaptive assignment (if exists) will have its state also match. i.e. if you unpublish the source assignment, then this will unpublish the adaptive assignment. Or if you publish the source assignment this will publish the adaptive assignment.
If the source assignment “turns off” adaptive follow up (and saves), then this will unpublish the adaptive assignment (if this had already been created and published). This field is handled by sourceAssignment.adaptiveEnabled
.
If students enroll on the course later, then these students will also get picked up and added to the existing adaptive assignment (as per the Adaptive Scheduler).
The adaptive assignment in general is “created” shortly after the source assignment expires. However the “start” and “due” dates will be set independently and are based on the adaptive settings.
Whenever the adaptive scheduler results in new adaptive assignments to be created then it must decide the start and due dates (adaptiveAssignment.startDate
and adaptiveAssignment.dueDate
).
sourceAssignment.adaptive
.Adaptive Assignment Start Date Strategy (adaptiveAssignment.startDate
):
sourceAssignment.dueDate
).sourceAssignment.dueDate
is null).sourceAssignment.dueDate
(if this exists)adaptiveAssignment.createdDate
Adaptive Assignment Due Date Strategy (adaptiveAssignment.dueDate
):
(first we calculate the start date as above)
adaptiveAssignment.startDate
).adaptiveAssignment.startDate
Adaptive Assignment “Late” Due Date Strategy (adaptiveAssignment.lateDueDate
):
(first we calculate the due date as above)
adaptiveAssignment.dueDate
is null (i.e. unlimited), then the adaptiveAssignment.lateDueDate
will also always be null (which means late due date does not apply).adaptiveAssignment.dueDate
).adaptiveAssignment.startDate
(ignored if earlier than the calculated adaptiveAssignment.dueDate
).Note that just because the adaptive assignment has been created, it might not appear in the student feed because it has a later start date.
API: Check which source assignments are pending to be picked up by the scheduler.
curl https://dev.api.platform.aktiv.com/api/adaptive-assignment/source-assignments-pending
X
below). curl 'https://dev.api.platform.aktiv.com/api/adaptive-assignment/source-assignments-pending' \
-H 'token: X'
There is also a “count” version of this (this does not need an admin token):
API: Get the source assignments that have recently failed by the scheduler (and are will be retried later).
In other words, these failing source assignments are just paused for a while (in hope that they may work again in the near future).
(prod) api.platform.aktiv.com/api/adaptive-assignment/source-assignments-failed
Note there is also a count version of this:
API: Check if a specific source assignment is “adaptive-generable”.
curl https://dev.api.platform.aktiv.com/api/adaptive-assignment/{assignmentId}/is-generable
X
below).assignmentId
below). curl 'https://dev.api.platform.aktiv.com/api/adaptive-assignment/{assignmentId}/is-generable' \
-H 'token: X'
API: Check if a specific source assignment is “adaptive-generable” for a particular student.
curl https://dev.api.platform.aktiv.com/api/adaptive-assignment/{assignmentId}/is-generable/{studentId}
X
below).assignmentId
below).studentId
below). curl 'https://dev.api.platform.aktiv.com/api/adaptive-assignment/{assignmentId}/is-generable/{studentId}' \
-H 'token: X'
API: Check what adaptive assignment currently exist for the provided source assignment.
curl https://dev.api.platform.aktiv.com/api/adaptive-assignment/{assignmentId}/adaptive-assignments
X
below).assignmentId
below). curl 'https://dev.api.platform.aktiv.com/api/adaptive-assignment/{assignmentId}/adaptive-assignments' \
-H 'token: X'