This project features an HTTP REST API for player management, developed with an Express.js server using TypeScript. The API allows users to perform various actions, including listing players, adding new players, initiating battles between players, and getting attack logs within a battle.
Table of Contents (click to expand)
Please ensure that you have Node.js 20 and pnpm installed for local development. Alternatively, you can use Docker to run the application in a containerized environment using the included compose file, which eliminates the need for local Node.js and pnpm installations.
-
Clone the repository
git clone https://github.com/askmrsinh/business-lookup business-lookup cd business-lookup
-
Install dependencies:
pnpm install
Run migrations and seed the database:
npx mikro-orm migration:fresh && npx mikro-orm seeder:run
To run the application in development mode (watch mode):
pnpm start:dev
The server will be available at http://localhost:3000
.
Lists all players with all the details of each player.Z
[
{
"id": "912cb35e-a7f5-46a7-bd75-90f46a7e911c",
"createdAt": 1726593308147,
"name": "Player A",
"gold": 1000000,
"attack": 98,
"hit": 55,
"luck": 40
},
{
"id": "ad8c1dfd-5143-4dd5-950d-7ee120b39e4a",
"createdAt": 1726593308150,
"name": "Player B",
"gold": 1000000,
"attack": 98,
"hit": 68,
"luck": 86
}
]
Adds a player to the database, only 'name' of the player is user provided, other fields are randomly assigned.
{
"name": "Batman"
}
{
"id": "03b5aef8-2aea-41fc-9fef-5f4dad8e996a",
"createdAt": 1726593328519,
"name": "Batman",
"gold": 1000000,
"attack": 17,
"hit": 44,
"luck": 92
}
Lists all the battles
Initiates a battle between two players using their UUIDs.
{
"from": "912cb35e-a7f5-46a7-bd75-90f46a7e911c",
"to": "ad8c1dfd-5143-4dd5-950d-7ee120b39e4a"
}
TODO: Fix the response structure. It's too verbose to include in this README.
Lists attacks that were a part of the given battle
{
"id": "843719db-1ef4-4b78-9629-b688c5ff0473",
"createdAt": 1726594628433,
"from": "912cb35e-a7f5-46a7-bd75-90f46a7e911c",
"to": "ad8c1dfd-5143-4dd5-950d-7ee120b39e4a",
"isFinished": true,
"attacks": [
{
"id": "356ce03f-63e5-4a62-8590-6844d343c176",
"createdAt": 1726594628444,
"battle": "843719db-1ef4-4b78-9629-b688c5ff0473",
"attacker": "912cb35e-a7f5-46a7-bd75-90f46a7e911c",
"damage": 53.9
},
{
"id": "2d84a6c7-c394-4fd6-8f22-7c0e19d60a9f",
"createdAt": 1726594628557,
"battle": "843719db-1ef4-4b78-9629-b688c5ff0473",
"attacker": "ad8c1dfd-5143-4dd5-950d-7ee120b39e4a",
"damage": 0
},
{
"id": "38ea21b2-a4e5-4e72-a814-c5d2af223d7c",
"createdAt": 1726594628573,
"battle": "843719db-1ef4-4b78-9629-b688c5ff0473",
"attacker": "912cb35e-a7f5-46a7-bd75-90f46a7e911c",
"damage": 0
},
{
"id": "58dc14d9-345b-4541-9568-26a6cf428dee",
"createdAt": 1726594628588,
"battle": "843719db-1ef4-4b78-9629-b688c5ff0473",
"attacker": "ad8c1dfd-5143-4dd5-950d-7ee120b39e4a",
"damage": 49
},
{
"id": "edf5308a-0cdf-4715-ae2e-257c8463098b",
"createdAt": 1726594628603,
"battle": "843719db-1ef4-4b78-9629-b688c5ff0473",
"attacker": "912cb35e-a7f5-46a7-bd75-90f46a7e911c",
"damage": 0
},
{
"id": "67a04dda-0a1c-4e2f-bbf0-378d2deb197e",
"createdAt": 1726594628617,
"battle": "843719db-1ef4-4b78-9629-b688c5ff0473",
"attacker": "ad8c1dfd-5143-4dd5-950d-7ee120b39e4a",
"damage": 49
}
]
}
Some request validation is implemented using class validator package with the player's controller file. An example request and response is given below, similar pattern can be extended to other api endpoints.
Example:
POST /players
{
"name": "Hi"
}
{
"error": {
"name": [
"name must be longer than or equal to 3 characters"
]
}
}
pnpm start
: Initializes the Database and start the application in production modepnpm start:dev
: Start the application in development (watch) modepnpm start:prod
: Start the application in production modepnpm test
: Run testspnpm lint
: Check code style with Prettier and ESLintpnpm format
: Format code with Prettier
- Express.js
- TypeScript
- MikroORM
- SQLite
- class-validator (for request validation)
- class-transformer (for request deserialization)
- Pino (for logging)
- Jest (for testing) - not implemented
The project uses a typical Express.js structure with TypeScript. Key files and directories include:
server.ts
: Main application fileapp/
: Contains application logiccontrollers/
: API route handlersentities/
: Database entity definitionsseeders/
: Database seedersdtos/
: Request deserialization and validation
-
Player Table: This table stores comprehensive information about each player and is used to perform all basic CRUD (Create, Read, Update, Delete) operations on player data.
-
Battles Table: This table records the details of each battle, including the participants — attacker and defender. The player who initiates the battle is recorded as the attacker.
-
Attacks Table: This table captures the details of each attack, linked to the corresponding battle through a battle ID. It represents a one-to-many relationship, where each battle can have multiple attack entries. This table is used to retrieve all attacks that occurred during a specific battle.
-
Player State Table: This table saves teh health state of the players in a battle after each attack.
// TODO
pnpm test
- Implement request validation for all endpoints
- Restructure the response for
battles
endpoint - Implement logic for reducing looser's gold
- Cleanup the battle engine logic (
app/repositories/battle.repository.ts
)