The basis of any engineering is creating something that’s useful to your customer. Whether that’s yourself, somebody else or a genericised “customer” is irrelevant; anything that will be in the final product will be with the basis that the user wants it.
The user needn’t be who people think it is. Facebook’s users aren’t the people editing their profile, it’s the advertisers and companies buying data. The user for a non-refundable product isn’t the one using it, it’s the one buying it. Focusing on the right user is something that takes time to get right and will still go wrong. You could split it up as “perceived user” and “financial user” – the one who interacts with the product and the one who generates your income. In lots of cases, especially consumer scenarios with proper return laws they’re the same user – an unhappy perceived user will get his money back and cease being a financial user; a happy perceived user will leave his money in your bank account.
In lots of cases helping your perceived user is going to help your financial user, and making things uncomfortable for your perceived user is going to hurt your financial users. In that way, they’re connected.
So, where does YAGNI come in? In case you’re not familiar with the acronym, it stands for “You Ain’t Gonna Need It”. Put really short, it’s the thing you tell yourself every time you come up with any concept or detail on your design. One of the most important parts is that it applies to your *current* status of development on your product. If you want to make a big database and drag in some kind of big database thing, implement it as a linked list first. Or a std::map, or a HashTable, or a Dictionary, or whatever fits and is easy. When you run into the actual limit that it won’t fit or where the actual database would be better, only then do you replace it with the actual database.
For most projects, there’s a choice what you want. Commercial products can throw money at a problem until it is solved; open-source tends to split into two halves: the projects that are fast, efficient and complete, but that don’t work and on the other hand the projects that work, but are slow, inefficient and incomplete. Prefer the incomplete, inefficient and slow but working software to the complete, efficient, fast but not-working software.