A ConnectRPC-based betting service that handles various types of betting pools including win, place, each way, quinella, double, trifecta, and quaddie bets.
- Multiple Pool Types: Support for win, place, each way, quinella, double, trifecta, quaddie, exotic, and compound betting pools
- Business Rule Validation: Configurable rules for minimum bet amounts, bet increments, required legs, and maximum selections
- Atomic Transactions: Database operations are performed atomically to ensure data consistency
- ConnectRPC API: Modern gRPC-compatible API with HTTP/1.1 and HTTP/2 support
- Comprehensive Validation: Validates bet structure, business rules, and data integrity
The service uses three main tables:
- bets: Stores bet metadata with external references
- transactions: Stores bet details including stake, combinations, and status
- bet_selections: Stores individual selections for each bet
- BetService: Main ConnectRPC service implementation
- BetValidator: Validates bets against business rules
- PoolRulesService: Manages pool-specific business rules
- BetRepository: Handles database operations
- Go 1.21+
- PostgreSQL 15+
- Docker and Docker Compose (optional)
- Clone the repository and navigate to the bets directory
- Start the services:
make docker-up
This will start:
- PostgreSQL database on port 5432
- Bet service on port 8080
-
Start PostgreSQL and create the database:
CREATE DATABASE bets;
-
Run the database schema:
psql -d bets -f db-design.sql
-
Set environment variables:
export DB_HOST=localhost export DB_PORT=5432 export DB_USER=postgres export DB_PASSWORD=password export DB_NAME=bets export DB_SSLMODE=disable export SERVER_ADDR=:8080
-
Generate proto files and run the service:
make proto make dev
req := &betv1.CreateBetRequest{
ExternalReference: "WIN-001",
PoolId: 1, // Win pool
Stake: 10.0,
CustomerId: "customer-123",
Selections: []*betv1.BetSelection{
{
Position: 1,
SelectionId: 5,
LegNumber: 1,
CombinationCount: 1,
},
},
}req := &betv1.CreateBetRequest{
ExternalReference: "QUAD-001",
PoolId: 7, // Quaddie pool
Stake: 20.0,
CustomerId: "customer-456",
Selections: []*betv1.BetSelection{
{
Position: 1,
SelectionId: 3,
LegNumber: 1,
CombinationCount: 1,
},
{
Position: 1,
SelectionId: 7,
LegNumber: 2,
CombinationCount: 1,
},
{
Position: 1,
SelectionId: 2,
LegNumber: 3,
CombinationCount: 1,
},
{
Position: 1,
SelectionId: 9,
LegNumber: 4,
CombinationCount: 1,
},
},
}| Pool Type | Pool ID | Required Legs | Max Selections/Leg | Description |
|---|---|---|---|---|
| WIN | 1 | 1 | 1 | Single selection to win |
| PLACE | 2 | 1 | 1 | Single selection to place |
| EACH_WAY | 3 | 1 | 1 | Win and place combination |
| QUINELLA | 4 | 1 | 2 | First two in any order |
| DOUBLE | 5 | 2 | 1 | Two consecutive wins |
| TRIFECTA | 6 | 1 | 3 | First three in exact order |
| QUADDIE | 7 | 4 | 1 | Four consecutive wins |
| EXOTIC | 8 | 1 | 10 | Flexible exotic bet |
| COMPOUND | 9 | 2+ | 5 | Multiple leg combinations |
- Minimum Bet: $1.00
- Bet Increment: $1.00 multiples only
- Maximum Bet: $1,000.00 (configurable per pool)
- Validation: All bets are validated against pool-specific rules
Run the example client to test the service:
# Start the service
make dev
# In another terminal, run the client
go run ./cmd/clientmake build- Build the applicationmake run- Run the applicationmake test- Run testsmake proto- Generate proto filesmake dev- Run in development modemake docker-up- Start with Docker Composemake docker-down- Stop Docker Compose services
bets/
├── cmd/
│ ├── server/ # Main server application
│ └── client/ # Example client
├── gen/ # Generated proto files
├── internal/
│ ├── model/ # Data models
│ ├── repository/ # Database operations
│ ├── service/ # Business logic
│ └── validator/ # Validation logic
├── proto/ # Protocol buffer definitions
├── db-design.sql # Database schema
├── docker-compose.yml # Docker services
└── Makefile # Build commands
The service returns appropriate ConnectRPC error codes:
INVALID_ARGUMENT: Validation errors, malformed requestsNOT_FOUND: Bet not foundINTERNAL: Database or internal server errors
- Database migrations
- Bet settlement and payout logic
- Real-time odds integration
- Customer balance management
- Bet history and reporting
- Rate limiting and throttling
- Metrics and monitoring