Skip to content

Camilo716/game-store

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Epic 1 - Admin Panel with Services

Before you started

The task requires .NET 8 SDK installed. You can find project configuration requerarments in this file

General requirements

System should support the following features:

  • Get game by key.
  • Get games by genre.
  • Get games by platform.
  • Download a game file.
  • CRUD for games.
  • CRUD for genres.
  • CRUD for platforms.
  • Global error handling.

Technical specifications:

  • Use the latest stable version of ASP.NET CORE (MVC template).  
  • N-layer architecture should be used.
  • Use a built-in service provider. 
  • Use SOLID principles.
  • Use JSON as response/request format.  
  • Use MS SQL Server. 

Entities

Game:

  • Id: Guid, required, unique
  • Name: String, required
  • Key: String, required, unique
  • Description: String, optional

Genre:

  • Id: Guid, required, unique
  • Name: String, required, unique
  • ParentGenreId: Guid, optional

Platform:

  • Id: Guid, required, unique
  • Type: String, required, unique

GameGenre:

  • GameId: Guid, required.
  • GenreId: Guid, required.

Game-Genre combinations are unique.

GamePlatform:

  • GameId: Guid, required.
  • PlatformId: Guid, required

Game-Platform combinations are unique.

Additional requirements

Game key It is a short unique name of the game that can be used for creating user-friendly routes The key can be entered manually. If the key is not entered manually – then it must be generated automatically based on the game name. Game File It is an autogenerated .txt file with “_” prefix in the name and serialized game as content. Predefined Genres The system should contain predefined genres and subgenres: Strategy RTS  TBS RPG Sports Races Rally Arcade Formula Off-road Action FPS   TPS Adventure Puzzle & Skill

Predefined platforms

The system should contain predefined platforms:

  • Mobile
  • Browser
  • Desktop
  • Console

Task Description

Please use the following CI with pipelines, quality gate by code style, and unit-tests coverage for your project:

CI.zip

US1E1 - User story 1

Add a new Game endpoint

Url: /games
Type: POST 
Request Example:
{
  "game": {
    "name": "Super game name",
    "key": "gameKey",
    "description": "Some text"
  },
  "genres": [
    "7c9c7b90-363f-487a-bc08-0e9a31e60d2e",
    "acd05e04-a8df-4d6f-9369-b6d6bd40e1ee"
  ],
  "platforms": [
    "34df8f15-ca69-4c44-949a-f53ca4929a72"
  ]
}

US2E1 - User story 2

Get game by key endpoint

Url: /games/{key}
Type: GET
Response example:
{
  "id": "15d9da6c-1f12-483d-b4ea-97f661c2ce0e",
  "description": "Some text",
  "key": "gameKey",
  "name": "Super game name"
}

Get game by id endpoint

Url: /games/find/{id}
Type: GET
Response example:
{
  "id": "0146978c-cf50-45cd-8949-605938f920a9",
  "description": "string",
  "key": "string",
  "name": "string"
}

Get games by platform endpoint

Url: /platforms/{id}/games
Type: GET
Response example:
[
  {
    "id": "777d5792-3602-423a-8e8d-272a9a22b0fc",
    "description": null,
    "key": "Game1",
    "name": "Game1"
  },
  {
    "id": "4883afcf-3c66-4d44-a622-b8d5d6ced8df",
    "description": null,
    "key": "Game2",
    "name": "Game2"
  }
]

Get games by genre endpoint

Url: /genres/{id}/games
Type: GET
Response example:
[
  {
    "id": "777d5792-3602-423a-8e8d-272a9a22b0fc",
    "description": null,
    "key": "Game1",
    "name": "Game1"
  },
  {
    "id": "4883afcf-3c66-4d44-a622-b8d5d6ced8df",
    "description": null,
    "key": "Game2",
    "name": "Game2"
  }
]

US3E1 - User story 3

Update a Game endpoint

