Examples/Marketplace
Course marketplace (example)
Instructors upload video courses, students buy them, and instructors get monthly payouts. Built with Next.js, a Node API, Postgres, Stripe Connect, S3 with Mux for video, and Meilisearch for search. Replace any part with how your own system works.
Scale: 40k students, 1,200 instructors, 5 purchases/min
Select a component to see what it is responsible for and which state it owns.
- 1Next.js web app → Node API: Browse and buy
- 2Node API → Meilisearch: Search courses
- 3Node API → Stripe Connect: Create checkout
- 4Stripe Connect → Node API: Payment webhooks
- 5Node API → Postgres: Write orders and enrolments
- 6Next.js web app → S3 video storage: Upload via presigned URL
- 7Node API → Job queue: Enqueue index, transcode and payout
- 8Course worker → Job queue: Claim jobs
- 9Course worker → Mux: Start transcode
- 10Mux → Node API: Asset ready webhook
- 11Course worker → Meilisearch: Reindex course
- 12Course worker → Stripe Connect: Monthly transfers
- 13Next.js web app → CDN: Stream lessons
- Request / response
- Asynchronous
- Bulk data
Select a part to trace its flows.
- Request / response
- Asynchronous
- Bulk data
Parts 10
Flows 13
- 1Next.js web app → Node APIBrowse and buyRequest / response
- 2Node API → MeilisearchSearch coursesRequest / response
- 3Node API → Stripe ConnectCreate checkoutRequest / response
- 4Stripe Connect → Node APIPayment webhooksAsynchronous
- 5Node API → PostgresWrite orders and enrolmentsRequest / response
- 6Next.js web app → S3 video storageUpload via presigned URLBulk data
- 7Node API → Job queueEnqueue index, transcode and payoutAsynchronous
- 8Course worker → Job queueClaim jobsRequest / response
- 9Course worker → MuxStart transcodeRequest / response
- 10Mux → Node APIAsset ready webhookAsynchronous
- 11Course worker → MeilisearchReindex courseRequest / response
- 12Course worker → Stripe ConnectMonthly transfersRequest / response
- 13Next.js web app → CDNStream lessonsRequest / response
Invariants 3
A student is enrolled only after payment succeeds
Enrolment inserted in the transaction that marks the order paid, run only from the verified webhook; unique (order_id) makes redelivery a no-op.
Kept by
Each instructor is paid once per period
payouts unique (instructor_id, period); the Stripe transfer uses idempotency key = payout id.
Kept by
Search results converge to the database
Course changes write an outbox row; the worker reindexes from it; a nightly full reindex repairs drift.
Kept by