0) Throw that dumb DDD/FRD schema you learned in college out the window.
1) Gather requirements. Talk, meet, and outline as much of the system as you can with your poor human brain. Make sure you know your tools well enough to ask the right questions. Compile a list of atomic features that can be checked off by a tester for completion. Call it the FRD. Make estimates.
2) Implement a working version of the features. Anything obvious that they do, they should do well, but they don’t have to do EVERYTHING. Show prototypes to the client for feedback on potentially confusing features whenever possible. Update estimates.
3) Review the running code with the client to ensure that you haven’t forgotten any functional requirements. This does not include bugs. You must learn this difference. Get a final sign off from the client agreeing that the FRD is complete and no additional features are required. This is absolutely critical for your sanity later.
3) The code is now in “beta”. This isn’t the stupid flash word that is overused everywhere to mean “new and cool”. It means that the client is seeing the code run and providing feedback, and no new features can be added. Only bugs can be fixed, and only without causing new ones. If the client cannot be held responsible for putting the time in to test the code, then you need to find someone that can.
4) When you feel like you are getting down to the last few show stoppers and you as a developer or project manager feels that the system is stable enough to release, start talking to the client about a deadline for bug submittal. There will always be more bugs. It will never be perfect, but it WILL be USABLE. If they thought that they were paying for perfection, direct them to the nearest meditation hall and instruct them that perfection is only found within.
5) You are gold. Or, at least your code is. Compensate your employees as well as you can while retaining enough capitol for the next project.