Url: /games
Type: PUT
Request example:
{
  "game": {
    "name": "New name",
    "key": "newkey",
    "description": "Updated desc",
    "id": "15d9da6c-1f12-483d-b4ea-97f661c2ce0e"
  },
  "genres": [
    "15d9da6c-1f12-483d-b4ea-97f661c2ce0e"
  ],
  "platforms": [
    "61bf29f3-d7f0-4afe-a283-f4c7d8865d96"
  ]
}

US4E1 - User story 4

Delete a Game endpoint

Url: /games/{key}  
Type: DELETE  

US5E1 - User story 5

Download a Game endpoint

Url: /games/{key}/file
Type: GET
Result: file downloading is started

US6E1 - User story 6

Get All games endpoint

Url: /gamesType: GET
Response example:
[
  {
    "id": "0146978c-cf50-45cd-8949-605938f920a9",
    "description": "string",
    "key": "string",
    "name": "string"
  },
  {
    "id": "777d5792-3602-423a-8e8d-272a9a22b0fc",
    "description": null,
    "key": "Game1",
    "name": "Game1"
  },
  {
    "id": "4883afcf-3c66-4d44-a622-b8d5d6ced8df",
    "description": null,
    "key": "Game2",
    "name": "Game2"
  },
  {
    "id": "15d9da6c-1f12-483d-b4ea-97f661c2ce0e",
    "description": "Updated desc",
    "key": "newkey",
    "name": "New name"
  }
]

US7E1 - User story 7

Add a new Genre endpoint

Url: /genres
Type: POST
Request example:
{
  "genre": {
    "name": "Sub genre",
    "parentGenreId": "ed1ecab9-358a-4c19-9ab7-6031bda097a9"
  }
}

US8E1 - User story 8

Get genre by id endpoint

Url: /genres/{Id}
Type: GET
Response Example:
{
  "id": "f668ed18-b5f5-41df-b48d-a9ec6451d55d",
  "name": "genre name 2",
  "parentGenreId": null
}

Get all genres endpoint

Url: /genres
Type: GET
Response Example:
[
  {
    "id": "ed1ecab9-358a-4c19-9ab7-6031bda097a9",
    "name": "string"
  },
  {
    "id": "334b000f-0f8b-417f-b7da-e4549f0f0518",
    "name": "genre name"
  },
  {
    "id": "f668ed18-b5f5-41df-b48d-a9ec6451d55d",
    "name": "genre name 2"
  },
  {
    "id": "2420ef87-c5ff-4354-91e7-b768a4ec3e8b",
    "name": "Sub genre"
  }
]

Get genres by game key endpoint

Url: /games/{key}/genres
Type: GET
Response Example:
[
  {
    "id": "ed1ecab9-358a-4c19-9ab7-6031bda097a9",
    "name": "string"
  }
]

Get genres by parent id endpoint

Url: /genres/{id}/genres
Type: GET
Response Example:
[
  {
    "id": "2420ef87-c5ff-4354-91e7-b768a4ec3e8b",
    "name": "Sub genre"
  }
]

US9E1 - User story 9

Update a Genre endpoint

Url: /genres
Type: PUT
Request Example:
{
  "genre": {
    "id": "ed1ecab9-358a-4c19-9ab7-6031bda097a9",
    "name": "Updated Name",
    "parentGenreId": null
  }
}

US10E1 - User story 10

Delete a Genre

Url: /genres/{Id}
Type: Delete

US11E1 - User story 11

Create a new Platform endpoint

Url: /platforms
Type: POST
Request example:
{
  "platform": {
    "type": "Platform Name"
  }
}

US12E1 - User story 12

Get platform by id endpoint

Url: /platforms/{Id}
Type: GET
Response Example:
{
  "id": "b763be02-652c-4d89-9a65-ec1f1c4106f2",
  "type": "Updated Name"
}

Get all platforms endpoint

Url: /platforms
Type: GET
Response Example:
[
  {
    "id": "61bf29f3-d7f0-4afe-a283-f4c7d8865d96",
    "type": "string"
  },
  {
    "id": "fdd7dae2-76d5-4ee6-ac97-3d21c3d0b41c",
    "type": "Platform Name"
  },
  {
    "id": "b763be02-652c-4d89-9a65-ec1f1c4106f2",
    "type": "Updated Name"
  }
]

