The problem
Due to the nature of how my place of work operates, FTP/SFTP is the only way to deploy code for 98% of the sites we work on. There are too many opporunities for code to be overwritten incorrectly.
There were situations where developers were overwriting analytics codes and pixels with incorrect versions. Either leading to gaps in analytics data, or worse, analytics data going into the wrong account. Both of which happen without people noticing, leading to a lot of red faces.
The solution
To solve this, I developed a basic service that monitors the sites we manage for changes to analytics codes. It would store each of the sites, their environments (production, staging, development) and test schemes to run against the environments. Test schemes would have a frequency set for how often they should run.
Each test scheme would have a series of tests, which are strings that are searched for in the source of a webpage. A cron would run in the background, running the test runner once every 15 minutes. If a test scheme matches the current time frequency, then it’d be scraped with Puppeteer and checked for the code.
Puppeteer was chosen over using a standard fetch request to allow JS to run before scraping. Meaning if Google Tag Manager is used to load in more scripts that need to be tracked, they can be found.
If a test scheme runs and tests fail for any reason, a notification is sent to Slack by webhook. This allows the relevant people to be able to fix things quickly if a change is made that shouldn’t be.
The stack
Lifeline, is in two parts. A Fastify API running on Bun with MongoDB. Then a SvelteKit frontend to manage the UI. The service was split into separate services due to the API needing to do significantly more work than the frontend.
The backend
I’d been looking for an excuse to build an API in TypeScript and this seemed like the perfect opportunity. It needed to be lightweight, but provide the essentials for building out an API. Fastify was chosen as it was incredibly fast and it’s ecosystem of plugins meant you could add on features as you need them. This approach also meant I could try out DDD (Domain Driven Development) and have each feature self contained within the API.
The API used Vitest for testing, Bun’s test runner would not work with Fastify for some reason.
Clerk was used for Auth. Basic auth was only needed, but I wanted to try out their supposedly super fast auth setup. It was indeed very fast to setup.
I also added on the Swagger plugin to Fastify, meaning there are auto-generated swagger docs to accompany the API.
The service was then dockerized and is deployed to Google Cloud. I setup a continous deployment to Cloud Run from the repo that will build and deploy the container on commit.
The frontend
I decided to listen to tech Twitter and abandon React for this one. As it was a fairly straightforward UI, I decided to try out Svelte and SvelteKit. The ecosystem is no where near the size of React’s, so there are situations where it’s difficult to find an off the shelf solution for something. Especially when it came to using a UI library. I wanted an off the shelf pre-built UI library like Mantine so I could just build. After too much time searching, I came across Flowbite Svelte which did the trick.
The frontend was then hosted on Vercel, which as always, was a dream and completely effortless.