Advanced Concepts
Stability
Your custom transformation is part of the pipline for the sourceor integration it is applied to. This means that it will be run every time the source or integration is modified. Because of this the output needs to be stable so that changes to the dataset only occur when you want them to. Fundamentally, for a function to be "stable", the output should be the same every time the transformation is run.
Do not intoduce randomness into your transformation. This will cause the output to change every time the transformation is ran.
If you need to introduce randomness for some reason, consider using some sort of pseudo-random algorithm that starts from a stable seed. It is recommended you use Edlink's id
as a seed. This will ensure that your pseudo-random operations produce the same result everytime they run. Edlink object IDs are always UUID v4 (although they may be UUID v5 if they're inserted into the dataset via a transformation) so they will have enough natural entropy to create sufficiently random results.
For example if you needed to generate random names you could do something like this:
for (const person of $input.people.values()) {
person.first_name = generateFirstName(person.id);
person.last_name = generateLastName(person.id);
person.display_name = `${person.first_name} ${person.last_name}`;
}
return $input;
This example assumes you have implemented a function that generates a first and last name based on a seed. This will ensure that the same person will always have the same name.
Referential Integrity
The $input
parameter is a self-referential dataset. It is a custom data structure that will manage references and dependencies for you. It is recommended that you modify this dataset in place and then return it for the best results. For this reason you should use the provided functions to create and delete entities. These functions will ensure that the references and dependencies are maintained.
This data structure is designed to protect you from getting the dataset into and invalid state. For example, if you try to create an enrollment for a person that does not exist, the dataset will throw an error. This is very useful later on as recovering from an invalid state can be very difficult.
Modifying references
Additionally, if you are modifying references to other entities the dataset will manage the references for you. For example, if you modify an enrollment to reference a different class. You can simply change the class_id
property and the dataset move the enrollment to that class's list of enrollments.
const some_class = $input.classes.get('some_edlink_class_id');
console.log(some_class.enrollments); // [ ]
$input.enrollments.get('some_enrollment_id').class_id = some_class.id;
console.log(some_class.enrollments); // [ Enrollment ]
Please note, we do not currently support array manipulation operations on the dataset. For example, you cannot use Array.push
to add an additional school_id
to a person
object. Instead, you should replace the whole array like so:
const some_person = $input.classes.get('some_edlink_person_id');
// BAD
some_person.school_ids.push('some_edlink_school_id');
// GOOD
some_person.school_ids = ['some_edlink_school_id', 'some_other_edlink_school_id'];
Creating and Deleting entities
There are some important details to understand when creating and deleting entities. Although the dataset manages references and dependencies for you, it is important for you to be aware of what it is doing.
Creating Entities
If you are creating a new entity that references another entity, the referenced entity must exist before you create the new entity.
For example, if you are creating an enrollment for a person not yet in the dataset. You must create the person first. And only after the person is created can you create the enrollment.
const person = $input.people.create(
'your_stable_id',
Person.from({
first_name: 'John',
last_name: 'Doe',
display_name: 'John Doe'
})
);
$input.enrollments.create(
'some_other_stable_id',
Enrollment.from({
person_id: person.id,
class_id: some_edlink_class_id,
role: Role.Student,
state: EnrollmentState.Active
})
);
Deleting Entities
Deleting entities with dependents will delete the dependents as well if they require the deleted entity. Otherwise the entity's reference will be removed from the dependent. For example, deleting a person will delete all their enrollments. However, when objects support an array of dependencies (e.g. a person can have multiple school_ids
), deleting an entity will just remove its ID from the arrays that reference it.
For example:
- When you delete a person, all their enrollments will be deleted.
- When you delete a class, all the enrollments for that class will be deleted.
- When you delete a school, all the classes in that school will be deleted (and subsequently all the enrollments for those classes).
However:
- When you delete a school, Edlink will not delete the people in that school. Instead, it will remove the school's ID from the
school_ids
array of each person in that school.