← Wszystkie case studies
Produkt cyfrowy · Creator economy

Wyzwania twórców na księdze, która zawsze się zgadza.

Platforma rozrywkowa oparta na kredytach: twórcy publikują realne wyzwania, a widownia bierze udział za kredyty platformy. Pod spodem audytowalna księga na liczbach całkowitych, automatyczna moderacja i silnik rozliczeń bez ani jednej operacji zmiennoprzecinkowej.

Wyzwania twórców na księdze, która zawsze się zgadza.
>20 minśredni czas spędzony w aplikacji
12niezależnych modułów domenowych
0operacji zmiennoprzecinkowych w rozliczeniach
75+endpointów REST udokumentowanych w OpenAPI
~27klinii Pythona bez migracji
~21klinii TypeScript w 49 trasach
Branża
Creator economy / rozrywka społecznościowa
Zakres
Pełna budowa produktu (backend + aplikacja web)

Heads Up pozwala każdemu użytkownikowi zostać twórcą, otworzyć Room i publikować wyzwania, do których widownia dołącza za kredyty platformy. Równolegle działają dwa formaty: predykcyjny w modelu parimutuel, gdzie uczestnicy wybierają jeden z 2–5 wyników, oraz format zgłoszeń, gdzie uczestnicy płacą wpisowe i przesyłają zdjęcia lub wideo oceniane do tabeli miejsc. Każdy ruch kredytów trafia do niezmiennej księgi, każde przesłane wideo przechodzi automatyczną moderację, a prowizja platformy jest dzielona z monetyzowanymi twórcami według konfigurowalnej stawki.

Produkt celowo nie jest aplikacją hazardową. Kredyty nie mają wartości pieniężnej, nie można ich wypłacić i nigdy nie opuszczają systemu inaczej niż przez wyniki wyzwań. To ograniczenie ukształtowało język domeny, powierzchnię API i postawę compliance całej budowy.

Z czym się mierzyliśmy

  • Księga finansowa, która nie mogła się rozjechać. Przy każdym rozliczeniu kredyty przepływają między tysiącami uczestników, a do tego dochodzi prowizja platformy, udział twórcy i reszty z zaokrągleń. Jeden cent rozjazdu, skumulowany przez kolejne rozliczenia, uczyniłby salda nieuzgadnialnymi, a każde potwierdzenie wypłaty niemożliwym do udowodnienia.
  • Dwa ekonomicznie różne formaty na jednym portfelu. Wyzwania predykcyjne rozdzielają pulę przegranych proporcjonalnie między wygranych. Wyzwania ze zgłoszeniami zbierają wpisowe i wypłacają stałą tabelę miejsc. Oba musiały korzystać z tego samego salda, zostawiać ten sam ślad audytowy i zwracać ten sam format potwierdzenia, bez przeciekania reguł jednego formatu do drugiego.
  • Wideo od użytkowników w centrum produktu. Uczestnicy przesyłają zgłoszenia wideo i komentarze wideo. Publikowanie niemoderowanych mediów jest nie do przyjęcia prawnie i z punktu widzenia bezpieczeństwa platformy, ale blokowanie każdego uploadu synchroniczną weryfikacją uczyniłoby produkt bezużytecznym.
  • Wyniki, które muszą rozstrzygać się uczciwie, gdy nikt nie patrzy. Wyzwania blokują się na deadline niezależnie od tego, czy twórca się pojawi. Nierozstrzygnięte zamrażają kredyty uczestników na czas nieokreślony. System musiał sam zamykać, rozstrzygać, wypłacać i zwracać: poprawnie i dokładnie raz.

