Girowin: a real-money gaming platform
How I structured Girowin's platform: NestJS services per domain, a wallet with an idempotent ledger, messaging with RabbitMQ and operation across replicas.

1. Context & Engineering Challenge
Girowin is an online gaming platform with casino, original games, live casino, a wallet, promotions, affiliates and KYC, run from a full back office. I'm the CTO and built the architecture and much of the backend. On a platform like this every cent has to be right: the same deposit can never become balance twice, a bet can never be debited twice and the history must match the balance, even with providers resending callbacks and queues redelivering messages.
The problems that shaped the architecture: • Game providers and payment gateways resend calls; the queue redelivers messages. • Many concurrent bets on the same wallet. • Scheduled jobs running on several replicas at once. • Integrations with different requirements, including a fixed outbound IP. • A back office that needs to see everything: finance, risk, KYC and CRM.
2. Decisions
The main decisions: • Services per domain: auth, casino, gaming, payment, affiliates, communication and CRM, in a NestJS monorepo, each with its own PostgreSQL database. • Idempotent credits: every credit carries the id of its source movement as a key, and a resend returns the original receipt. • Wallet ledger, currently rolling out: every movement records the balance before and after in the same transaction that changes the balance, with a unique key per wallet, kind and external id. • Explicit concurrency: bet debits with FOR UPDATE and withdrawals with an advisory lock per withdrawal and a debit receipt. • Events between services over RabbitMQ, with the client hardened against channel failures. • Workers separate from the API (web and worker roles), with crons coordinated by a Redis lease. • An outbound proxy with a fixed IP for providers that require an allowlist.