How a friend's call ended up with me building #AThing
Tags: nextjs, react, typescript, prisma
Published: 2022-12-08 07:17:10

Hi, In this post I'll talk about how I ended up creating **[A Thing](https://athing.vercel.app/)**, _an open source, fullstack platform dedicated towards people struggling with mental health_. I'll tell how, but let's begin by telling you why. 💚

## ⌚ Back Story 
(tick tick…click…) Shh! We go back in time. About two months ago one night I got a call from one of my friends Devesh and we talked about how people often struggle a lot in their day to day lives. Thoughts, are something which people on the internet base their entire identities around and they are also something which people find often hardest to share. Atleast, I do. I know platforms like twitter exist and even though they give you a choice to choose your identity. Somewhere in the authentication flow you'll find something that is linked to you. It could be your email, phone, sso or anything else used to access those services.

This topic deserves an article on it's own and I'll save it for later but for now I'll tell you two problems that I found that engulf today's social media platforms. (In my opinion)

- Lack of transparency. To be honest, I hate when amazing techonologies are put behind this closed door's and we never get a chance to learn from it.
- The Identity Problem. It is necessary to strike a balance between maintaing law and order and still giving enough privacy to individuals.

On top of just the social isses. We have our stack issues. The problem with current frameworks is that they rarely cover typesafety which is very important if you want secure and have a well defined data flowing from backend to frontend.

So compressing down, We have four important issues to deal.
- Full Typesafety
- Open Source
- Identity Issue
- Transparency

There I was and I thought to myself. _"You know what? Let's create a open source platoform that is run by community themselves..."_

And Then it was all a game of time.

## 🧑🏽‍💻 The Ingredients

So did I use the new #solidjs release? or #astro or … Well, I wanted to use #t3-stack here. The reasons is typesafety. It takes care of our first issue. I can also quickly scaffold a serverless API with #tRPC (this is better dev-ex since i don't have to deal with a lot of REST issues such as validating data, making sure it's typesafe with custom zod schemas etc. tRPC take's care of everything.)

