Recently I went „back to school” and decided to learn to build software again. Not code – that’s AI’s job – but build a web app, one of those that developers used to build when I designed flows, screens and interactions for.I’m building an app to manage pilot training. Root for me!
The link to the app is at the bottom of the page
My goals:
- Build an app, not a prototype
- Create an architecture that will allow me to scale quickly
- Document as we go
- Publish to the web
- Learn to build web apps according to DDD

My setup:
- IDE: Cursor
- Database: Supabase
- Deployment: Vercel
- Repository: GitHub
- AI model: Chat GPT Plus
- Documentation: Obsidian
- Apple Command Line Tools to set everything up.
My journey
I would undermine myself if I said I didn’t know anything about building web apps, but I approached Chat GPT – whom I will refer to as „Chat” from now on – as if I didn’t. I told it that I wanted to learn to build web apps and that it suggests where I should start. It had to be the Command Line – which I think is the scariest part.
If you’re not familiar what a Terminal is, I suggest you look something up on YouTube first.
I had to instruct Chat to take things slow, that I’m learning and to keep its answers brief and not answer anything I hadn’t asked. This is very helpful, as otherwise it goes into all sorts of rabbit holes and you have plenty of unrelated reading to do.
Its instruction was very clear, took me by the hand and I could ask the same questions over and over, and not feel like a dummy.
Useful information here: pay attention to what model you’re using. Instructing how to build your first app is most likely everyday bread nowadays, so I used the Instant model for that. Later, when I was researching the domain or looking for trademarks, when coming up with a name for my app, I used the High model, which spent much more time searching, but (I hope) it will keep me out of legal trouble.
Building the app
Like I said, I wanted an app, not a prototype. The difference is, that an app has a real database where real data is stored, users, that need to authenticate themselves and have different permissions, is available on the web, and finally, is scalable, this means, it’s built in a way, that I can deliver the MVP and then add more features. Quickly.
This is was I called „laying the foundation”.

Most of my time I work with Chat and Cursor open side by side. Chat tells me what to do, and I do it. Sometimes I reach out to Supabase and Obsidian. I don’t really use Vercel or GitHub. Committing code to repository and deployments are done through the Cursor Terminal.
Real users
The first rule was to start with logging in by a real user. The user logs in, and sees a starting page. On the web. Nothing more. I wanted to start with that, because too often had I seen whole systems being built and available only on developers’ laptops. Chat told me that Supabase takes care of creating and authenticating users, and instructed me how to create my first user directly from the Supabase UI. This was my first shortcut. I decided that creating accounts and resetting passwords could wait, although, I must say, I had to resist the urge not to build a „Log out” feature and focus on my MVP which was display real data from the real database.

The login screen may not look like much at the moment, but from the very beginning, it’s built using MUI Design System components, and the app is configured to use dark theme.
Real data
Once logging in with an email (fake, but still), and a password worked, I wanted to display real data from the database. I created 2 simple tables, asked Chat to prepare csv content and was ready to go, when I realized, that data is best displayed in read components. So I had to incorporate a Design System.
I followed this incremental, end to end approach throughout my development process. Each time I introduced a new domain object, the UI and proper routing was built at the same time.


The important thing was that an end to end scenario is supported.

Design system
Once I asked Chat what it thinks about the idea – whom I fist had to instruct to be constructive and that I don’t need compliments – it replied with „that’s a great idea”…
It suggested two options, and I went with MUI as it supposedly is great for complex, data heavy system, which is nothing less of what I intend to build.
Until that moment, installing a Design System, for some reason, sounded really scary to me. I’ve built DSes before, but incorporating it is something completely different.
Well, with a good prompt, it was done in a flash. Now, I would look at the MUI website for a component I would like to use and tell Chat to use it to display such and such data.
At first, the home page did not look like much, but from the very beginning, you had to be authenticated to get in and it worked on a phone from day 0.




And it’s using the proper List component from MUI

Responsiveness
„Mobile first” is a slogan that was popular back in the day, so I thought it’d be another good thing to start. Again, I told Chat how I thought different users would use different devices and for what purpose, and it guided me step by step, suggesting what files I needed to create and code I needed to paste into them.
Scalability
Starting with MVP and adding features as we go, is probably my number one value in building software. I also wanted to build according to DDD principles. Chat suggested to start with a proper folder structure, which will pay off later, to which I agreed.
This folder structure – features, lib, theme – was suggested by Chat.

Debugging and Refactoring
It hasn’t been all smooth sailing. Out of the 25 hours I’ve spent on the project so far, ~ 10 hours was spent on learning, discussing and debugging. Without its help when errors appear, I think I would have given up.
I refresh the page -> get an error -> paste the error into the chat -> it tells me what to do.
Sometimes I paste file content, sometimes screenshots. It reads them suprisingly well.
Since I’m learning as I go, I try to understand what is happening in the files, so I often go over line by line and tell it what I think the code means, and it corrects me if I’m wrong – and I think this is a huge differentiator and benefit.

I see that tsconfig.json is shining red. This means „bug” and that’s what we’ll fix first.
Issues with Cursor!
When you’re vibe coding with Cursor, be careful, because it does not always save the content of your files onto the hard drive. You see proper code in the IDE, but when you try to run in, the UI shows an old version. Turns out, that if you open the file in a text editor, the changes are not there.
Overall feeling
In general, the work is very pleasant. I tell Chat what I want to do, it tells me what file I need to change or create. I paste the content of the file and either it tells me where to make changes, or gives me back complete new content.
I am aware, that without recent coding experience, I could be doing it all wrong, but, at the end of the day, if it’s all wrong, it wouldn’t be working, right?
And I think, that fact that I’m using Chat GPT, and external model, rather than Claude, which is built into Cursor, it forces me to understand what is happening. Once I get the gist of it, I will probably switch, so that the model can access all of my files and things might go smoother.
Next steps
Styling the home page and adding a „Pilot details” panel. Clicking on a pilot on the list displays its details on the right. On smaller resolutions, the details will be on a separate details page.
Visit the app
https://vercel.com/velodame/pilot-training
login: pilot@bestpilots.fly
password: bestpilots4ever!


My journey
You can follow my journey, how I am making it.
