0% found this document useful (0 votes)
26 views18 pages

The Goal of This Challenge Is To Build An API That Will Manage

Uploaded by

Hasna Ayu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views18 pages

The Goal of This Challenge Is To Build An API That Will Manage

Uploaded by

Hasna Ayu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 18

The goal of this challenge is to build an API that will manage (add,

update, list, delete) players with some skills and select the best
players with the desired position/skill.

The players will need to have:

 name
 position
 list of skills

The available positions for players are:

 'defender'
 'midfielder'
 'forward'

The skill will have:

 skill name
 value

The available skills for a player are:

 'defense'
 'attack'
 'speed'
 'strength'
 'stamina'

The player needs to have at least one skill, but it does not need to
have values for all available skills. A valid player in JSON format
is:
Automatic Testing
Team lead will use their test suite to run automatic tests to verify your
implementation.

Files under __tests__ directory provide example test cases. You


should read them to figure out how to properly implement the
solution and throw exceptions.

You are also encouraged to write your own test cases under tests
directory.

Existing Source Code


Even though this is a new project you will not be starting from
scratch. In the repository you will also find some preexisting
source code.

You must continue building on top of that preexisting source code


and you should NOT DELETE any of the existing source code,
files and folders NOR move or rename any of the existing files,
classes, methods or variables. However, you’re free to add new
source files to the project and extend existing classes with your
own methods and variables.
IMPORTANT NOTES:

1. Please follow the instructions in the existing source code.


Not following the instructions and not using the preexisting
source code as a base might result in automatic test failures.
2. Please DO NOT CHANGE the folder structure of WebApi and
WebApiTest projects, and DO NOT MOVE the provided files
to a different place, as this will result in a test failure.
3. All the new classes should have public access.
4. Before you submit the challenge, please make sure the
project was successfully built.

API Description

Basic Config:
The app needs to be served at http://localhost:3000 and the API
requests should be available at http://localhost:3000/api/.

In case of errors, the body should return the correct error


message following this pattern:

It is important that the error message contains the field that is


invalid (position field in this case) and the invalid value used in
the request (midfielder1 in this case).

If the field is inside an array, the error message should show the
field inside it, for example if the skill of the player (inside
playerSkills array) has an invalid value, the error should contain
the "skill" field and the invalid value for that skill.

The solution should return only the first error found. If the request
to create the player has invalid values for position and skill fields,
the solution should return only the message for one of those
fields. The validation rules do not need to follow any specific
order.
[
{
"id": 1,
"name": "player name 1",
"position": "defender",
"playerSkills": [
{
"id": 1,
"skill": "defense",
"value": 60,
"playerId": 1
},
{
"id": 2,
"skill": "speed",
"value": 80,
"playerId": 1
}
]
},
{
"id": 2,
"name": "player name 2",
"position": "midfielder",
"playerSkills": [
{
"id": 3,
"skill": "attack",
"value": 20,
"playerId": 2
},
{
"id": 4,
"skill": "speed",
"value": 70,
"playerId": 2
}
]
}
]
The expected result from this endpoint is the best list of players
from the database according to the requirements ex:

[
{
"name": "player name 2",
"position": "midfielder",
"playerSkills": [
{
"skill": "speed",
"value": 90
}
]
},
{
"name": "player name 3",
"position": "defender",
"playerSkills": [
{
"skill": "strength",
"value": 50
},
{
"skill": "stamina",
"value": 2
}
]
},
{
"name": "player name 4",
"position": "defender",
"playerSkills": [
{
"skill": "strength",
"value": 37
}
]
}
];

Rules To Select The Best Team:


1.
1. Given a position and the skill desired for that position,
the app should be able to find the best player in the
database with that skill and position. If there are more
than one player with the highest skill value, the
solution can select any of those players.

2. The same skill can be used in different positions. For


example: you can send a request with a requirement
for defender with the highest speed, and a midfielder
with the highest speed in the same request.

3. The request should allow the same position and skill


combination only once but should accept the same
position multiple times. For example: you cannot send
a request with two requirements for defender with the
highest speed, but you can send a request with a
requirement for defender with the highest speed and a
defender with the highest strength. In the example
above the same player cannot be used multiple times.

