0002 Architecture#

Status#

Provisional

Context#

  1. This Django app generates and shows user certificates.

  2. The models should store certificate configurations. The certificate types will vary between different course types. The available course types are:

    1. Course.

    2. Lesson.

    3. Pathway.

  3. This Django app uses celerybeat to periodically retrieve data from the external API. Retrieving this data is pluggable - it means that other developers can develop a Python package and install it to have a custom ways to retrieve data from different APIs.

  4. If a user matches the criteria, the certificates will be generated from a PDF template (stored in the assets model). The PDF will be uploaded to S3, and the link will be sent to the user. The generation process should also be pluggable - it means that other developers can develop a Python package and install it to have custom ways to generate certificates.

Decision#

digraph G {
    node [shape=box, style=filled, fillcolor=gray95]
    edge [fontcolor=black, color=black]

    subgraph cluster_0 {
        label = "Open edX";
        style=filled;
        color=lightgrey;

        // Resources
        LMS;
    }

    subgraph cluster_1 {
        label = "openedx-certificates";
        style=filled;
        color=lightgrey;

        // Resources/models
        CertificateType [label="ExternalCertificateType"]
        CourseConfiguration [label="ExternalCertificateCourseConfiguration"]
        Certificate [label="ExternalCertificate"]
        Asset [label="ExternalCertificateAsset"]
        PeriodicTask
        Schedule

        // Processes
        Processing [shape=ellipse]
        Generation [shape=ellipse]

        // DB relations
        edge [fontcolor=black, color=gray50]
        CertificateType -> CourseConfiguration [dir=back, headlabel="0..*", taillabel="1   "]
        CourseConfiguration -> PeriodicTask [dir=both, headlabel="1   ", taillabel="1"]

        // Non-DB relations
        edge [fontcolor=black, color=blue]
        CourseConfiguration -> Generation
        Asset -> Generation
        PeriodicTask -> Schedule

        // Processes
        edge [fontcolor=black, color=red]
        Schedule -> Processing [label="trigger"]
        Processing -> Generation [label="provide elgible users"]
        Generation -> Certificate [label="generate certificates"]
    }


    // Processes involving external APIs.
    edge [fontcolor=black, color=red]
    Processing -> LMS [label="pull data", dir=forward]

}

User stories#

TODO: Move this to the docs.

As an Instructor, I want to enable certificate generation for a course.#

To do this, I should:

  1. Visit course certificate admin page.

  2. Create a new entry with a course ID, certificate type and an “Enabled” toggle.

  3. Internally, each of these entries will be a cron task. This way, we can set individual certificate generation schedules. It means that an Instructor can schedule generating different certificates for the same course at different times.

Once done, the celery cron will be scheduled to run at the specified time. The celery task will:

  1. Retrieve data from the external API.

  2. Check which users are eligible for a certificate.

  3. Generate certificates for the eligible users.

Questions:

  1. Should we use course’s start/end date to gate cert generation?

  2. Maybe we could disable the cron task when the course is closed?