Jak to rozwiązaliśmy

  • Księga wyłącznie na liczbach całkowitych z blokadą na poziomie wiersza. Kredyty są przechowywane jako całkowite jednostki minorowe z czterema miejscami po przecinku, bez floatów gdziekolwiek na ścieżce pieniędzy. Każda mutacja zakłada blokadę SELECT FOR UPDATE na portfelu, wymusza nieujemne saldo i zapisuje niezmienny wiersz transakcji z wynikowym saldem i ustrukturyzowanym reference ID. Reszty z proporcjonalnych podziałów są deterministycznie przypisywane największemu uczestnikowi, a nie po cichu odrzucane.
  • Rozliczenie jako czysta funkcja. Silnik parimutuel to funkcja bez bazy danych: przyjmuje stawki, ogłoszone wyniki, stawkę prowizji i udział twórcy, a zwraca linie wypłat, podział opłat i reszty, wszystko w arytmetyce całkowitej. Orkiestracja (blokowanie wierszy, zapis wypłat, zasilanie portfeli) jest poza nią. Najtrudniejsza logika produktu stała się wyczerpująco testowalna w milisekundach, włącznie z unieważnieniami, remisami, jednostronnymi pulami i depozytami twórców.
  • Asynchroniczna moderacja z domyślnym fail-closed. Uploady są przyjmowane natychmiast i kolejkowane do Celery, gdzie wideo ocenia wielogłowe API moderacji wizualnej, a linki sprawdza Google Web Risk. Oflagowane media są usuwane, a ich treść redagowana; ścieżka eskalacji dla bezpieczeństwa dzieci oznacza przegląd jako krytyczny i loguje go do obsługi przez człowieka. Progi i flagowane klasy są konfigurowalne przez środowisko na zapisanych odpowiedziach dostawcy, więc zmiana polityki nie wymaga deployu.
  • Zaplanowane zadania cyklu życia, które pilnują zegara. Okresowe zadania Celery blokują przeterminowane wyzwania, automatycznie rozstrzygają wyniki głosowane przez społeczność, finalizują wyzwania ze zgłoszeniami po okresie karencji, zwracają depozyty twórców przy unieważnieniu i przyznają odznaki. Każde jest idempotentne i chronione jawnymi sprawdzeniami warunków wstępnych zamiast łapania naruszeń ograniczeń bazy, więc powtórka lub nakładające się uruchomienie nie wypłaci dwa razy.

Mierzalny efekt

  • Księga, która uzgadnia się z konstrukcji. Całkowite jednostki minorowe, obowiązkowe blokady wierszy i dziennik transakcji append-only sprawiają, że każde saldo w systemie wynika z jego historii. Każdy uczestnik może pobrać potwierdzenie per wyzwanie z wielkością puli, prowizją, udziałem twórcy i własną linią.
  • 816 testów automatycznych skupionych na ścieżce pieniędzy. Rozliczenie, stawianie, finalizacja i mutacje portfela są pokryte scenariuszami unieważnienia, remisu, jednostronnej puli i zwrotu. Regresje w najbardziej ryzykownym kodzie wychodzą w CI, nie na saldach produkcyjnych.
  • Moderacja, która skaluje się bez kolejki ludzi. Weryfikacja wideo i linków działa w całości w tle z powtórzeniami i backoffem. Produkt publikuje treści użytkowników bez recenzenta w pętli, zachowując pełny ślad audytowy odpowiedzi dostawcy do strojenia progów i eskalacji.
  • Dwie ekonomie wyzwań na jednej platformie. Format predykcyjny i format zgłoszeń działają równolegle z niezależnymi stawkami prowizji, niezależnymi regułami cyklu życia oraz wspólnym portfelem, księgą i potwierdzeniami, więc nowe formaty można dodawać bez otwierania rdzenia finansowego.

Pod maską

  • Backend Django 5.2 i Django REST Framework w 12 modułach domenowych (users, creators, wallet, payments, challenges, submit challenges, engagement, badges, stats, files, observability, common). Logika biznesowa żyje w dedykowanych klasach serwisów, nigdy w views czy serializers; Django signals są całkowicie zakazane, więc każdy efekt uboczny da się prześledzić do jawnego wywołania. 100% pokrycia adnotacjami typów, wymuszane w pre-commit.
  • Dane PostgreSQL 16. Pieniądze jako jednostki minorowe w PositiveBigIntegerField, unikalność i ograniczenia check na poziomie bazy dla inwariantów domeny oraz jawne warunki wstępne .exists() zamiast reguł biznesowych opartych na wyjątkach.
  • Async Celery 5 na Redis do moderacji, walidacji linków, blokowania wyzwań, autofinalizacji, przyznawania odznak i czyszczenia osieroconych plików.
  • Frontend Next.js 16 z React 19, TypeScript i Tailwind 4, 49 tras. Warstwa repozytoriów ukrywa każde wywołanie API za interfejsem, a implementacje mock pozwoliły budować i demonstrować UI przed gotowością endpointów.
  • Integracje Stripe Checkout z podpisanymi, idempotentnymi webhookami do zakupu kredytów; AWS S3 z presigned URL dla mediów; TheHive.ai do moderacji wizualnej; Google Web Risk do bezpieczeństwa linków; Sentry plus strukturalne logi JSON z korelacją X-Request-ID między HTTP i Celery.
  • Dostarczanie Docker Compose na AWS EC2, CI/CD w GitHub Actions, agregacja logów w CloudWatch, Flower do podglądu kolejek.

Czego użyliśmy

  • 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
Twój projekt

Masz proces wart usprawnienia?

Pokaż, co dzieje się dziś. Pomożemy określić, co powinno się zmienić i co warto zbudować.

Omów projekt