<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Reposter]]></title><description><![CDATA[Reposter]]></description><link>https://blog.reposter.fez.world</link><generator>RSS for Node</generator><lastBuildDate>Thu, 14 May 2026 21:14:22 GMT</lastBuildDate><atom:link href="https://blog.reposter.fez.world/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Stack overview]]></title><description><![CDATA[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 ...]]></description><link>https://blog.reposter.fez.world/stack-overview</link><guid isPermaLink="true">https://blog.reposter.fez.world/stack-overview</guid><category><![CDATA[Build In Public]]></category><category><![CDATA[coding]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[chartjs]]></category><category><![CDATA[AWS]]></category><category><![CDATA[DynamoDB]]></category><category><![CDATA[Redis]]></category><category><![CDATA[S3]]></category><category><![CDATA[FastAPI]]></category><category><![CDATA[Jinja2]]></category><category><![CDATA[Python]]></category><category><![CDATA[k8s]]></category><category><![CDATA[Grafana]]></category><category><![CDATA[side project]]></category><dc:creator><![CDATA[Felix Kratzer]]></dc:creator><pubDate>Wed, 18 Jun 2025 23:02:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/KuCGlBXjH_o/upload/9a8a67dc1f29c709496c1d19a8ea0704.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>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.</p>
<h2 id="heading-authentication-google">Authentication :: google</h2>
<p>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.</p>
<h2 id="heading-database-aws-dynamodb">Database :: AWS DynamoDB</h2>
<p>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.</p>
<h2 id="heading-caching-redis-aws-s3">Caching :: Redis + AWS s3</h2>
<p>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.</p>
<h2 id="heading-backend-fastapi">Backend :: fastapi</h2>
<p>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.</p>
<p>To schedule the required jobs, I use <a target="_blank" href="https://pypi.org/project/APScheduler/">apscheduler</a>. As with FastAPI, I just love it for its simplicity.</p>
<p>One thing I added only very recently is <a target="_blank" href="https://pypi.org/project/fastapi-events/">fastapi-events</a>. 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 <strong>way</strong> more flexible.</p>
<h2 id="heading-frontend-app-vue-vuestic">Frontend (app) :: Vue + Vuestic</h2>
<p>Initially, I wanted to do the frontend in React… But while hiking, <a target="_blank" href="https://bsky.app/profile/mademyday.bsky.social">@mademyday</a> convinced me - simply by being very opinionated about the topic <sup>😉</sup> - to give Vue a try. Well, and I did.</p>
<p>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.</p>
<p>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 <a target="_blank" href="https://ui.vuestic.dev/">Vuestic UI</a> and did not regret it so far.</p>
<h2 id="heading-frontend-charts-chartjs">Frontend (charts) :: chart.js</h2>
<p>Although I'm usually not much of a frontend developer, I put more passion than expected into the first version of the metric charts.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/I1W7fjsdy1c">https://youtu.be/I1W7fjsdy1c</a></div>
<p> </p>
<p>The main library I use is chart.js - or, to be more precise, <a target="_blank" href="https://vue-chartjs.org/">vue-chartjs</a>. On top of it, I use the following extensions/plugins:</p>
<ul>
<li><p><a target="_blank" href="https://www.npmjs.com/package/chartjs-plugin-gradient">chartjs-plugin-gradient</a> for nice gradients that most of us may know from Grafana. I just had to have some gradients in my area charts 😉</p>
</li>
<li><p><a target="_blank" href="https://www.chartjs.org/chartjs-plugin-annotation/latest/">chartjs-plugin-annotation</a> - 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.</p>
</li>
<li><p><a target="_blank" href="https://github.com/jkmnt/chartjs-scale-timestack">chartjs-scale-timestack</a> for the time axis. It does a fantastic job of rendering nice values automatically on different time-scales.</p>
</li>
</ul>
<h2 id="heading-frontend-web-jinja2">Frontend (web) :: Jinja2</h2>
<p>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…</p>
<p>One thing I want to mention, just because it made my life much easier: I included <a target="_blank" href="https://github.com/florimondmanca/arel">arel</a>, 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 <code>--reload</code> functionality for now. But at least I do not have to reload the page every time I change the code.</p>
<h2 id="heading-css-tailwind">CSS :: tailwind</h2>
<p>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.</p>
<h2 id="heading-infrastructure-k8s-argocd-prometheus-grafana">Infrastructure :: k8s, argocd, prometheus, grafana</h2>
<p>All backend code is run on a Kubernetes cluster, which is provided, maintained, and hosted by the one and only <a target="_blank" href="https://github.com/drpsychick">DrPsychick</a>.</p>
<p>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.</p>
<h2 id="heading-mails-mailjet">Mails :: MailJet</h2>
<p>Not much to say here, I think. I send all transactional emails via <a target="_blank" href="https://www.mailjet.com/">MailJet</a>’s APIs. A simple web frontend to create the emails. And an even <a target="_blank" href="https://dev.mailjet.com/email/guides/">easier API</a> to actually send them. No pain in trying to resend etc. MailJet got me covered (for now).</p>
<h2 id="heading-any-opinions">Any Opinions?</h2>
<p>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 <a target="_blank" href="https://dev.mailjet.com/email/guides/">completely wrong</a> in your opinion? Which is <strong>the one</strong> API/library I missed?</p>
<p>Anything else you want to know/share/contribute? Just ping me on <a target="_blank" href="https://bsky.app/profile/fez.world">Bluesky</a>, <a target="_blank" href="https://www.reddit.com/user/fez_de/">Reddit</a>, or <a target="_blank" href="https://github.com/fezde">GitHub</a>. Looking forward to meet you there.</p>
]]></content:encoded></item><item><title><![CDATA[2 weeks in - time for a first recap]]></title><description><![CDATA[Looking back, it all started about three or four weeks ago. I had "finished" my previous side project, alc4.me, so my brain started to look for new ideas to work on. As I was already running a Bluesky repost bot and was thinking about starting a new ...]]></description><link>https://blog.reposter.fez.world/2-weeks-in-time-for-a-first-recap</link><guid isPermaLink="true">https://blog.reposter.fez.world/2-weeks-in-time-for-a-first-recap</guid><category><![CDATA[Build In Public]]></category><category><![CDATA[progress]]></category><dc:creator><![CDATA[Felix Kratzer]]></dc:creator><pubDate>Thu, 12 Jun 2025 10:34:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/npxXWgQ33ZQ/upload/704b2351a443e6cc34e43640ff9782a9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Looking back, it all started about three or four weeks ago. I had "finished" my previous side project, <a target="_blank" href="https://alc4.me?utm_source=reposter&amp;utm_medium=post&amp;utm_campaign=20250612">alc4.me</a>, so my brain started to look for new ideas to work on. As I was already running a Bluesky repost bot and was thinking about starting a new one, I got the idea of creating a little "platform" that would allow me to easily configure such bots <strong>and</strong> to run them in a more controlled environment than my previous implementation.</p>
<p>The last few weeks I had also started to read along in <a target="_blank" href="https://www.reddit.com/r/SideProject/">r/SideProject</a> and r/buildinpublic. So I decided to build a platform that could be used by others as well (aka "SaaS") and to share my progress about it publicly. This post is the first result of the latter.</p>
<h2 id="heading-what-has-happened-so-far">What has happened so far</h2>
<p>The first thing I worked on was the backend, which provides all the required functionalities, such as authentication, user management, bot management, and more. Creating the required APIs was quite easy, as I had done things like this several times. But for the first time, I actually incorporated authorization using the "login with Google functionality". And thanks to this <a target="_blank" href="https://blog.futuresmart.ai/integrating-google-authentication-with-fastapi-a-step-by-step-guide">great tutorial</a> by <a class="user-mention" href="https://hashnode.com/@sakalya21">Sakalya Mitra</a>, it was quite easy to achieve.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749742944955/fdc57a87-b863-452c-9e88-3d35f029d7e5.png" alt class="image--center mx-auto" /></p>
<p>Of course, all this backend work also included learning about and integrating dynamoDB as the backend database.</p>
<p>Next was the actual bot runner. Again, this was not too hard as I had done similar things before, and I could also reuse parts of the code of my old implementation. The trickiest part here was getting the Bluesky session handling correct so my bots would not get rate-limited again. One of the main reasons I decided to implement my bot handling new from the ground up.</p>
<p>The third step was implementing the frontend. This was by far the most complicated thing, as I usually do not do a lot of frontend development. I started with a basic React solution. Again, because I had seen some React before. But luckily, the one and only <a target="_blank" href="https://bsky.app/profile/mademyday.bsky.social">@MadeMyDay</a> convinced me to check out Vue as he strongly prefers it over React. And I must say, I do not regret looking into it at all. So, after learning a lot, trying several component libraries, I finally got the first working version of the frontend done.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749721641559/83d338b4-1c0f-4505-8f56-58eaae2bede5.png" alt class="image--center mx-auto" /></p>
<p>So, after these first two weeks, I have a frontend that allows me to interact with the system. A backend that stores data and allows interaction with the data. And a scheduler that is running two bots as of now (will share some statistics in one of my next posts).</p>
<h2 id="heading-next-steps">Next steps</h2>
<p>As usual, there are a lot of things to be done. But these are the bigger ones that are on my agenda for now:</p>
<ul>
<li><p>As you could very clearly see in the screenshots, some basic styling of the frontend is required. So I am pretty sure that I will do some more improvements on this side. Tailwind, here I come!</p>
</li>
<li><p>To have a smooth onboarding journey, I will include some transactional emails. I’ve done first tests but the overall onboarding needs to be defined.</p>
</li>
<li><p>Share more about the progress and the stack I am using</p>
</li>
<li><p>Getting in touch with people to get feedback on this project</p>
</li>
</ul>
<h2 id="heading-questions-wanna-join">Questions? Wanna join?</h2>
<p>I would be really happy to hear from you. And it does not matter if you have questions, feedback, ideas, or even think the whole thing is not worth it ,-). Any of your feedback is welcome.</p>
<p>Also, if you want to be part of the pre-pre-alpha users, just ping me and we can see what we can do.</p>
<p>You can find me on Bluesky (<a target="_blank" href="https://bsky.app/profile/fez.world">@fez.world</a>), Reddit (<a target="_blank" href="https://www.reddit.com/user/fez_de/">fez_de</a>), or GitHub (<a target="_blank" href="https://github.com/fezde">fezde</a>).</p>
]]></content:encoded></item></channel></rss>