The offerings of T3:
- Everything's Typesafe thanks to tRPC and zod. 💚
- [tRPC](https://trpc.io/). Want an API quickly? It has your back. ✨
- [Prisma](https://www.prisma.io/). Oh your app needs database? It got you covered. 💽
- [Next-Auth](https://next-auth.js.org/). Don't want to deal with authentication for that third side project of the month. It still has your back. 🔒
- [NextJS](https://nextjs.org/). Who doesn't love nextjs? ⚡
- [Tailwind](https://tailwindcss.com/) out of the box. The frontend UI goat 🐐.

> T3 makes it really easier for you to use all of these at once or on select the ones you need. Just go to [create.t3.gg](https://create.t3.gg/) if you want to try or learn more.

Extra Tools:
- [Excalidraw](https://excalidraw.com/). I'm in love with the tool. The amount of productivity it has boosted for me is simply amazing. (Yes, I even used to create mock designs for the UI right on the whiteboard.)
- [Figma](https://www.figma.com/). The Icon? All credits to my fine work in Figma.

Okay, Okay, Now you know I'm a huge fan of the stack. So, Now It's a puzzle game more than an application challenge. We have all the peices. We need to put them together.

## 🍳 The Recipe 

The first and foremost was the main app itself. The app itself took the largest chunk of the total time I devoted to the project and it's reasonable. Let's dive in step by step:

### The Authentication
Well, after initialziation of t3 stack. My first step was to create the Authentication. Remember the challenge I discussed earlier? _The Identity Challenge_. Well, a simple solution I came up with was to simply generate usernames for the user's and ensure there is no link between the user's real identity and the platform's identity. This approach would also require me to let them simply signup via a password.
This approach also has drawbacks. How? Let me show you.

Tech giant's usually require you to signup via an email or phone to prevent spam on their servers. This is nice but then again, now we go back to "square zero" back to identity problem. So how do we prevent bots? After a little research, I found an amazing article with several awesome ways to do so. Internet is amazing. I chose two ways.
- **Captcha**: (Readers Voice: _Google Captcha? Isn't it famous for some shady stuff? What did you go for?_) I used HCaptcha here. An alternative solution to captcha instead of Google Recaptcha. In short, you verify the captcha solution submitted by user over the API on the backend and it returns true if it's valid. You treat all other attempts as invalid. Easy Peazy.
- **Rate Limiting**: The good old solution to bots. I created a simple middelware with memory rate limiter. Then I assigned the middelware to the tRPC public procedures that were exposed (signup/login).

**The Authorization Flow (on private procedures via middleware):**
A typical Authorization Flow goes like and this app is no less exception.
![A Thing's Authorization Flow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l134xmey2115dl1m8czl.png)


**The Authorization Flow (on public procedures):**
The Authentication Flow is a bit hard to draw but Here's a quick summary. A user signs up with a password, the forms submits three fields to the server. The password, the HCaptcha token, the terms and services boolean. On the backend. I validate the HCaptcha Token and if it's valid. I generate the user a username and add everything to the database. Now I send the response back to the user with their new (generated) username which they can use to log in.

> Tip: Depending on the way you go about building your authentication. You'd somewhat rely on a secure cookie to hold the `access token` or your user's login state. You can create a`nextjs middleware to check for the cookie's presence in the `NextRequest` and then proceed. You can do so much in the middlewares and auth is just an example. It could be A/B Testing, Geo Fencing and so many cool things.

Phew, So Problem Solved? Sort of. Since the app is quite small, it's barely an issue to manage it. If the app grew to a tremendous size. This would be a nightmare unless solutions like Machine Learning are involved. For now, I consider this a win. This approach also has a drawback. There is no way to recover accounts as there is no way to identify you. (which is a good thing but it may turn bad if you forgot your password. hence i recommend you to write it down.)

### The Features

So, we're here in the little happier part. The features. So what should a social media app hold? Photos, Videos, Text, Comments. Eh Nope, What's the point of building the same thing every other social media out there offer's? This was the very question I ended up on. So, considering I wanted people to rant about their daily lives. I settled on two features. 
- Notes. You can write a quick short note.
- Journals. You can write a long journal entry

It's not too hard to build these features. I spent most of the time on UI. I really want my project's to look beautiful. Why? I believe that it's the first interaction your user has. Put yourself in the shoes of a consumer/user. Would'nt you visit again if you had a really good experience?

With this idea, I usually build all my projects and this one was no exception. I built everything in a private procedure and created yet another middleware to pass the user state (id) in the context so I could access it in my procedures If I needed to.

I used [`Framer Motion`](https://www.npmjs.com/package/framer-motion) for the animations which is an outstanding library and I learned a lot about layout's and groups. Another awesome mention I want to credit here is a library called `cva` or [`class-varience-authority`](https://www.npmjs.com/package/class-variance-authority). The amount of class concatication it has saved me from while building reactive components is just incredible.

And a week of work and everything was done. By this point, The core app was ready.

### 🔮 So What's Next?
What do you think is missing? A Landing page of course. I built the landing page quickly and also created some more page's I thought were important such as a `/stats`, a `/rules` and that's it. The stats use Incremental Static Rendering with a invalidation period of 30 minutes to display almost real time statistics of the platform and rules display clear guidelines on what could lead to termination of the account. 

### 🛣️ Future Roadmap
This was my second attempt at creating something. I know this is not going to be the next big thing and I never really planned it that way. However, I did enjoy the journey it took me and I hope the target audience, i.e. the people who want to vent in the notes or rant about their daily lives in the journal entries might use it someday. 
I'd also love if you want to contribute to the project or add more features to it. Just go [here](https://github.com/is-it-ayush/athing#i-want-to-contribute). 💙

So did we achieve our initial goals?
- ☑️ Full Typesafety
- ☑️ Open Source
- ☑️ Identity Issue
- ☑️ Transparency

Yes, We did and now here are some stats on how long it took me for this project.

![The time it took to completet the project and a generel overview.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbl8os3gcnjbpvuvyryq.png)

That's enough for this one. I hope you learned something and maybe enjoyed the whole blog. For me, I'll go into hibernation until I get enough inspiration to start something fresh. Thanks for reading. <4