Class Alerts


In high school (2016), a number of students started taking dual enrollment classes at a local city college. Dual enrollment students had the lowest registration priority, so our classes were always full and waitlisted. To help us get in, I made a script that would check the waitlists for availability and send an email when there was an opening. This proved to be very effective, and I ended up building a simple website around it. By senior year (2019) almost every student that was taking dual enrollment classes was using the website. During the summer before college, I rebuilt the project into Class Alerts, ultimately supporting eight colleges.

Class Alerts Home Page

Unfortunately, over the following years, only a few dozen people used the website. This was less than necessary to pay for expenses, so in December 2022, I shut it down.


In this short post, I want to highlight a few features and lessons learned.

Features

Technology

I was first exposed to Python decorators in this project. I ended up building a powerful system for describing API endpoints. Here's an excerpt:

@app.route("/api/contact", methods=["POST"])
@requires_form_field("email", if_missing="Email missing", redirect_url_for="contact_page",
                     value_pattern=PATTERN_EMAIL)
@requires_form_field("subject", if_missing="Subject missing", redirect_url_for="contact_page",
                     value_pattern=PATTERN_NOT_EMPTY)
@requires_form_field("message", if_missing="Message missing", redirect_url_for="contact_page",
                     value_pattern=PATTERN_NOT_EMPTY)
@limiter.limit("5 per day")
def api_send_contact():
    ...

It included decorators for requiring certain permissions (signed-in, admin, paid, etc.). It automatically repopulated fields on errors and handled CSRF protection.

Lessons

I never intended for this project to become anything massive or profitable. But I did hope it would pay for itself, and I could count on some organic growth to sustain it. Unsurprisingly, that's a hard place to get.

  1. Growth is hard: I had a very established competitor (Coursicle). Although their service was worse in some ways (checking every 5 minutes, only in-app notifications), they offered 100s of colleges, and could afford to offer a version of their service for free. They were VC-backed, and spent on advertising. I focused on an improved experience for a limited number of colleges, even spending around $50 on targeted Google Ads, to no avail. My dedicated user-base from high school dwindled, and few users came in to replace them.

  2. LLCs are not free: I spent around $200 to create a California-based LLC, followed by $800 in minimum taxes despite not making any money. I was a bit scared of liability, but there was little reason for this at my scale, and I terminated it after a year. I can say that I was a CEO—but is that worth $1000? Don't think so.

  3. Helping people is rewarding: So why did I put so much time and money into this project? It's a bit cliché, but being able to help my friends and classmates was the most rewarding aspect. And this didn't really scale past a small group: class enrollment is a zero-sum game. The more people that use the service, the less they benefit.

The project was an educational venture. It was not the right project to turn into a business. But it prepared me in case I ever stumble upon one that is. And of course, I learned a bunch of new tech and was able to help a handful of people.


The full code is now public on GitHub. You can visit some parts of the site on the Internet Archive.