Get platforms by game key endpoint

Url: /games/{key}/platforms
Type: GET
Response Example:
[
  {
    "id": "61bf29f3-d7f0-4afe-a283-f4c7d8865d96",
    "type": "string"
  }
]

US13E1 - User story 13

Update a Platform endpoint

Url: /platforms 
Type: PUT
Request example:
{
  "platform": {
    "id": "b763be02-652c-4d89-9a65-ec1f1c4106f2",
    "type": "Updated Name"
  }
}

US14E1 - User story 14

Delete a Platform endpoint

Url: /platforms/{Id}
Type: DELETE

US15E1 - User story 15

Implement global exception handling

Non-functional requirement (Optional)

NFR1E1 Repository and Unit of Work patterns should be implemented.
NFR2E1 Use the latest stable version of Microsoft Entity framework Core.
NFR3E1 Add GET endpoints responses caching for 1 minute. 

3.2. Owner Service

Implement the GetAccountOwnersTotalBalance method

Please use the following CI with pipelines, quality gate by code style, and unit-tests coverage for your project:

CI.zip

Epic 2 - Headers and Unit Testing

General requirements

System should support the following features:

  • Total Games count calculation.

Technical specifications:

  • Code coverage rate must be not lower than 50%.  
  • Use Moq package for test data mocks.
  • Use XUnit package for unit tests. 

E02 US1 - User story 1

Add x-total-numbers-of-games response header which represents the total games count in the system. A header should be added in each API response. Hint: The header should be exposed in Cors’s configuration. Example:

 content-type: application/json; charset=utf-8 
 date: Fri,17 Nov 2023 18:21:31 GMT 
 server: Kestrel 
 x-total-numbers-of-games: 4 

E02 US2 [Optional]

x-total-numbers-of-games header value should be cached for 1 minute

Non-functional requirement (Optional)

E02 NFR1 Cover application code with by Unit tests with coverage not lower than 50%.

Epic 3 - Logging and Swagger

General requirements

System should support the following features:

  • Inbound requests logging.
  • Error logging.
  • Swagger.

Technical specifications:

  • Use build-in logging infrastructure.  
  • Use a global exception handler for error logging.
  • .txt files should be used as log storage. 
  • A separate log file per day should be used. 

E03 US1 - User story 1

Add Swagger infrastructure. All endpoints should be accessible via the Swagger page.

E03 US2 - User story 2

Create user-friendly response message in case of error.

Non-functional requirement (Optional)

**E03 NFR1 ** Create a middleware for logging request details, logs should include the user IP Address, target URL, response status code, request content, response content, and elapsed time.

E03 NFR2 Add exception details logging, logs should include the exception type, exception message, inner exceptions, exception details, stack trace.

E03 NFR3 Implement a logging in file to store all logs produced by the application. Use a separate file for exception logs.

E03 NFR4[optional]   Add logs in main business layer methods.

Epic 5 - Payment methods

Extend the functionality of the Game Store by adding the ability to buy a game.

General requirements

Please use the following Angular Front-end: gamestore-ui-app You should use the following Microservice payment
System should support the following features:

  • Add game to cart.
  • Get games from cart.
  • Get orders.
  • Get payment methods.
  • Perform payment with the selected method.

Entities

Order

  • Id: Guid, required, unique
  • Date: DateTime, optional
  • CustomerId: Guid, required
  • Status: Enum, required

OrderGame

  • OrderId: Guid, required
  • ProductId: Guid, required
  • Price: Double, required
  • Quantity: Int, required
  • Discount: Int, optional

Product-Order combinations are unique.

Additional Requirements

Payment

Create a single endpoint for payment independently from the selected method.  
If the payment is processed successfully then the order must be marked as paid otherwise cancelled

Payment Methods

Allowed payment methods: “Bank”, “IBox terminal”, “Visa”.   
Only one method can be applied to an order to get paid.  
Each payment method contains a little picture (open-source pictures), title, short description.  

