What is the fundamental issue why you keep switching tech stacks?
I'm not an architect or senior developer, and not saying my take is better, but my considerations would be very different.
First, I would want to have a reasonably clear idea of what you want. My first idea when I hear 'stackoverflow for flash cards' is that you want collections of flash cards. I suppose you need some discovery mechanism, and ways for users to upload and share collections. You mention syncing, I suppose that means that every user always has the last version of a collection. What happens if a user deletes all or most of the flash cards in a collection? Will it be lost for the user or will (s)he be able to use an older snapshot of the collection. This would probably make things more complicated.
Then, I would consider the architecture. It is natural to go for a client-server architecture (and at this point I would draw two circles with two arrows pointing both ways between them). This simple architecture is enough for most applications.
The arrows in this diagram represent dataflow. The choices you make determine the actual data that is sent "over" the arrows. In this case you would need a strategy to distribute the flash cards and update them. So, you define the types of messages that the client and server need to handle and define some data structures for them.
So, the next step is to pick an implementation. An obvious choice for the arrows is HTTP. The client and server can then be implement in any programming language, not necessarily the same. The server can use some DB in the backend. So, again you need have some dataflow between db and server, so you can refine the diagram a bit, and define the data that goes over the arrows.
So slowly you can build up a detailed architecture. Note that it is mostly tech-agnostic, implementation should be possible in most programming languages and you can even make multiple types of client.
Even if you decide to redesign, with this method it is easier to keep your design clean and salvage some parts of protocols/structured that worked well enough.
> What is the fundamental issue why you keep switching tech stacks?
In a sentence: better understanding of the domain/problem and changing my philosophy from "build it quickly" to "build it right".
To repeat myself a bit, I started off with the tech stack I was most familiar with (which is fairly uncontroversial) (F#/RDBMS/Blazor (okay I'm not too familiar with Blazor, but I know C#/dotnet a hell of a lot more than I know JavaScript)). I was originally following the maxim "build an MVP quickly", and I more or less did - I demoed that MVP in a YouTube video on the GitHub. However that advice is tactical - I eventually realized why that advice exists. Startups launch an MVP quickly to de-risk their idea and investigate whether a market exists. I am positive this market need exists. (The real risk is whether it's monetizable... but that's another topic.) I always intended this to be offline-friendly, but just assumed that could be something I could tack on after launching an MVP. I started to investigate that after making the GitHub video, and it turns out to be a significant technical challenge. This facilitated my move to event sourcing, which (in theory) can sync occasionally offline clients. Finally, I grew extremely annoyed at how long it was taking to build an event sourced system. Taking a lesson from my "tacking on offline-mode is easy" mistake, I decided to investigate how a plugin system would work. It turns out there are fundamental incompatibilities between Blazor and any reasonably powerful plugin system. Hence finally, my switch to a VDOM-less UI framework (SolidJS/Svelte) and TypeScript. This kicked me off the dotnet ecosystem (and F#), so I'm glad I decided to this this now rather than post-launch. I previously thought plugins could be something that I "just tacked on later."
> I would want to have a reasonably clear idea of what you want.
Begin with the end in mind :) For me I let the advice of "build an MVP quickly" overcome my better sensibilities. Now, I'm attempting to do "steel thread programming" - something that proves out the technology, before I even consider adding business value.
> What happens if a user deletes all or most of the flash cards in a collection? ... This would probably make things more complicated.
Yes - I have many thoughts on how to resolve this. Event sourcing is of great benefit here, but let's not get into that.
> It is natural to go for a client-server architecture
Yep, my GitHub video demoed this architecture. Unfortunately since what I'm building is going to have an offline mode, this architecture is insufficient.
Unfortunately the devil is in the details. You can describe all the high level arrows/diagrams you want - but as I found out when trying to do event sourcing, what really matters is the implementation. For example, to respond to, "you need have some dataflow between db and [client]"... this is a tough, nontrivial problem that PostGres and other RDBMses have significant problems with.
My adventures have led me to believe that when building out a project of any significant technical complexity - you should first start with a "steel thread". Don't just build out something of "minimal viability" - tacking on additional features that you know you want down the line should be proven out. Perhaps not implemented for real, but there should exist a technical proof of concept.
I'm not an architect or senior developer, and not saying my take is better, but my considerations would be very different.
First, I would want to have a reasonably clear idea of what you want. My first idea when I hear 'stackoverflow for flash cards' is that you want collections of flash cards. I suppose you need some discovery mechanism, and ways for users to upload and share collections. You mention syncing, I suppose that means that every user always has the last version of a collection. What happens if a user deletes all or most of the flash cards in a collection? Will it be lost for the user or will (s)he be able to use an older snapshot of the collection. This would probably make things more complicated.
Then, I would consider the architecture. It is natural to go for a client-server architecture (and at this point I would draw two circles with two arrows pointing both ways between them). This simple architecture is enough for most applications.
The arrows in this diagram represent dataflow. The choices you make determine the actual data that is sent "over" the arrows. In this case you would need a strategy to distribute the flash cards and update them. So, you define the types of messages that the client and server need to handle and define some data structures for them.
So, the next step is to pick an implementation. An obvious choice for the arrows is HTTP. The client and server can then be implement in any programming language, not necessarily the same. The server can use some DB in the backend. So, again you need have some dataflow between db and server, so you can refine the diagram a bit, and define the data that goes over the arrows.
So slowly you can build up a detailed architecture. Note that it is mostly tech-agnostic, implementation should be possible in most programming languages and you can even make multiple types of client.
Even if you decide to redesign, with this method it is easier to keep your design clean and salvage some parts of protocols/structured that worked well enough.