4. If there are no players in the database with the desired


skill, the app should find the highest skill value for any
players in the selected position. For example, if in the
database we have 3 defenders with these skills:

 player 1 has {speed: 90}


 player 2 has {strength: 20}
 player 3 has {stamina: 95}

And the requirements ask for a defender with


defense skill, the app should select player 3,
because there are no defenders with defense skill,
and the defender with highest skill value is player
3. The same rule should be applied if the player
has multiple skills, so if we have in the database
the following players:
 player 1 has {stamina: 90, speed: 100,
strength: 20}
 player 2 has {stamina: 80, speed: 80,
strength: 80}
 player 3 has {stamina: 95, speed 90,
strength: 50}

And the requirements specify a defender


with defense skill, the app should select
player 1, because it is the player with
highest skill: speed 100.

5. The app should always fill the number of required


players with the correct position. For example, if the
requirement is for 2 defenders, the app should find the
best 2 defenders with the desired skill and use rule
number 4 if there are no available defenders with the
desired skill.

6. The app should return an error if there are no available


players in the required position. For example, if the
request requires 2 defenders and there is only one
defender in the database, the app should return an
error with the message: “Insufficient number of players
for position: defender”. This rule should only be applied
for positions. The skill requirement should follow the
rules described in point 4.
2.

 First, install Git

https://github.com/git-guides/install-git

 Clone the repository:

git clone https://[email protected]/inspiraworld-1381/ayu-5u8D-player-team-generator-web-


api-nGwp.git

 Your password is:

02742dd143ee4f43ecd4cec7b29fa9d4064828d7

 Work on your challenge following the description above.


 Once you are satisfied with the result, push your commits to the master branch of the
repository:

git push origin master


1. Create player
 public function store(Request $request)
 {
 // Menggunakan validator untuk validasi request
 $validator = Validator::make($request->all(), [
 'name' => 'required|string|max:255',
 'position' => 'required|
in:defender,midfielder,forward',
 'playerSkills' => 'required|array|min:1',
 'playerSkills.*.skill' => 'required|
in:defense,attack,speed,strength,stamina',
 'playerSkills.*.value' => 'required|integer|min:0|
max:100',
 ]);

 // Jika validasi gagal, kembalikan respons error
 if ($validator->fails()) {
 return response()->json(['message' => $validator-
>errors()], 422);
 }

 try {
 // Ambil data yang telah tervalidasi
 $playerData = $request->only(['name', 'position']);
 $playerSkillsData = $request->input('playerSkills');

 // Buat player baru
 $player = Player::create($playerData);

 // Tambahkan skills ke player
 foreach ($playerSkillsData as $skillData) {
 $player->skills()->create($skillData);
 }

 // Muat relasi skills
 $player->load('skills');

 // Kembalikan respons sukses
 return response()->json($player, 201);
 } catch (\Exception $e) {
 // Kembalikan respons error jika terjadi exception
 return response()->json(['message' => $e-
>getMessage()], 500);
 }
 }
// app/Http/Controllers/PlayerController.php

use Illuminate\Http\Request;
use App\Models\Player;
use App\Models\PlayerSkill;
use Validator;

class PlayerController extends Controller


{
public function selectPlayers(Request $request)
{
$validator = Validator::make($request->all(), [
'*.position' => 'required|string|in:defender,midfielder,forward',
'*.mainSkill' => 'required|string|in:defense,attack,speed,strength,stamina',
'*.numberOfPlayers' => 'required|integer|min:1',
]);

if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 400);
}

$selectedPlayers = [];

