Architecture mistakes I made building a CRM
I made several architectural mistakes building Digital Wave CRM that I would correct if starting over. Documenting them here so others can avoid the same traps.
Mistake 1: The permission system was an afterthought. The initial RBAC model assigned roles at the organisation level. This worked for the first three customers. By customer ten, we needed row-level security based on team hierarchy, deal ownership, and temporary delegations. Retrofitting this into an existing data model required a painful schema migration. Start with a flexible permission model, even if you only need simple roles today.
Mistake 2: Synchronous document generation. The first version generated documents (contracts, proposals) synchronously during the API request. Complex documents with tables and images took 10-15 seconds, blocking other operations. The fix was a background job queue with polling. Design for async from day one if any operation could take more than 500ms.
Mistake 3: Not abstracting the notification system. We started with email-only notifications (SendGrid). When we added in-app notifications, push notifications, and Slack webhooks, each required threading notification logic through every service. A simple notification abstraction layer — even just a centralised event bus — would have saved weeks of refactoring.
The common thread across all three mistakes: I optimised for the present use case without anticipating how requirements would evolve. The lesson is not to over-engineer, but to identify which dimensions of your system are most likely to change and invest in flexibility there.