# Stack overview

Now that I have been working on the project for several weeks and the technologies being used are starting to settle down, I thought I would share some insights on what I am using — and perhaps also the reasoning behind these choices.

## Authentication :: google

Well, the decision here was kind of easy. I wanted to go with some general OAuth flow and not implement anything on my own. As I am on Google (like many others), I decided to start with it. The way I use it will also enable me to add several other providers later on if they are required.

## Database :: AWS DynamoDB

The project does not need a lot of database technology. At least as of now. Some storage for user data and the bots. As I wanted to be dynamic on the schema side, I decided to go for a NoSQL solution. AWS DynamoDB is a very nice offering for a quick start.

## Caching :: Redis + AWS s3

Reposting requires some fast caching to ensure no double-postings happen. For this, I use a local Redis host. To keep the Redis instance simple, I additionally put the keys into an S3 bucket on AWS as a persistent second layer. This way, I can restart the whole application without losing the cache.

## Backend :: fastapi

As I have been working with FastAPI for the last 3 years, this was a natural choice for a simple yet robust solution for all the APIs.

To schedule the required jobs, I use [apscheduler](https://pypi.org/project/APScheduler/). As with FastAPI, I just love it for its simplicity.

One thing I added only very recently is [fastapi-events](https://pypi.org/project/fastapi-events/). It provides means to dispatch events while handling requests, which will then be handled after returning the responses. A similar idea to FastAPI’s native Background Tasks, but **way** more flexible.

## Frontend (app) :: Vue + Vuestic

Initially, I wanted to do the frontend in React… But while hiking, [@mademyday](https://bsky.app/profile/mademyday.bsky.social) convinced me - simply by being very opinionated about the topic <sup>😉</sup> - to give Vue a try. Well, and I did.

And, as the section headline might have already given away, I kept going with it. It just feels way more natural to create frontends with it. Clear and simple.

As I did not want to create all the frontend components of the app on my own, I also checked for a frontend component library. After reddit-ing for a few hours and some simple tests, I settled for [Vuestic UI](https://ui.vuestic.dev/) and did not regret it so far.

## Frontend (charts) :: chart.js

Although I'm usually not much of a frontend developer, I put more passion than expected into the first version of the metric charts.

%[https://youtu.be/I1W7fjsdy1c] 

The main library I use is chart.js - or, to be more precise, [vue-chartjs](https://vue-chartjs.org/). On top of it, I use the following extensions/plugins:

* [chartjs-plugin-gradient](https://www.npmjs.com/package/chartjs-plugin-gradient) for nice gradients that most of us may know from Grafana. I just had to have some gradients in my area charts 😉
    
* [chartjs-plugin-annotation](https://www.chartjs.org/chartjs-plugin-annotation/latest/) - the name gives it away, a very flexible tool for chart annotations. I use it for the big overlay numbers that show the “totals” on top of my charts.
    
* [chartjs-scale-timestack](https://github.com/jkmnt/chartjs-scale-timestack) for the time axis. It does a fantastic job of rendering nice values automatically on different time-scales.
    

## Frontend (web) :: Jinja2

As of now, I have decided to do all “landing pages” with basic HTML. This means I will use FastAPI + Jinja2 templating here. Again, mainly because I am used to it and not much frontend-fanciness (other than styling) is required. If this changes at some point, I will switch over to some Vue-based solution…

One thing I want to mention, just because it made my life much easier: I included [arel](https://github.com/florimondmanca/arel), which provides a nice page-autoreload-solution. The only downside is that I could not manage to make it detect changes on my template files, which are mounted into a Docker container. This is why I use uvicorn’s `--reload` functionality for now. But at least I do not have to reload the page every time I change the code.

## CSS :: tailwind

This was also an easy decision. Firstly, it is easy to use, and I simply love the way one can create new classes using the @apply tool. Secondly, it is also easy to integrate it into Vuestic, so, in the end, I might even be able to create a central theme for both implementations.

## Infrastructure :: k8s, argocd, prometheus, grafana

All backend code is run on a Kubernetes cluster, which is provided, maintained, and hosted by the one and only [DrPsychick](https://github.com/drpsychick).

Full disclosure: I just love Grafana dashboards. I use them as my daily dose of motivation. This way, I can always see that something is happening on my projects.

## Mails :: MailJet

Not much to say here, I think. I send all transactional emails via [MailJet](https://www.mailjet.com/)’s APIs. A simple web frontend to create the emails. And an even [easier API](https://dev.mailjet.com/email/guides/) to actually send them. No pain in trying to resend etc. MailJet got me covered (for now).

## Any Opinions?

As you may have realized, I tend to try things that are recommended by highly opinionated people. So, send me your opinions and suggestions. What am I doing [completely wrong](https://dev.mailjet.com/email/guides/) in your opinion? Which is **the one** API/library I missed?

Anything else you want to know/share/contribute? Just ping me on [Bluesky](https://bsky.app/profile/fez.world), [Reddit](https://www.reddit.com/user/fez_de/), or [GitHub](https://github.com/fezde). Looking forward to meet you there.
