Servyst had a product vision — connecting residents with verified local service providers — but no technical foundation. No API, no database, no auth, no payment flow, no dashboards. Everything had to be designed and built from scratch, end to end, within a startup timeline where requirements evolved as the business did.
Two-sided marketplaces are structurally hard to build from scratch — every system depends on another. The booking flow needs auth. Payments need a verified provider record. Disputes need a complete booking history. You cannot build these independently and stitch them together later; the data model has to account for all of it upfront.
On top of that, Servyst was a startup still validating its model. Requirements changed as real decisions were made — provider verification rules, payment release conditions, how disputes should resolve. The technical challenge was building a system rigid enough to be reliable but flexible enough to absorb those changes without rebuilding core logic.
I designed the booking and payment flows as explicit state machines rather than implicit status fields scattered across the database. Every transition — booking requested, accepted, in progress, completed, disputed, resolved — was a defined state with defined rules for what could follow it. This made the data model more deliberate to design upfront, but it meant that when requirements changed around payment release conditions or dispute resolution, we updated the state machine in one place rather than hunting through API handlers. It also made the system auditable: any booking's full history was always reconstructible.
Explicit state over flexible fields — the business rules were too important to leave implicit.
I would lock down a written API contract with the product manager before writing any code. Requirements shifting mid-build is normal in a startup, but several changes late in the project touched core API response shapes that had already been integrated into the frontend. A versioned API spec agreed on upfront — even a simple one — would have contained those changes to the backend without cascading into the UI. It would also have forced earlier decisions on the business logic that kept arriving late.