This project is a dice betting API built as part of the Technical Test at AG for Senior Backend Engineer Position. It allows to place bets and calculates payouts based on a random chance, also query users and bets. The API is built using NestJS, GraphQL, TypeScript, Sequelize, and includes PostgreSQL for database management and Redis for distributed locks.
- TypeScript
- NestJS
- GraphQL
- Sequelize
- PostgreSQL
- Redis
- Docker
-
Clone the repository:
git clone https://github.com/agustintosco/ag-api-assignment
-
Navigate to the project directory:
cd ag-api-assignment
-
Run this command:
This command will set up the app, the PostgreSQL database, and a Redis server.
npm run start:app
- Requirements:
- docker
- docker-compose
Once the server is running, you can access the GraphQL Playground at:
http://localhost:3000/graphql
-
getBetList: Retrieves a paginated list of bets.
- Arguments:
first
(Int, optional): The number of results to return.after
(String, optional): Cursor for pagination.
- Returns: A
Connection
object withedges
andpageInfo
for pagination.
Example query:
query { getBetList(first: 10, after: "cursorValue") { edges { node { id betAmount payout } } pageInfo { hasNextPage endCursor } } }
- Arguments:
-
getBet: Retrieves a specific bet by its ID.
- Arguments:
id
(Int): The ID of the bet.
- Returns: A Bet object with details of the bet.
Example query:
query { getBet(id: 1) { id betAmount win payout user { name } } }
- Arguments:
-
getBestBetPerUser: Retrieves the best bet for each user, with an option to limit the results.
- Arguments:
limit
(Int): The maximum number of users to return.
- Returns: A list of Bet objects representing the best bet for each user.
Example query:
query { getBestBetPerUser(limit: 5) { id payout user { name } } }
- Arguments:
-
getUser: Retrieves a specific user by their ID.
- Arguments:
id
(Int): The ID of the user.
- Returns: A User object.
Example query:
query { getUser(id: 1) { id name balance bets { chance win } } }
- Arguments:
-
getUserList: Retrieves a paginated list of users.
- Arguments:
limit
(Int, optional): The number of users to return (default is 10).offset
(Int, optional): The number of users to skip for pagination.
- Returns: A list of User objects and a boolean indicating if there's a next page.
Example query:
query { getUserList(limit: 10, offset: 0) { users { id name balance bets { payout chance } } hasNextPage } }
- Arguments:
-
createBet: Creates a new bet for a user.
- Arguments:
userId
(Int): The ID of the user placing the bet.betAmount
(Float): The amount of money being bet.chance
(Float): The chance (probability) of winning, passed as a decimal.
- Returns: The created Bet object.
Example mutation:
mutation { createBet(userId: 1, betAmount: 100.0, chance: 0.5) { id betAmount win payout } }
- Arguments:
- Basic Unit Tests were added for
UserService
andBetService
to ensure that main logic works correctly. - To run the unit tests:
npm run test
- For simplicity no repository separated classes were used.
- Basic error mapping for covering possible errors.
- Add ORDER BY to cursor-paginated resolvers to ensure correct results.
- Add filtering and sorting to list Queries.
- Add integration and end-to-end tests.
- Implement user authentication and authorization to restrict access to the API.
- Add advanced error handling and custom error messages for better user experience.
- Include global logger.