Customer

Since we don’t have users yet, for Customer Id use a stub value.

Bank payment date of validity

The date of validity – how long the invoice is valid. The value should be configurable by application settings.

Order limitations

User cannot order more games than available in the stock.

Order statuses

Any order has the next possible statuses:

  • Open – games are in the cart.
  • Checkout – payment is started.
  • Paid – payment is performed successfully.
  • Cancelled – payment is performed with errors.

Task Description

E05 US1 - User story 1

Add game in and delete from the cart Add game in the cart endpoint.

Url: /games/{key}/buy
Type: POST
Limitation: if the endpoint is called for the game which is already in the cart, then just increment the quantity
Response: Success status code

Delete game from cart endpoint

Url: /orders/cart/{key}
Type: DELETE
Response: Success status code

E05 US2 - User story 2

Get paid and cancelled orders endpoint.

Url: /orders
Type: GET
Response example:
[
  {
    "id": "5d8af81a-c146-4588-93bf-0e5c7e9e4a9e",
    "customerId": "5aa1c97e-e6b3-497c-8e00-270e96aa0b63",
    "date": "2023-11-20T11:03:26.0572863+02:00"
  },
  {
    "id": "bec0ffb1-fb80-47ff-8720-2f9a544a55a2",
    "customerId": "bfa70dfa-6b18-4f3f-b882-14af597396d4",
    "date": "2023-11-18T11:03:26.0575052+02:00"
  }
]

Get order by id endpoint.

Url: /orders/{id}
Type: GET
Response example:
{
  "id": "5d8af81a-c146-4588-93bf-0e5c7e9e4a9e",
  "customerId": "5aa1c97e-e6b3-497c-8e00-270e96aa0b63",
  "date": "2023-11-20T11:03:26.0572863+02:00"
}

E05 US3 - User story 3

Get order details endpoint.

Url: /orders/{id}/details
Type: GET
Response Example:
[
  {
    "productId": "8ea595c2-765b-4190-b3da-da00540b2202",
    "price": 100,
    "quantity": 3,
    "discount": 0
  },
  {
    "productId": "c3a73173-fe0f-4771-a7eb-f2cd458d8303",
    "price": 10,
    "quantity": 5,
    "discount": 0
  },
  {
    "productId": "923a8bd8-b256-44f4-b972-a0d640d56ef4",
    "price": 100,
    "quantity": 1,
    "discount": 10
  }
]

E05 US4 - User story 4

Get cart endpoint.

Url: /orders/cart
Type: GET
Hint: Cart is an order in the status Open, if such an order is not present in the database this should be created automatically during adding the first game to the cart. As a result, if the last game is deleted from the cart then the open order should be deleted automatically.
Response example:
[
  {
    "productId": "f6f698ee-41df-4594-b90c-3862e7d2cbee",
    "price": 30,
    "quantity": 1,
    "discount": 0
  },
  {
    "productId": "75396383-c1fa-4cbd-81c9-c874ae3a3e67",
    "price": 100,
    "quantity": 1,
    "discount": 20
  }
]

E05 US5 - User story 5

Get payment methods endpoint.

Url: /orders/payment-methods
Type: GET
Response Example:
{
  "paymentMethods": [
    {
      "imageUrl": "image link1",
      "title": "Bank",
      "description": "Some text 1"
    },
    {
      "imageUrl": "image link2",
      "title": "IBox terminal",
      "description": "Some text 2"
    },
    {
      "imageUrl": "image link3",
      "title": "Visa",
      "description": "Some text 3"
    }
  ]
}

E05 US6 - User story 6

"Bank" payment

Url: /orders/payment
Type: POST
Request: {"method":"Bank"} 
Flow: the system should return generated invoice file for download:
File type: PDF
The file content:
User ID
Order ID
Creation date
The date of validity – how long is the invoice is valid.
Sum

E05 US7 - User story 7

"IBox terminal" payment

