💡 Inspiration

Emergency blood shortages are still handled the same fragmented way they were decades ago — hospitals making phone calls, families posting on social media, and nearby willing donors having no idea they're needed just kilometers away. There's no shared coordination layer connecting the people who need blood to the people who can give it, right when it matters most. Project BloodBank started as an attempt to build that missing layer.

⚙️ What it does

Project BloodBank connects hospitals and donors around three core workflows:

  • Emergency Requests — hospitals publish urgent blood needs by type, unit count, and urgency level
  • Compatibility + Proximity Matching — donors only see requests they're biologically compatible with, filtered to a 50km radius using real distance calculation, sorted by proximity
  • Donation Camps — hospitals organize collective blood drives, donors RSVP directly, with automatic waitlisting once capacity is reached

The platform also includes a consent-first availability system — donors control their own availability status; hospitals can log that a donation happened, but can never override a donor's own status. Every match respects both medical eligibility (a computed 56-day donation cooldown) and the donor's personal choice.

Project BloodBank doesn't aim to be the only solution — it's an idea about what the solution could look like.

🛠️ How we built it

Built with Next.js 16 (App Router) and TypeScript on the frontend, Tailwind CSS v4 and Framer Motion for the interface, Prisma 7 with a PostgreSQL database (hosted on Neon) for data, and Clerk for role-based authentication. Deployed on Vercel.

The blood type compatibility engine is a standalone ABO/Rh lookup matrix in TypeScript, validated server-side before any match or contribution is recorded. Proximity matching uses the Haversine formula to calculate real distance between donor and hospital coordinates:

a = sin²(Δφ / 2) + cos(φ1) · cos(φ2) · sin²(Δλ / 2)

c = 2 · atan2(√a, √(1 − a))

distance = R · c

Development was heavily AI-assisted, with iterative planning, schema design, and manual verification at each major step rather than one-shot generation.

🚧 Challenges we ran into

The biggest challenge was a production-only bug: after deploying to Vercel, the nearby-matching feature silently returned stale or empty results — even though the underlying database query logic was correct. The root cause turned out to be Vercel's CDN aggressively caching the API route response by default. Diagnosing it required reproducing the exact bug with real coordinates, adding temporary logging to trace the actual computed values, and confirming the fix (force-dynamic route config + no-store cache headers) against a real reproduction case before trusting it was resolved.

A second challenge was a design correction mid-build: the initial availability system let hospitals directly toggle a donor's status without their knowledge. Recognizing this as a real consent problem — not just a bug — led to redesigning availability as a donor-controlled opt-in layered on top of computed medical eligibility, rather than a field hospitals could freely edit.

🏆 Accomplishments that we're proud of

Getting the core "aha" moment working end-to-end and verified in production: a donor logging in and seeing a real, compatible, nearby emergency request appear live, with the hospital's contact info one click away. Also proud of catching and fixing the consent issue in the availability system before it shipped, rather than after — that felt like the difference between building a feature and building something that respects the people using it.

📚 What we learned

  • Designing a normalized relational schema that handles many-to-many relationships (donors ↔ requests, donors ↔ camps) with proper cascading deletes
  • Implementing real domain logic — blood compatibility rules and geospatial distance — as testable, pure TypeScript utilities rather than vague heuristics
  • Diagnosing production-only bugs that don't reproduce locally, by tracing the full request lifecycle from route config → CDN → browser
  • That "consent" is a design requirement, not an afterthought — especially when building software that touches personal medical-adjacent data

🔮 What's next for Project BloodBank

  • Dynamic radius by urgency — CRITICAL requests could expand the matching radius beyond 50km to reach more potential donors
  • Cross-hospital request relay — when a hospital's local donor pool can't fulfill a request, relay it to nearby hospitals, forming a cooperative network instead of isolated silos

Built With

Share this project:

Updates

Submission history