foreach ($request->all() as $criteria) {


$position = $criteria['position'];
$mainSkill = $criteria['mainSkill'];
$numberOfPlayers = $criteria['numberOfPlayers'];

// Find players with the desired skill and position


$players = Player::whereHas('playerSkills', function ($query) use ($mainSkill,
$position) {
$query->where('skill', $mainSkill);
})->where('position', $position)->get();

// If no players found with the desired skill, find the best players in the
position
if ($players->isEmpty()) {
$players = Player::where('position', $position)
->orderByDesc('playerSkills.value')
->get();
}

// Check if there are enough players in the selected position


if ($players->isEmpty()) {
return response()->json(['error' => "Insufficient number of players for
position: $position"], 404);
}

// Select the best players based on the requirement


$selected = $players->take($numberOfPlayers);

foreach ($selected as $player) {


// Include only the necessary fields in the response
$selectedPlayers[] = [
'name' => $player->name,
'position' => $player->position,
'playerSkills' => $player->playerSkills()->where('skill', $mainSkill)-
>get(['skill', 'value']),
];
}
}

return response()->json($selectedPlayers, 200);


}
}
1. Dengan adanya posisi dan
keterampilan yang diinginkan untuk posisi
tersebut, aplikasi harus dapat
menemukan pemain terbaik dalam
database dengan keterampilan dan posisi
tersebut. Jika terdapat lebih dari satu
pemain dengan nilai skill tertinggi,
solusinya dapat memilih salah satu
pemain tersebut.

2. Skill yang sama dapat digunakan pada


posisi berbeda. Misalnya: Anda dapat
mengirimkan permintaan dengan
persyaratan bek dengan kecepatan
tertinggi, dan gelandang dengan
kecepatan tertinggi dalam permintaan
yang sama.

3. Permintaan harus mengizinkan posisi


dan kombinasi keterampilan yang sama
hanya satu kali tetapi harus menerima
posisi yang sama beberapa kali. Misalnya:
Anda tidak dapat mengirim permintaan
dengan dua persyaratan pembela dengan
kecepatan tertinggi, tetapi Anda dapat
mengirim permintaan dengan persyaratan
pembela dengan kecepatan tertinggi dan
pembela dengan kekuatan tertinggi. Pada
contoh di atas pemain yang sama tidak
dapat digunakan berkali-kali.

4. Jika tidak ada pemain dalam database


dengan keterampilan yang diinginkan,
aplikasi harus mencari nilai keterampilan
tertinggi untuk setiap pemain di posisi
yang dipilih. Misalnya jika di database kita
memiliki 3 pemain bertahan dengan skill
berikut:

• pemain 1 memiliki {kecepatan: 90}


• pemain 2 memiliki {kekuatan: 20}
• pemain 3 memiliki {stamina: 95}

Dan persyaratannya meminta pemain


bertahan dengan keterampilan bertahan,
aplikasi harus memilih pemain 3, karena
tidak ada pemain bertahan dengan
keterampilan bertahan, dan pemain
bertahan dengan nilai keterampilan
tertinggi adalah pemain 3. Aturan yang
sama harus diterapkan jika pemain
memiliki banyak keterampilan. , jadi jika
kita memiliki pemain berikut di database:
• pemain 1 memiliki {stamina: 90,
kecepatan: 100, kekuatan: 20}
• pemain 2 memiliki {stamina: 80,
kecepatan: 80, kekuatan: 80}
• pemain 3 memiliki {stamina: 95,
kecepatan 90, kekuatan: 50}

Dan persyaratannya menentukan bek


dengan keterampilan pertahanan, aplikasi
harus memilih pemain 1, karena itu
adalah pemain dengan keterampilan
tertinggi: kecepatan 100.

5. Aplikasi harus selalu mengisi jumlah


pemain yang dibutuhkan dengan posisi
yang benar. Misalnya, jika persyaratannya
adalah 2 pemain bertahan, aplikasi harus
mencari 2 pemain bertahan terbaik
dengan keterampilan yang diinginkan dan
menggunakan aturan nomor 4 jika tidak
tersedia pemain bertahan dengan
keterampilan yang diinginkan.
6. Aplikasi akan menampilkan kesalahan
jika tidak ada pemain yang tersedia di
posisi yang diperlukan. Misalnya, jika
permintaan memerlukan 2 pemain
bertahan dan hanya ada satu pemain
bertahan di database, aplikasi akan
menampilkan kesalahan dengan pesan:
“Jumlah pemain tidak mencukupi untuk
posisi: pemain bertahan”. Aturan ini
hanya boleh diterapkan pada jabatan.
Persyaratan keterampilan harus mengikuti
aturan yang dijelaskan pada poin 4.

You might also like