Learning, growth, and decision-making throughout the DonorConnect build.
The biggest challenge was implementing session-based authentication with Next.js 16's App Router. The new async params and cookies() APIs required completely rethinking how API routes handle authentication. I had to migrate from usinggetSessionUser() in Server Components torequest.cookies.get('session') in API routes because the cookies() helper doesn't work in route handlers.
Ensuring every database query was properly scoped to the user's organization was tedious but critical. I had to audit every API endpoint to verify organizationId filtering was applied, and that users couldn't access data from other organizations through parameter manipulation.
Configuring Prisma 7 with the new driver adapters for Neon's serverless PostgreSQL required understanding the new configuration format in prisma.config.js and how the custom output path in prisma/generated/ works. Connection pooling and SSL settings needed careful tuning for both local development and production.
The workflow automation feature went through several iterations. Initially I had ambitious plans for complex triggers and conditional logic, but I had to scope down to practical step types (email, task creation, wait periods) that could actually be implemented and tested within the timeline.
The multi-tenant architecture decision made early on (organizationId on every model) proved essential. It would have been nearly impossible to retrofit data isolation later. Taking time to design the schema properly saved countless hours of refactoring.
Every API endpoint needs authentication and authorization checks. I learned to never trust client-side data and always validate on the server. HTTP-only cookies are more secure than localStorage for session management.
I started with grand plans for workflow automation, AI coaching, and advanced analytics. Reality forced me to cut features and focus on what users actually need first: basic CRUD, clear data display, and simple automation. Ship something usable, then iterate.
The seed script with 75 donors and 200+ donations was invaluable. Realistic test data exposed edge cases, made the UI feel real, and helped stakeholders understand the product. Worth every minute invested in creating it.
AI is a powerful productivity multiplier but not a replacement for understanding. The biggest gains came when I used AI to accelerate tasks I already understood conceptually. When I relied on AI for unfamiliar territory (like Next.js 16's new APIs), I often had to spend extra time debugging incorrect suggestions. AI + human judgment is the winning combination.
Building DonorConnect taught me that real-world software development is about making trade-offs. You can't have everything โ you have to choose what matters most for users right now, ship it, and improve iteratively. The nonprofit sector needs accessible tools, and I'm proud to have built something that could genuinely help small organizations manage donor relationships better. This project gave me confidence that I can design, build, and deploy a complete full-stack application from scratch, and that's a skill that will serve me well in any future role.