MAG Interactive: New Leonardo
The main reason for being hired at MAG was to help update the Leonardo frontend tool, which is used by the game teams and player support to create and manage our different games.
Old Leonardo was a Java solution that was hard to maintain and update, so the decision was made to create a new tool from scratch.
Leonardo is a large application, with functions to handle player information, in-game offers, products, and purchases, A/B-test, game, and server settings, and a host of other things.
What I needed to do was to make the tool easier to use for all the different roles that use it, make it easier to maintain and update, and make it harder to do things the wrong way.
The application
It was decided that Leonardo should be a web application, but apart from that, I had free hands to decide how to build it. Since I had prior experience with Next.js, I decided to use that as the base for the application, as I would have access to both server and client side rendering, and I could use TypeScript for type safety.
For styling, I decided to use css-modules, but later on moved to Tailwind and DaisyUI.
Hosting and builds
The backend infrastructure is hosted on Google Cloud, so hosting the frontend there as well was a natural choice. Using Google Cloud also lets us use Google IAP for authentication.
The code is hosted on GitHub, and we use GitHub actions for building and deploying the application. Semantic versioning is used to handle versioning, together with a semantic-release GitHub action.
For development, we have a test-server set up with a GitHub actions workflow that builds and deploys the application when anything is pushed to the develop
-branch. For production, we have a similar setup, flow for the main
-branch, but deploying to several environments pointing to different databases.
Leonardo can also be pointed to different versions of the DaVinci API, which is good for testing new features.
APIs
The game APIs, aptly named DaVinci, are written in Java and used by both games and Leonardo. We import the OpenAPI specs and generate Tanstack Query-hooks for the different endpoints using a Deno script, as well as generating TypeScript types and API functions to be used on the server.
We use JWTs to authenticate the users to the API.
Features
Leonardo can be divided into a few main parts:
Player support
All tools used to handle player support.
- Player search and information
- Player clan search and information
- Reported players
BI systems
The area for the business intelligence team.
- A/B-test setup and maintenance
- Tagging of players
- Player segments
Game systems
All settings that a game team needs to handle their game.
- In-game offers, products, items, and currencies
- Handling game events
- Statistics
- Multiplayer room templates and settings
- Game settings
- Game-specific AB-tests and segments
Server admin
This is only used by the server team.
- Server settings and tools
- Internal users
Content handling
- Profanity word lists
- Internal ads
Integrations and libraries
- Next.js for routing and server side rendering
- React Query for fetching data on the client side
- Formik and formidable for form handling
- Yup for form validation
- Jest and React testing linrary for testing
- Tailwind and DaisyUI for styling and components
- Google FireStore for storing data
- Axios for API calls
- CodeMirror for JSON editing
- FullCalendar for calendar views
- Diff2Html and just-diff for showing diffs
We also use a host of libraries for development UX, such as Prettier, ESLint, Husky, Plop, and TypeScript.