Gum-Joe / isitweeka

Site for isitweeka.com
https://isitweeka.com
MIT License
7 stars 3 forks source link

isitweeka

This repo contains the source code for the website https://isitweeka.com/, a centre of information for students of King Edward VI Camp Hill School for Boys and King Edward VI Camp Hill School for Girls.

It is primarily concerned with telling students what timetable week it is (A or B), but also provides information on school events (including house event results) and an alert banner for important news (ranging from green and blue for low level alerts, to red for breaking news).

It also has a widely followed social media account covering school news, events and house events. See @isitweeka on Instagram for this.

Our frontend in frontend/ is based on Create React App. A CI script builds this into a bundle every push and deploys it to GitHub Pages to host our website.

Here's how everything in this repo works:

How we find out what week it is

At a higher level (for a deeper level, and the modules involved, read the code) we find the week like this:

Before academic year 2022/23

  1. Every other week we download a copy of the school's calendar of events as a .ical file
  2. This file is stored on our website as a static file
  3. When the site loads, the ical file is fetched
  4. We find the current date in the calendar, and rewind back to the nearest weekMarkerDate (a number, where 0 is Sunday, where an event saying what week it is should be found).
    • On Saturdays and Sundays however, we go to the next monday as students will be interested in what the next week is
  5. If there is an event "Week A" or "Week B", display the week detected. Else, say it is neither Week A or B

From academic year 2022/23

KECHB (but not KECHG) changed how they define the week this year (moving from a separate event each week defining the week to a recurring event), and so an algorithm change was needed:

  1. Every other week we download a copy of the school's calendar of events as a .ical file
  2. This file is stored on our website as a static file
  3. When the site loads, the ical file is fetched
  4. If a recurring rule is used, loop through recurrences until one matching this (or next on weekends) week is found. If no recurrences, the same steps as 4. apply
  5. Use the current date (weekday or weekend) to determine the message shown ("It is" or "Next week is")
  6. If no recurrence or IIWA marker event is found, say it is neither Week A or B

Code also exists to do this detection on a server, with the site then just requesting an API that says what week it is. However this requires running a server which costws money, so instead this client side detection is used instead.

Structure of repo

Packages

IsItWeekA makes use of a monorepo structure to hold the various modules that make it up:

Other folders

Below, find how things are structured in this repo:

The API

Whilst this is currently not deployed, sometimes a server-side API is required. This is normally for when the site needs to fetch data from external APIs such as Eventbrite - this requires an API key, which we can't put in public client-side code.

Therefore, an API was created. I wanted something modular, so this is what we did:

  1. There are a series of services that run as their own programsP:
    1. packages/@isitweeka/service-kech/ - using libisitweeka figure out the current week for KECHB and KECHG once every 30 seconds
    2. packages/@isitweeka/service-eventbrite
      1. This is used to fetched donation data from Eventbrite
      2. It is configurable by environment variables for the API Key, Organisation ID and Event ID
      3. Runs every 30 seconds
  2. These services fetch data and place it into a Redis database
    1. This means services can be written in any platform we want so long as it can reach the Redis DB
    2. For simplicity, TypeScript (node.js) was used, but Python, Rust, Java, anything could be used
    3. Redis keys to use for each service are stored in packages/@isitweea/core/src/constants.ts
  3. The server server/ receives requests from clients at specific routes, fetches the appropriate key from redis and sends it back to the client

The API runs using docker containers:

  1. Each service has a docker file
  2. These docker files are build (manually!) and uploaded to a GitHub container registry for my username Gum-Joe
  3. A server then uses docker compose to pull and run these containers

Since the API is setup lik this, to add a new sevice:

  1. Write the service, set up to store the result of each fetch in a specfic redis key
  2. Build it as a docker image and add it to the docker-compose.yml files
  3. Add a route in server/ that returns the data from Redis
  4. Rebuild server image
  5. Push newly built images to a container registry
  6. Use the docker compose config files (the .prod.yml one) to deploy the updated images to production so they can be used as the API

Building everything (frontend, API, etc.)

Requirements