Url: /orders/payment
Type: POST
Request: {"method":"IBox terminal"}
Integration: Integration with payment microservice is required 
Flow: The system should handle requests with an IBox payment. 
Response: should contain a user Id, invoice number (order ID), and sum.
Response Example:
{
  "userId": "24967e32-dec1-47b5-8ca6-478afa84c2be",
  "orderId": "7dce8347-4181-4316-9210-302361340975",
  "paymentDate": "2023-11-18T11:03:26.0575052+02:00",
  "sum": 100
}

E05 US8 - User story 8

"Visa" payment

Url: /orders/payment
Type: POST
Request:
{
  "method": "Visa",
  "model": {
    "holder": "Vitalii",
    "cardNumber": "123321122344231",
    "monthExpire": 10,
    "yearExpire": 2030,
    "cvv2": 111
  }
}
Integration: Integration with payment microservice is required 
Flow: The system should handle requests with card holder’s name, card number, Date of expiry (month and year), CVV2/CVC2
Response: Success status code.

Non-functional requirement

E05 NFR1
Microservice - an additional project that must be run locally and integrated with the game store api for Visa and IBox payments. You can investigate possible requests and results of microservice by calling the swagger endpoint.

E05 NFR2
Implement full tolerance payment acceptation. As the microservice that accepts iBox and card payments can reject up to 10 % of the transactions. A response validation must be implemented and an additional request must be sent in case of failure, the solution must be able to work with all responses of the Microservice.

Epic 9 - Authorization

General requirements

Please use the following Angular Front-end: gamestore-ui-app

Existing Authorization microservice

System should support the following features:

  • User Management
  • Login
  • Roles Management
  • Access by permissions

Additional Requirements

Roles

  • The system should have the next default roles: Administrator, Manager, Moderator, User, and Guest (not authorized).
  • Custom roles can be created additionally.
  • Multiple roles can be assigned to the user.

Admin

  • Can manage users and roles.
  • Can see deleted games.
  • Can manage comments for the deleted game.
  • Can edit a deleted game.

Manager

  • Can manage business entities: games, genres, publishers, platforms, etc.
  • Can edit orders.
  • Can view orders history.
  • Can’t edit orders from history.
  • Can change the status of an order from paid to shipped.
  • Can't edit a deleted game.

Moderator

  • Can manage game comments.
  • Can ban users from commenting.

