아 선발 등록 API에 코드들이 너무 난해하여 리펙토링을 해주면 좋을 거 같다는 의견과 참고해보라고 코드를 보여 주셨습니다.
for (let i = 1; i < 4; i++) {
const myPlayerId = myTeam[`UserPlayer` + i].playerId;
const myPlayer = await findPlayerFromDB(myPlayerId);
// 본인 플레이어 정보가 존재하지 않을 경우
if (!myPlayer)
throw new NotFoundError(
`내 팀 선수 중 '${myPlayerId}'의 선수 데이터가 존재하지 않습니다.`,
);
저는 여기서 myTeam[`UserPlayer` + i]
이부분 "`" 이걸 통해서 이런식으로도 작성이 되는 구나를 보았습니다. 오 이렇게 응용해서 해보면 여러 조건문들을 정리 할 수 있을 것 같아 시도해 보았습니다.
// 선수 선발 등록 API 토큰없이 테스트
router.post("/team/:teamId", async (req, res, next) => {
try {
const userId = 1;
const { teamId } = await teamIdParamValidate(req.params);
const { userPlayerId, position } = await teamInfoBodyValidate(req.body);
// userPlayerId는 유저가 가지고 있는 선수 등록할 userPlayerId를 요청받습니다.
// position는 team컬럼 중 userPlayerId1, userPlayerId2, userPlayerId3 등 어느 위치(실제 축구라면 포지션)에 등록할 것인지를 요청받습니다.
const userPlayer = await userPrisma.userPlayers.findFirst({
where: {
userPlayerId: userPlayerId,
},
});
if (!userPlayer || userPlayer.count <= 0)
throw new BadRequestError("현재 소유하고 있는 선수가 아닙니다.");
if (+userId !== userPlayer.userId)
throw new ConflictError("현재 계정의 선수가 아닙니다.");
const player = await gamePrisma.players.findFirst({
where: { playerId: userPlayer.playerId },
});
if (!player) throw new NotFoundError("해당 선수 정보가 없습니다.");
let team = await userPrisma.teams.findFirst({
where: {
teamId: +teamId,
},
});
// 팀이 없으면 새로 팀을 생성하고 선발할 선수를 해당 자리에 등록합니다.
if (!team) {
// 한 계정 당 3개의 팀만을 가집니다.
const isTeamCountCheck = await userPrisma.teams.findMany({
where: {
userId: +userId,
},
});
if (Object.keys(isTeamCountCheck).length >= 3)
return res.status(400).json({
message: "이미 3개의 팀을 가지고 있습니다.",
yourTeamId1: isTeamCountCheck[0].teamId,
yourTeamId2: isTeamCountCheck[1].teamId,
yourTeamId3: isTeamCountCheck[2].teamId,
});
// 팀 생성
team = await userPrisma.teams.create({
data: {
userId: +userId,
[`userPlayerId${position}`]: userPlayerId, // 이게되네
},
});
return res.status(201).json({
message: `${player.name} 선수를 새로운 팀 ${team.teamId}번 팀에 등록했습니다.`,
});
}
// 현재 계정의 팀이 아닐때 현재 계정이 가지고 있는 팀을 응답으로 보여줍니다.
if (+userId !== team.userId) {
const isTeamCountCheck = await userPrisma.teams.findMany({
where: {
userId: +userId,
},
});
return res.status(409).json({
message: "현재 계정의 팀이 아닙니다.",
yourTeamId1: isTeamCountCheck[0]
? isTeamCountCheck[0].teamId
: "비어있음",
yourTeamId2: isTeamCountCheck[1]
? isTeamCountCheck[1].teamId
: "비어있음",
yourTeamId3: isTeamCountCheck[2]
? isTeamCountCheck[2].teamId
: "비어있음",
});
}
// 여기서부턴 teamId로 찾은 팀이 있다는 과정하에 팀에 선수 등록 및 선수 위치 수정 등을 합니다.
// 해당 userPlayerId 선수가 이미 팀에 존재하고 선발 위치만을 변경해 주기위한 코드들입니다. 그리고 선발할 위치에 다른 선수가 있으면 다른 선수의 userPlayerId를 서로 위치를 변경하기 위해 작성해 보았습니다.
let originPosition = null; // 선발할려던 userPlayerId가 이미 존재하여 위치를 알기위해 사용합니다. 그래야 이 위치에 다른 userPlayerId를 넣어주기 위해서 입니다.
let otherUserPlayerId = null; // 선발할 위치에 있던 다른 선수의 userPlayerId를 가집니다.
for (let i = 1; i < 4; i++) {
// 선발 선수가 이미 존재하는 위치를 찾아서 지정합니다.
if (userPlayerId === team[`userPlayerId${i}`]) {
originPosition = i;
break;
}
}
// 해당 선발할려는 위치에 선수가 존재하면 그 선수의 userPlayerId를 가져옵니다.
if (team[`userPlayerId${position}`]) {
otherUserPlayerId = team[`userPlayerId${position}`];
}
// 다른 선수의 위치를 원래 선발할려는 선수의 위치를 변경해 줍니다.
if (originPosition) {
await userPrisma.teams.update({
data: {
[`userPlayerId${originPosition}`]: otherUserPlayerId,
},
where: { teamId: +teamId },
});
}
확실히 전에 있던 조건문들은 거의없어지고 전보단 깔끔하게 보이게 되었습니다. 근데 생각해 보면 나중에 해당 변수이름 같은걸 수정한다고하면 문제가 생길수도 있겠다 만약 다른사람이 코드를 수정할때는 이걸 염두해 두고 해당코드의 주석을 달아주면 좋을 거 같다는 생각도 해봤습니다.
그리고 후보 등록 API입니다.
// 선수 후보 등록 API
router.delete("/team/test1/:teamId", async (req, res, next) => {
try {
const userId = 1;
const { teamId } = await teamIdParamValidate(req.params);
const { position } = await positionBodyValidate(req.body);
const isTeam = await userPrisma.teams.findFirst({
where: { teamId: +teamId },
});
if (!isTeam) throw new NotFoundError("팀이 존재 하지 않습니다.");
// 현재 계정의 팀이 아닐때 현재 계정이 가지고 있는 팀을 응답으로 보여줍니다.
if (+userId !== isTeam.userId) {
const isTeamCountCheck = await userPrisma.teams.findMany({
where: {
userId: +userId,
},
});
return res.status(409).json({
message: "현재 계정의 팀이 아닙니다.",
yourTeamId1: isTeamCountCheck[0]
? isTeamCountCheck[0].teamId
: "비어있음",
yourTeamId2: isTeamCountCheck[1]
? isTeamCountCheck[1].teamId
: "비어있음",
yourTeamId3: isTeamCountCheck[2]
? isTeamCountCheck[2].teamId
: "비어있음",
});
}
if (!isTeam[`userPlayerId${position}`])
throw new BadRequestError("해당위치에 선수가 존재하지 않습니다.");
const userPlayer = await userPrisma.userPlayers.findFirst({
where: { userPlayerId: isTeam[`userPlayerId${position}`] },
});
if (!userPlayer)
throw new BadRequestError("현재 소유하고 있는 선수가 아닙니다.");
const player = await gamePrisma.players.findFirst({
where: { playerId: userPlayer.playerId },
});
if (!player) throw new NotFoundError("해당 선수 정보가 없습니다.");
// 팀 위치의 userPlayerId를 null로 변경 후보로 변경
await userPrisma.teams.update({
data: {
[`userPlayerId${position}`]: null,
},
where: { teamId: +teamId },
});
// 변경된 팀의 선수 명단을 확인합니다.
const renewalTeamUserPlayerIds = await userPrisma.teams.findFirst({
select: {
userPlayerId1: true,
userPlayerId2: true,
userPlayerId3: true,
},
where: { teamId: +teamId },
});
const userPlayerIds = Object.values(renewalTeamUserPlayerIds);
let isUserPlayerIdCheck = false;
for (let i = 0; i < userPlayerIds.length; i++) {
// 팀에 선수 한명이라도 있으면 isUserPlayerIdCheck = true;
if (userPlayerIds[i]) {
isUserPlayerIdCheck = true;
break;
}
}
// 모든 위치에 선수가 없으면 팀 레코드 삭제
if (!isUserPlayerIdCheck) {
await userPrisma.teams.delete({
where: { teamId: +teamId },
});
}
return res
.status(200)
.json({ message: `${player.name} 선수를 후보로 등록 되었습니다.` });
} catch (err) {
next(err);
}
});
해당 코드는 팀레코드에서 해당 위치에 있는 선수를 후보(Null)로 변경하여 팀에서 제외시킵니다.
팀에서 모든 선수가 존재하지 않으면 팀을 삭제하게끔 작성해보았습니다.
오늘도 화이팅 팀원 모두 화이팅!