Virtual Folder App (2021)

Virtual Folder App (2021)
The default page of the Virtual Folder App.

GitHub: https://github.com/McMackety/folder-lti-archive

The Virtual Folder App was a LTI (Learning Tool Integration) designed to make it extremely easy to create study "Folders", a multi-page study sheet used to review for the IB (International Baccalaureate) History of Americas IA (Internal Assessment).

The idea for it originated when I was a senior in High School, at the time COVID was still fresh and many people decided to do synchronous online learning rather than returning to school in-person. As such, given that online learning was still quite new at the time and limited tools were available, me and my friend decided that it would be a cool project to develop a web application for. Thus, we started development with the following constraints:

  • It should be as easy as possible to write and submit folders.
  • It must support multiple folders.
  • It must allow for image uploads.
  • It MUST integrate with the Canvas LMS as an assignment.

The Application

A view of a Folder Assignment within Canvas LMS.

The application was split into three separate sections: the backend, frontend, and PDF generator. The frontend was a React Single Page Application (SPA) that was hosted on Cloudflare Pages, the backend was a GraphQL Server written in Golang hosted on a AWS EC2 instance, and finally the PDF generator was a NodeJS server that would use puppeteer to generate a PDF of the folder.

The frontend has four separate pages that can be shown:

  • Home Page (Seen at top of this post, viewable by anyone)
  • Assignment Page (Seen by students only, allows for folder editing and submission)
  • Selection Page (Allows the teacher to select which folder is used on an assignment)
  • View Page (A read-only view of the folder available to students after the due date)

All of those pages make GraphQL calls to the backend server to retrieve and save the folders to the server.

The Folder Selection Page.

On the serverside, the backend is a stateless application that authenticates the user with a LTI V1.1 (https://www.imsglobal.org/specs/ltiv1p1/implementation-guide) authentication request sent by Canvas, then allows that user to query their individual folders based on the assignment ID returned by the LTI authentication. The folder information is stored on DynamoDB (all text data) and S3 (images), with the backend handling all queries/uploads/downloads to those respective services.

An example of the folder editor with a test folder.

Finally, the PDF generator is a NodeJS web server that will generate and serve a PDF version of a folder. It does this by creating a Puppeteer instance, loading the folder's data, displaying that all in the Puppeteer window, then saving that as a PDF and responding to the GET request with that PDF. This means that getting a PDF version of your folder is as easy as pointing your web browser to https://pdf.folders.chasemacdonnell.net/<assignment-id> (server is not online) when you are logged in. The PDF generator is also used to return a PDF version of the folder to Canvas when the folder is submitted, as can be seen below.

A folder that has been submitted by a Test Student to Canvas.

Results

This application was ran from 2021-2022 and was used by two years worth of students when creating folders for IB History of Americas at my school. As such quite a few things were learned:

  • First off, observability is key to getting to the root cause of issues, quite often we were informed of an issue that could not be replicated. Thus we added Sentry Analytics to trace errors down to which users saw errors on which assignments.
  • Secondly, don't scale too early, realistically this project SHOULD NOT have used DynamoDB and S3, it should have used SQLite and a local folder for image storage. This would have vastly reduced the cost to run this program and made it far easier to change in the future, as now this application has AWS vendor lock-in.
  • Finally, reliability and validation is key to software, people would spent upwards of ten hours filling out these folders, if this application failed or experience data loss the results would be quite upsetting. As such a key part of our testing for this application was manually testing the submission and saving processes, then monitoring those actions using Chrome DevTools and the console.

All in all this ended up being one of my favorite projects from early in my education, and shaped a lot of how I do any form of development now-a-days.