The relational model basically exists to support option 2.
The “gotcha” with option 1 is that you’re duplicating massive swathes of functionality (auth) that should be shared. You don’t perceive the pain associated with this because you have a magic button (mix phx.gen.auth) that writes the code for you. Once you actually have to maintain that code, you will suffer proportionately.
Option 3 is fine if they’re really separate apps but the fact that you even felt the need to make this post is a pretty good indicator that they are not.
Thinking things through is great and all, but the only way to get better is to practice. If you want to learn how not to make a mess, write more code and force yourself to maintain it. You will eventually learn what works and what doesn’t, and we call that “experience” ![]()






















