Overview
DooGo ("Dugo" is Filipino for blood) helps families find blood donors fast. A seeker enters the blood type, number of bags, urgency, hospital and needed-by date, then sees only compatible donors who can donate in time and can ask one or several at once. Donors upload a medical record to get verified, switch their availability on or off, and accept requests they can actually fulfil. Once a donor accepts, both sides chat to agree on a time.
The problem
When a patient needs blood, families usually post in group chats and on social media and wait. There is no way to know who has a compatible blood type, who is nearby, or who has donated too recently to give again, so time is lost asking the wrong people.
Goals
- Show seekers only donors who are compatible, verified and able to donate in time
- Follow real donation rules instead of letting anyone accept anything
- Treat seekers and donors equally on the dashboard
- Work well on phones, with a full desktop layout too
Approach
I built it on Next.js with TypeScript and Firebase. Screens are written once and rendered in a phone layout or a desktop layout with a branded header and breadcrumbs, picked by a proxy at the same URLs. The donation rules live in one module (compatibility, waiting periods by sex, one unit per donor, one commitment at a time) and are used by every screen. Because the free Firebase plan has no server code, Firestore security rules do the enforcement: they validate every write, require a real medical record before a donor can be verified, and check that names on a request match the public profiles.
Key features
Blood requests
Blood type, bags, urgency, hospital, needed-by date and up to 5 cities. Ask one donor or several at once, then track each request from sent to accepted to donated.
Real donation rules
ABO and Rh compatibility, a 12-week (men) or 16-week (women) waiting period, one unit per donor, and one commitment at a time. A recovering donor can still accept if they'll be ready by the needed-by date.
Bag-by-bag progress
A 3-bag request needs 3 donors. The request shows how many agreed and donated, and closes once every bag is given.
Verified donors
Donors upload a medical record before they can appear in searches. Only they can see the document; others see a Verified badge.
Live city view
The dashboard shows donors available and blood requests open in your city, plus donors by blood type with low-supply warnings.
Chat and notifications
Accepting a request opens a chat with an automatic first message. In-app notifications and unread badges keep both sides updated.
Account safety
Password rules with a strength meter, a required blood-details step for new accounts, and full data deletion including the medical record.
Challenges & solutions
Enforcing rules without a server
Problem
On the free plan every write comes straight from the browser, so anyone could edit their own data to look verified or send fake requests.
Solution
I moved enforcement into Firestore security rules. Each document accepts only its known fields, "verified" requires a medical record that actually exists, requests can only go to listed donors, and the names on a request must match both people's public profiles.
A 3-bag request is three donations
Problem
Treating a request as done when one donor accepts left patients short, and let extra donors accept a request that was already covered.
Solution
Each request has a public, anonymous summary that counts bags agreed and donated. Counters can only move up by one, donors see when a request is covered, and it only closes when every bag has been donated.
Recovery periods
Problem
A donor who just gave blood can't donate again for 12 to 16 weeks, but they may still have other requests waiting.
Solution
Eligibility is checked against the request's needed-by date, not just today. After a donation, any pending request needed before the donor recovers is declined automatically and the seeker is told to try someone else.
Not favouring one side
Problem
Early versions of the dashboard focused on donors, which made seekers feel like an afterthought.
Solution
The dashboard now shows donors available and requests open side by side, with equal "Request blood" and "Donate blood" actions.
Outcomes
- The full flow works end to end: request, accept, chat, donate, with bag counts and notifications at every step.
- Separate phone and desktop layouts on the same URLs.
- Security rules, headers and redirect checks reviewed before release.
What I learned
- Domain rules (like blood donation intervals) shape the whole product, not just one screen
- Security rules can replace a lot of server code when designed carefully
- Designing for two kinds of users without favouring either
What I'd improve next
- Enable App Check to block automated abuse
- Email or push notifications for urgent requests