Creator challenges on a ledger that never drifts.
A credit-based entertainment platform where creators post real-world challenges and their audience joins with platform credits — built on an auditable integer ledger, automated moderation and a settlement engine that never touches floating-point math.

- Industry
- Creator economy / social entertainment
- Engagement
- Full-stack product build (backend + web app)
Heads Up lets any user become a creator, open a Room and post challenges their audience joins with platform credits. Two formats run side by side: a parimutuel prediction format where participants pick among 2–5 outcomes, and a submission format where participants pay an entry fee and upload photo or video entries judged into a placement table. Every credit that moves is written to an immutable ledger, every uploaded video passes automated moderation, and the platform commission is split with monetized creators at a configurable rate.
The product is deliberately not a gambling application. Credits carry no cash value, cannot be withdrawn and never leave the system except through challenge outcomes. That constraint shaped the domain language, the API surface and the compliance posture of the entire build.
What we were up against
- A financial ledger that could not be allowed to drift. Credits move between thousands of participants on every settlement, with a platform commission, a creator revenue share and rounding remainders on top. A single cent of drift, compounded across settlements, would have made balances unreconcilable and every payout receipt unprovable.
- Two economically different formats sharing one wallet. Predictive challenges redistribute a losing pool proportionally to winners. Submission challenges collect entry fees and pay a fixed placement table. Both needed to draw from the same balance, produce the same audit trail and expose the same receipt format without one format's rules leaking into the other.
- User-generated video at the center of the product. Participants upload video entries and video comments. Publishing unmoderated media is a legal and platform-safety non-starter, but blocking every upload behind a synchronous review call would have made the product unusable.
- Outcomes that must resolve fairly when nobody is watching. Challenges lock on a deadline whether or not the creator shows up. Left unresolved, participants' credits sit frozen indefinitely. The system needed to close, resolve, pay out and refund on its own: correctly, and exactly once.
How we solved it
- An integer-only ledger with row-level locking. Credits are stored as integer minor units at four decimal places, with no floats anywhere in the money path. Every mutation acquires a SELECT FOR UPDATE row lock on the wallet, enforces a non-negative balance and writes an immutable transaction row carrying the resulting balance and a structured reference ID. Rounding dust from proportional splits is deterministically assigned to the largest participant rather than silently discarded.
- Settlement as a pure function. The parimutuel engine is a database-free function: it takes stakes, declared outcomes, a commission rate and a creator share, and returns payout lines, fee splits and dust, all in integer arithmetic. Orchestration (locking rows, writing payouts, crediting wallets) sits outside it. This made the hardest logic in the product exhaustively testable in milliseconds, including void paths, split ties, one-sided pools and creator-funded deposits.
- Asynchronous moderation with a fail-closed default. Uploads are accepted immediately and queued to Celery, where video is scored against a multi-headed visual-moderation API and links are checked against Google Web Risk. Flagged media is removed and its body redacted; a child-safety escalation path marks the review critical and logs it for human handling. Thresholds and flagged classes are environment-tunable against stored provider responses, so policy changes require no deploy.
- Scheduled lifecycle tasks that own the clock. Periodic Celery tasks lock expired challenges, auto-resolve community-voted outcomes, auto-finalize submission challenges after a grace window, refund creator deposits on void and award badges. Each is idempotent and guarded by explicit precondition checks rather than by catching database constraint violations, so a retry or overlapping run cannot double-pay.
Measurable impact
- A ledger that reconciles by construction. Integer minor units, mandatory row locks and an append-only transaction log mean every balance in the system is derivable from its history. Any participant can pull a per-challenge receipt showing pool size, commission, creator share and their own line.
- 816 automated tests, concentrated on the money path. Settlement, staking, finalization and wallet mutation are covered against void, tie, single-sided and refund scenarios. Regressions in the highest-risk code surface in CI, not in production balances.
- Moderation that scales without a human queue. Video and link review run entirely in the background with retry and backoff. The product ships user-generated media without a reviewer in the loop, while keeping a full provider-response audit trail for threshold tuning and escalation.
- Two challenge economies on one platform. Predictive and submission formats run in parallel with independent commission rates, independent lifecycle rules and a shared wallet, ledger and receipt surface, so new formats can be added without reopening the financial core.
Under the hood
- Backend Django 5.2 and Django REST Framework across 12 domain modules (users, creators, wallet, payments, challenges, submit challenges, engagement, badges, stats, files, observability, common). Business logic lives in dedicated service classes, never in views or serializers; Django signals are banned outright so every side effect is traceable to an explicit call. 100% type annotation coverage, enforced in pre-commit.
- Data PostgreSQL 16. Money as PositiveBigIntegerField minor units, database-level uniqueness and check constraints for domain invariants, and explicit .exists() preconditions instead of exception-driven business rules.
- Async Celery 5 on Redis for moderation, link validation, challenge locking, auto-finalization, badge issuance and orphaned-file cleanup.
- Frontend Next.js 16 with React 19, TypeScript and Tailwind 4, across 49 routes. A repository layer abstracts every API call behind an interface, with mock implementations that let the UI be built and demoed ahead of the endpoints backing it.
- Integrations Stripe Checkout with signed, idempotent webhooks for credit purchase; AWS S3 with presigned URLs for media; TheHive.ai for visual moderation; Google Web Risk for link safety; Sentry plus structured JSON logging with X-Request-ID correlation across HTTP and Celery.
- Delivery Docker Compose on AWS EC2, GitHub Actions CI/CD, CloudWatch log aggregation, Flower for queue visibility.
What we used
- Python
- Django
- Django REST Framework
- PostgreSQL
- Celery
- Redis
- Next.js
- React
- TypeScript
- Tailwind CSS
- Stripe
- AWS EC2
- AWS S3
- Docker
- GitHub Actions
- Sentry
- AI Content Moderation
- OpenAPI