This is something most CS grads don't really grasp immediately, but in the real World business and time constraints normally trump perfection.
Technical debt is fine as long as it's fully understood and managed properly.
Early in my career good enough meant it worked correctly with no thought put into how that functionality is going to age.
I would do things like find a function that did most of what I need, add a bool parameter to trigger a new mode (usually giving it a default value), add some comments, commit, ship! Ten years later that function has four more mode parameters and it's a mess.
These days I'm better at doing one more pass to break things apart or change the interface to accommodate new functionality. I also try to never have bool parameters that triggers a different mode and almost never give parameters default values.