User

  • Can`t see deleted games.
  • Can’t buy a deleted game.
  • Can see the games in stock.
  • Can comment game.

Guest

  • Has read-only access.

Comments

  • The username should be used as the commenter's name now.

Order history

  • Order history displays orders older than 30 days by default.

Default Roles hierarchy

Default Roles at the top inherit all accepts and limitations from roles below if other behavior is not specified in the role description.
Admin => Manager => Moderator => User => Guest

Task Description

E09 US1- User story 1

Login endpoint.

Url: /users/login
Type: POST
Request Example:
{
  "model": {
    "login": "UserName",
    "password": "SuperSecuredPassword",
    "internalAuth": true
  }
}

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}

E09 US2 - User story 2

Check page access endpoint.

Url: /users/access
Type: POST
Request Example:
{
  "targetPage": "Genre",
  "targetId": "84ea3383-08c2-48ba-9866-34c7e08e6e61"
}

E09 US3 - User story 3

Get all users endpoint.

Url: /users
Type: GET
Response Example:
[
  {
    "name": "Vitalii",
    "id": "454d4d01-406b-4a9b-9f8c-3fec63fc9266"
  },
  {
    "name": "John",
    "id": "80fbf934-45e7-49a8-8ae2-868a70bed2bf"
  }
]

E09 US4 - User story 4

Get user by id endpoint.

Url: /users/{id}
Type: GET
Response Example:
{
  "name": "Vitalii",
  "id": "a997674c-d34d-4074-81d2-fe27d739f55a"
}

E09 US5 - User story 5

Delete user by id endpoint.

Url: /users/{id}
Type: DELETE

E09 US6 - User story 6

Get all roles endpoint.

Url: /roles
Type: GET
Response Example:
[
  {
    "name": "Admin",
    "id": "529e960f-79c9-4e25-b3ef-a5ce8cbb42bc"
  },
  {
    "name": "Manager",
    "id": "765f9e20-fb70-4837-8b22-5d280ad9d2d2"
  }
]

E09 US7 - User story 7

Get role by id endpoint.

Url: /roles/{id}
Type: GET
Response Example:
{
  "name": "Admin",
  "id": "529e960f-79c9-4e25-b3ef-a5ce8cbb42bc"
}

E09 US8 - User story 8

Delete role by id endpoint.

Url: /roles/{id}
Type: DELETE

E09 US9 - User story 9

Add user endpoint.

Url: /users
Type: POST
Request Example:
{
  "user": {
    "name": "test"
  },
  "roles": [
    "529e960f-79c9-4e25-b3ef-a5ce8cbb42bc",
    "765f9e20-fb70-4837-8b22-5d280ad9d2d2"
  ],
  "password": "testpassword"
}

E09 US10 - User story 10

Update user endpoint.

Url: /users
Type: PUT
Request Example:
{
  "user": {
    "id": "9109858d-139b-4a13-a212-c3f6cf4ccc78",
    "name": "Vitalii"
  },
  "roles": [
    "765f9e20-fb70-4837-8b22-5d280ad9d2d2"
  ],
  "password": "updatedpassword"
}

E09 US11 - User story 11

Get user roles endpoint.

Url: /users/{id}/roles
Type: GET
Response Example:
[
  {
    "name": "Admin",
    "id": "484aeeeb-89d5-4ee7-b8c7-67c7d93292bb"
  },
  {
    "name": "Manager",
    "id": "548d6bec-635b-44ec-b719-baaf32758f12"
  }
]

E09 US12 - User story 12

Get permissions endpoint.

Url: /roles/permissions
Type: GET
Response Example:
[
  "AddGame",
  "DeleteGame",
  "ViewGame",
  "UpdateGame"
]

E09 US13 - User story 13

Get role permissions endpoint.

Url: /roles/{id}/permissions
Type: GET
Response Example: 
[
  "ViewGame",
  "UpdateGame"
]

E09 US14 - User story 14

Add role endpoint.

Url: /roles
Type: POST
Request example:
{
  "role": {
    "name": "test role"
  },
  "permissions": [
    "AddGame",
    "ViewGame",
    "UpdateGame"
  ]
}

E09 US15 - User story 15

Update role endpoint.

Url: /roles
Type: PUT
Request example:
{
  "role": {
    "id": "73e12b67-8f8e-4df9-bf0d-f1d7cb7296b4",
    "name": "User"
  },
  "permissions": [
    "ViewGame"
  ]
} 

E09 US16 - User story 16

Get all games without filters endpoint.

Url: /games/all
Type: GET
Response Example:
[
  {
    "id": "92753fa3-0207-4fd3-b892-0fafcb23d429",
    "description": "Test Desc",
    "key": "test1",
    "name": "Test Name",
    "price": 100,
    "discount": 0,
    "unitInStock": 100000
  },
  {
    "id": "12649a00-ca90-4d5e-b088-045db9cf4d9c",
    "description": "Test Desc 2",
    "key": "test2",
    "name": "Test Game2",
    "price": 10,
    "discount": 10,
    "unitInStock": 9000
  }
]

E09 US17 - User story 17

Update order detail quantity endpoint.

Url: /orders/details/{id}/quantity
Type: PATCH
Request Example:
{
  "count": 3
}

E09 US18 - User story 18

Delete order detail endpoint.

Url: /orders/details/{id}
Type: DELETE 

E09 US19 - User story 19

Ship order endpoint.

Url: /orders/{id}/ship
Type: POST 

E09 US20 - User story 20

Add game as the order detail endpoint.

Url: /orders/{id}/details/{key}
Type: POST

Optional requirements

E09 NFR1
Implement claim-based authorization. E09 NFR2 [Optional] Implement authentication with external microservice.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published