Product architecture
A three-sided marketplace optimized for velocity: post → match → confirm → work → pay. Every step is instrumented, every rule is transparent.
From post to payout in under 72 hours, typically less than 10 minutes to fill.
Post
Sets license, borough, rate range, urgency, block size.
Match
Scores eligible clinicians by location, license, reliability, rate.
Bid
Apply at posted rate or submit a counteroffer with a note.
Accept
Accept, reject, or counter. Escrow holds funds on accept.
Work
Clock in, complete shift, clock out with facility signoff.
Pay
Facility invoiced weekly. Clinician paid standard or next-day.
score = 0.35·L + 0.25·D + 0.20·R + 0.10·Rate + 0.10·Fav
Clinicians above threshold 0.6 are notified first; the pool widens every 90 seconds.
Score
100 − (late × 3) − (late-cancel × 8) − (no-show × 20)
Core entities and relationships.
Facility ──< Shift >── Bid >── Clinician │ │ │ │ └── Escrow ── Payout ─┘ │ └── Invoice (weekly, aggregates Shift.finalRate * hours) Clinician ──< Credential (License, BLS, ACLS, TB, ...) Clinician ──< Availability slots Facility ──< Favorites (Clinicians) Shift.status : open → pending → filled → completed | cancelled Bid.status : pending → accepted | rejected Credential : valid | expiring (<60d) | expired
Services and data stores backing the marketplace.
API Gateway
REST + Webhooks, rate-limited, signed.
Postgres + Redis
Transactional state, cache, matching queue.
Matching worker
Streams shift events, scores clinicians, notifies.
Payments core
Stripe Connect, ACH, escrow, next-day payouts.
Notifications
Email, SMS, push. Per-user preferences.
Credential vault
Encrypted uploads with expiry watch.
Messaging
1:1 threads scoped to a shift or facility.
Trust & Safety
Disputes, appeals, admin overrides.