diff --git a/src/api/member/getGameRegistrationStatus.ts b/src/api/member/getGameRegistrationStatus.ts
index 453ca3e2..126fe7e9 100644
--- a/src/api/member/getGameRegistrationStatus.ts
+++ b/src/api/member/getGameRegistrationStatus.ts
@@ -2,14 +2,14 @@ import { axiosInstance } from '@api/axiosInstance';
 
 import {
   GetGameRegistrationStatusRequest,
-  GetRegistrationStatusResponse,
+  GetGameRegistrationStatusResponse,
 } from '@type/api/member';
 
 export const getGameRegistrationStatus = async ({
   memberId,
   gameId,
 }: GetGameRegistrationStatusRequest) => {
-  const { data } = await axiosInstance.get<GetRegistrationStatusResponse>(
+  const { data } = await axiosInstance.get<GetGameRegistrationStatusResponse>(
     `/members/${memberId}/games/${gameId}/registration-status`
   );
 
diff --git a/src/hooks/mutations/useMannerScoreReviewPatchMutation.ts b/src/hooks/mutations/useMannerScoreReviewPatchMutation.ts
index 72553a24..dc1d9d59 100644
--- a/src/hooks/mutations/useMannerScoreReviewPatchMutation.ts
+++ b/src/hooks/mutations/useMannerScoreReviewPatchMutation.ts
@@ -1,7 +1,9 @@
-import { useMutation } from '@tanstack/react-query';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
 
 import { patchMannerScoreReview } from '@api/games/patchMannerScoreReview';
 
+import { useLoginInfoStore } from '@stores/loginInfo.store';
+
 import { PatchGameMannerScoreReviewRequest } from '@type/api/games';
 import { Game } from '@type/models';
 
@@ -12,8 +14,23 @@ export const useMannerScoreReviewPatchMutation = ({
   payload: PatchGameMannerScoreReviewRequest;
   gameId: Game['id'];
 }) => {
+  const queryClient = useQueryClient();
+  const loginInfo = useLoginInfoStore((state) => state.loginInfo);
+
   return useMutation({
     mutationKey: ['patch-manner-score-review', gameId, JSON.stringify(payload)],
     mutationFn: () => patchMannerScoreReview({ payload, gameId }),
+    onSuccess: () => {
+      console.log(['game-registration', loginInfo?.id, gameId]);
+      queryClient.invalidateQueries({
+        queryKey: ['created-games', loginInfo?.id],
+      });
+      queryClient.invalidateQueries({
+        queryKey: ['confirmed-games', loginInfo?.id],
+      });
+      queryClient.invalidateQueries({
+        queryKey: ['game-registration', loginInfo?.id, gameId],
+      });
+    },
   });
 };
diff --git a/src/mocks/data/member.ts b/src/mocks/data/member.ts
index c3fe80ea..8f5c3bcf 100644
--- a/src/mocks/data/member.ts
+++ b/src/mocks/data/member.ts
@@ -4,7 +4,12 @@ import {
   PostRefreshAccessTokenResponse,
   PostRegistrationResponse,
 } from '@type/api/member';
-import { Authenticated, CrewProfile, Game, Registration } from '@type/models';
+import {
+  Authenticated,
+  CrewProfile,
+  MemberGame,
+  Registration,
+} from '@type/models';
 
 export const AUTH_LOGIN_MEMBER: Authenticated = {
   accessToken:
@@ -129,7 +134,7 @@ export const MEMBERS_MEMBERID: GetMemberProfileResponse = {
   ],
 };
 
-export const MEMBERS_MEMBERID_CONFIRMED_GAMES: Game[] = [
+export const MEMBERS_MEMBERID_CONFIRMED_GAMES: MemberGame[] = [
   {
     id: 1,
     content: '같이 즐거운 게임 해요~',
@@ -146,6 +151,7 @@ export const MEMBERS_MEMBERID_CONFIRMED_GAMES: Game[] = [
     cost: 0,
     memberCount: 3,
     maxMemberCount: 5,
+    isReviewDone: false,
     host: {
       id: 1,
       email: 'james123@pickple.kr',
@@ -190,7 +196,7 @@ export const MEMBERS_MEMBERID_CONFIRMED_GAMES: Game[] = [
   },
 ];
 
-export const MEMBERS_MEMBERID_CREATED_GAMES: Game[] = [
+export const MEMBERS_MEMBERID_CREATED_GAMES: MemberGame[] = [
   {
     id: 1,
     content: '같이 즐거운 게임 해요~',
@@ -207,6 +213,7 @@ export const MEMBERS_MEMBERID_CREATED_GAMES: Game[] = [
     cost: 0,
     memberCount: 3,
     maxMemberCount: 5,
+    isReviewDone: false,
     host: {
       id: 1,
       email: 'james123@pickple.kr',
diff --git a/src/pages/GamesDetailPage/GamesDetailPage.tsx b/src/pages/GamesDetailPage/GamesDetailPage.tsx
index c2ad7475..af00a475 100644
--- a/src/pages/GamesDetailPage/GamesDetailPage.tsx
+++ b/src/pages/GamesDetailPage/GamesDetailPage.tsx
@@ -19,7 +19,12 @@ import { useLoginInfoStore } from '@stores/loginInfo.store';
 import { PATH_NAME } from '@consts/pathName';
 import { WEEKDAY } from '@consts/weekday';
 
-import { getGameStartDate, isGameEnded, isGameStarted } from '@utils/domain';
+import {
+  getGameStartDate,
+  isGameEnded,
+  isGameStarted,
+  isReviewPeriod,
+} from '@utils/domain';
 
 import Ball from '@assets/ball.svg';
 import GameMember from '@assets/gameMember.svg';
@@ -65,6 +70,11 @@ export const GamesDetailPage = () => {
     (member) => member.id === loginInfo?.id
   );
   const vacancy = match.maxMemberCount - match.memberCount > 0;
+  const canReview = isReviewPeriod(
+    match.playDate,
+    match.playStartTime,
+    match.playTimeMinutes
+  );
 
   const [year, month, day] = match.playDate.split('-');
   const [hour, min] = match.playStartTime.split(':');
@@ -260,9 +270,11 @@ export const GamesDetailPage = () => {
           <ErrorBoundary fallback={<></>}>
             {loginInfo?.id && isMyMatch && (
               <HostButton
+                loginId={loginInfo.id}
                 gameId={gameId}
                 isStarted={isStarted}
                 isEnded={isEnded}
+                isReviewPeriod={canReview}
               />
             )}
             {loginInfo?.id && !isMyMatch && (
@@ -272,6 +284,7 @@ export const GamesDetailPage = () => {
                 isStarted={isStarted}
                 isEnded={isEnded}
                 vacancy={vacancy}
+                isReviewPeriod={canReview}
               />
             )}
           </ErrorBoundary>
diff --git a/src/pages/GamesDetailPage/components/GuestButton.tsx b/src/pages/GamesDetailPage/components/GuestButton.tsx
index 9de9b1c2..d0774ff5 100644
--- a/src/pages/GamesDetailPage/components/GuestButton.tsx
+++ b/src/pages/GamesDetailPage/components/GuestButton.tsx
@@ -18,6 +18,7 @@ type GuestButtonProps = {
   isStarted: boolean;
   isEnded: boolean;
   vacancy: boolean;
+  isReviewPeriod: boolean;
 };
 
 export const GuestButton = ({
@@ -26,12 +27,13 @@ export const GuestButton = ({
   isStarted,
   isEnded,
   vacancy,
+  isReviewPeriod,
 }: GuestButtonProps) => {
   const isContinue = isStarted && !isEnded;
   const navigate = useNavigate();
 
   const {
-    data: { memberRegistrationStatus },
+    data: { memberRegistrationStatus, isReviewDone },
   } = useGameRegistrationStatusQuery({ memberId: loginId, gameId });
   const { mutate: participateMutate } = useGameParticipateCreateMutation();
 
@@ -53,7 +55,11 @@ export const GuestButton = ({
   }
 
   if (isEnded) {
-    if (memberRegistrationStatus === '확정') {
+    if (
+      isReviewPeriod &&
+      memberRegistrationStatus === '확정' &&
+      !isReviewDone
+    ) {
       return (
         <BottomButton onClick={navigateReviewPage}>리뷰 남기기</BottomButton>
       );
diff --git a/src/pages/GamesDetailPage/components/HostButton.tsx b/src/pages/GamesDetailPage/components/HostButton.tsx
index dc3d2b78..bf5be661 100644
--- a/src/pages/GamesDetailPage/components/HostButton.tsx
+++ b/src/pages/GamesDetailPage/components/HostButton.tsx
@@ -1,17 +1,30 @@
 import { useNavigate } from 'react-router-dom';
 
+import { useGameRegistrationStatusQuery } from '@hooks/queries/useGameRegistrationStatusQuery';
+
 import { PATH_NAME } from '@consts/pathName';
 
 import { BottomButton } from './BottomButton';
 
 type HostButtonProps = {
+  loginId: number;
   gameId: number;
   isStarted: boolean;
   isEnded: boolean;
+  isReviewPeriod: boolean;
 };
 
-export const HostButton = ({ gameId, isStarted, isEnded }: HostButtonProps) => {
+export const HostButton = ({
+  loginId,
+  gameId,
+  isStarted,
+  isEnded,
+  isReviewPeriod,
+}: HostButtonProps) => {
   const navigate = useNavigate();
+  const {
+    data: { isReviewDone },
+  } = useGameRegistrationStatusQuery({ memberId: loginId, gameId });
 
   const navigateManagePage = () =>
     navigate(PATH_NAME.GET_GAMES_MANAGE_PATH(String(gameId)));
@@ -23,7 +36,7 @@ export const HostButton = ({ gameId, isStarted, isEnded }: HostButtonProps) => {
     return <BottomButton onClick={navigateManagePage}>매치 관리</BottomButton>;
   }
 
-  if (isEnded) {
+  if (isReviewPeriod && isEnded && !isReviewDone) {
     return (
       <BottomButton onClick={navigateReviewPage}>리뷰 남기기</BottomButton>
     );
diff --git a/src/pages/GamesHostPage/GamesHostPage.tsx b/src/pages/GamesHostPage/GamesHostPage.tsx
index 9ec6391a..4c3ec8c5 100644
--- a/src/pages/GamesHostPage/GamesHostPage.tsx
+++ b/src/pages/GamesHostPage/GamesHostPage.tsx
@@ -13,7 +13,12 @@ import { useLoginInfoStore } from '@stores/loginInfo.store';
 
 import { PATH_NAME } from '@consts/pathName';
 
-import { getGameStartDate, isGameEnded, isGameStarted } from '@utils/domain';
+import {
+  getGameStartDate,
+  isGameEnded,
+  isGameStarted,
+  isReviewPeriod,
+} from '@utils/domain';
 
 import { PageContent, PageWrapper } from './GamesHostPage.styles';
 
@@ -44,6 +49,14 @@ export const GamesHostPage = () => {
             (member) => member.profileImageUrl
           );
           const startTime = getGameStartDate(game.playDate, game.playStartTime);
+          const canReview =
+            isReviewPeriod(
+              game.playDate,
+              game.playStartTime,
+              game.playTimeMinutes
+            ) &&
+            isGameEnded(startTime, game.playTimeMinutes) &&
+            !game.isReviewDone;
 
           return (
             <MatchItem
@@ -65,7 +78,7 @@ export const GamesHostPage = () => {
                   매치 관리
                 </MatchItem.BottomButton>
               )}
-              {isGameEnded(startTime, game.playTimeMinutes) && (
+              {canReview && (
                 <MatchItem.BottomButton
                   onClick={() =>
                     navigate(PATH_NAME.GET_GAMES_REVIEW_PATH(String(game.id)))
diff --git a/src/pages/GamesParticipatePage/GamesParticipatePage.tsx b/src/pages/GamesParticipatePage/GamesParticipatePage.tsx
index 8a2ad196..0fb768b9 100644
--- a/src/pages/GamesParticipatePage/GamesParticipatePage.tsx
+++ b/src/pages/GamesParticipatePage/GamesParticipatePage.tsx
@@ -13,7 +13,7 @@ import { useLoginInfoStore } from '@stores/loginInfo.store';
 
 import { PATH_NAME } from '@consts/pathName';
 
-import { getGameStartDate } from '@utils/domain';
+import { getGameStartDate, isReviewPeriod } from '@utils/domain';
 
 import { PageContent, PageWrapper } from './GamesParticipatePage.styles';
 
@@ -47,6 +47,14 @@ export const GamesParticipatePage = () => {
           const endTimeNumber =
             startTime.getTime() + game.playTimeMinutes * 60000;
           const isMatchEnd = endTimeNumber <= new Date().getTime();
+          const canReview =
+            isReviewPeriod(
+              game.playDate,
+              game.playStartTime,
+              game.playTimeMinutes
+            ) &&
+            isMatchEnd &&
+            !game.isReviewDone;
 
           return (
             <MatchItem
@@ -59,7 +67,7 @@ export const GamesParticipatePage = () => {
               maxMemberCount={game.maxMemberCount}
               membersProfileImageUrls={membersProfileImageUrls}
             >
-              {isMatchEnd && (
+              {canReview && (
                 <MatchItem.BottomButton
                   onClick={() =>
                     navigate(PATH_NAME.GET_GAMES_REVIEW_PATH(String(game.id)))
diff --git a/src/pages/MannerScoreReviewPage/MannerScoreReviewPage.tsx b/src/pages/MannerScoreReviewPage/MannerScoreReviewPage.tsx
index 26f1954b..779d5412 100644
--- a/src/pages/MannerScoreReviewPage/MannerScoreReviewPage.tsx
+++ b/src/pages/MannerScoreReviewPage/MannerScoreReviewPage.tsx
@@ -4,6 +4,8 @@ import { useNavigate } from 'react-router-dom';
 import { ProfileSkeleton } from '@pages/ProfilePage';
 import { Profile } from '@pages/ProfilePage';
 
+import { LoginRequireError } from '@routes/LoginRequireBoundary';
+
 import { Avatar } from '@components/Avatar';
 import { Header } from '@components/Header';
 import { Modal } from '@components/Modal';
@@ -13,6 +15,7 @@ import { Text } from '@components/shared/Text';
 
 import { useMannerScoreReviewPatchMutation } from '@hooks/mutations/useMannerScoreReviewPatchMutation';
 import { useGameDetailQuery } from '@hooks/queries/useGameDetailQuery';
+import { useGameRegistrationStatusQuery } from '@hooks/queries/useGameRegistrationStatusQuery';
 
 import { theme } from '@styles/theme';
 
@@ -20,6 +23,8 @@ import { useLoginInfoStore } from '@stores/loginInfo.store';
 
 import { PATH_NAME } from '@consts/pathName';
 
+import { isReviewPeriod } from '@utils/domain';
+
 import leftArrowIcon from '@assets/leftArrow.svg';
 import rightArrowIcon from '@assets/rightArrow.svg';
 
@@ -37,16 +42,31 @@ import { ToggleButton } from './ToggleButton';
 export const MannerScoreReviewPage = () => {
   const navigate = useNavigate();
   const gameId = Number(location.pathname.split('/')[2]);
-  const { data: gameData } = useGameDetailQuery(gameId);
   const loginInfo = useLoginInfoStore((state) => state.loginInfo);
+  if (!loginInfo?.id) {
+    throw new LoginRequireError();
+  }
+
+  const { data: gameData } = useGameDetailQuery(gameId);
+  const {
+    data: { isReviewDone },
+  } = useGameRegistrationStatusQuery({ memberId: loginInfo.id, gameId });
   const teammateListInfo = gameData.members.filter(({ id }) => {
     return loginInfo?.id !== id;
   });
+
   const nowDate = new Date();
   const gameDate = new Date(`${gameData.playDate}T${gameData.playEndTime}`);
-
+  const canReview = isReviewPeriod(
+    gameData.playDate,
+    gameData.playStartTime,
+    gameData.playTimeMinutes
+  );
   const exitCode =
-    nowDate <= gameDate || !loginInfo || teammateListInfo.length === 0;
+    !canReview ||
+    isReviewDone ||
+    nowDate <= gameDate ||
+    teammateListInfo.length === 0;
 
   const [currentSelectedMemberIndex, setCurrentSelectedMemberIndex] =
     useState(0);
diff --git a/src/type/api/member.ts b/src/type/api/member.ts
index fa3e82cf..97f726bd 100644
--- a/src/type/api/member.ts
+++ b/src/type/api/member.ts
@@ -3,6 +3,7 @@ import {
   CrewProfile,
   Game,
   Member,
+  MemberGame,
   MemberProfile,
   Registration,
 } from '@type/models';
@@ -37,12 +38,12 @@ export type GetConfirmedGamesRequest = {
   memberId: Member['id'];
 };
 
-export type GetConfirmedGamesResponse = Game[];
+export type GetConfirmedGamesResponse = MemberGame[];
 
 export type GetCreatedGamesRequest = {
   memberId: Member['id'];
 };
-export type GetCreatedGamesResponse = Game[];
+export type GetCreatedGamesResponse = MemberGame[];
 
 export type GetJoinedCrewsResponse = CrewProfile[];
 
@@ -63,3 +64,6 @@ export type GetGameRegistrationStatusRequest = {
 export type GetRegistrationStatusResponse = {
   memberRegistrationStatus: '없음' | '대기' | '확정';
 };
+
+export type GetGameRegistrationStatusResponse =
+  GetRegistrationStatusResponse & { isReviewDone: boolean };
diff --git a/src/type/models/Game.ts b/src/type/models/Game.ts
index 131e2992..98e58df2 100644
--- a/src/type/models/Game.ts
+++ b/src/type/models/Game.ts
@@ -23,3 +23,5 @@ export type Game = {
   positions: Position[];
   members: Member[];
 };
+
+export type MemberGame = Game & { isReviewDone: boolean };
diff --git a/src/utils/domain.ts b/src/utils/domain.ts
index b8b59438..0af5a2ab 100644
--- a/src/utils/domain.ts
+++ b/src/utils/domain.ts
@@ -20,3 +20,16 @@ export const isGameEnded = (startDate: Date, playTimeMinutes: number) => {
   const endTimeNumber = startDate.getTime() + playTimeMinutes * 60000;
   return endTimeNumber <= new Date().getTime();
 };
+
+export const isReviewPeriod = (
+  gamePlayDate: string,
+  gamePlayStartTime: string,
+  playTimeMinutes: number
+) => {
+  const gameStartDate = getGameStartDate(gamePlayDate, gamePlayStartTime);
+  const gameEndTimeNumber = gameStartDate.getTime() + playTimeMinutes * 60000;
+  const oneWeekMs = 1000 * 60 * 60 * 24 * 7;
+  const now = new Date();
+
+  return now.getTime() - gameEndTimeNumber < oneWeekMs;
+};