From 66200196aea96424f2c6f96fcb3eaf6deaa40407 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Mon, 11 May 2026 13:53:07 +0900 Subject: [PATCH 01/13] =?UTF-8?q?feat:=20activity=20query=20key=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20staleTime=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/mypage/model/useInfiniteActivityPosts.ts | 5 ++--- src/shared/consts/queryKeys.ts | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/features/mypage/model/useInfiniteActivityPosts.ts b/src/features/mypage/model/useInfiniteActivityPosts.ts index 0388580..13e51a3 100644 --- a/src/features/mypage/model/useInfiniteActivityPosts.ts +++ b/src/features/mypage/model/useInfiniteActivityPosts.ts @@ -3,7 +3,6 @@ import { type ActivityPostType, } from "@/shared/api/activity"; import { QUERY_CACHE_TIME } from "@/shared/consts/cacheTimes"; -import { MYPAGE_QUERY_KEY } from "../consts/queryKeys"; import { SHARED_QUERY_KEY } from "@/shared/consts/queryKeys"; import { useSuspenseInfiniteQuery } from "@tanstack/react-query"; @@ -11,7 +10,7 @@ export const useInfiniteActivityPosts = (type: ActivityPostType, size = 20) => { return useSuspenseInfiniteQuery({ queryKey: [ SHARED_QUERY_KEY.POSTS, - MYPAGE_QUERY_KEY.POSTS_ACTIVITY, + SHARED_QUERY_KEY.ACTIVITY, type, ] as const, @@ -32,7 +31,7 @@ export const useInfiniteActivityPosts = (type: ActivityPostType, size = 20) => { }, select: res => res.pages, - staleTime: QUERY_CACHE_TIME.POSTS.staleTime, + staleTime: 0, gcTime: QUERY_CACHE_TIME.POSTS.gcTime, }); }; diff --git a/src/shared/consts/queryKeys.ts b/src/shared/consts/queryKeys.ts index 94030ad..8a30ee7 100644 --- a/src/shared/consts/queryKeys.ts +++ b/src/shared/consts/queryKeys.ts @@ -3,4 +3,5 @@ export const SHARED_QUERY_KEY = { MY: "my", MY_PROFILE: "profile", MY_INTEREST: "interest", + ACTIVITY: "activity", } as const; From 3a0648dd38b87b267b5da555dc71bc68cfe9cbd6 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Mon, 11 May 2026 14:00:14 +0900 Subject: [PATCH 02/13] =?UTF-8?q?feat:=20errorCode=20=EC=83=81=EC=88=98?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/consts/errorCodes.ts | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/shared/consts/errorCodes.ts diff --git a/src/shared/consts/errorCodes.ts b/src/shared/consts/errorCodes.ts new file mode 100644 index 0000000..fc8d18b --- /dev/null +++ b/src/shared/consts/errorCodes.ts @@ -0,0 +1,61 @@ +// 공통 error + +export const COMMON_ERROR = { + BAD_REQUEST: "COMMON400", + VALIDATION: "COMMON400_VALIDATION", + TYPE: "COMMON400_TYPE", + FORMAT: "COMMON400_FORMAT", + PARAM: "COMMON400_PARAM", + UNAUTHORIZED: "COMMON401", + FORBIDDEN: "COMMON403", + NOT_FOUND: "COMMON404", + INTERNAL_SERVER: "COMMON500", + SERVICE_UNAVAILABLE: "COMMON503", +} as const; + +export const AUTH_ERROR = { + TYPE_MISMATCH: "AUTH400_TYPE_MISMATCH", + INVALID: "AUTH401_INVALID", + EXPIRED: "AUTH401_EXPIRED", + MALFORMED: "AUTH401_MALFORMED", + SIGNATURE: "AUTH401_SIGNATURE", + UNSUPPORTED: "AUTH401_UNSUPPORTED", + EMPTY_CLAIMS: "AUTH401_EMPTY_CLAIMS", + INVALID_REFRESH: "AUTH401_INVALID_REFRESH", + REFRESH_MISSING: "AUTH401_REFRESH_MISSING", + REFRESH_MISMATCH: "AUTH401_REFRESH_MISMATCH", + KAKAO_TOKEN: "AUTH401_KAKAO_TOKEN", + WITHDRAWN: "AUTH403_WITHDRAWN", + FORBIDDEN: "AUTH403_FORBIDDEN", + USER_NOT_FOUND: "AUTH404_USER", + KAKAO_API: "AUTH500_KAKAO_API", +} as const; + +export const POST_ERROR = { + NOT_FOUND: "POST404_1", +} as const; + +export const USER_ERROR = { + INVALID_INTEREST: "USER400_1", + ALREADY_WITHDRAWN: "USER400_2", + NOT_FOUND: "USER404_1", +} as const; + +export const ACTIVITY_ERROR = { + BOOKMARK_NOT_FOUND: "ACTIVITY404_1", + ALREADY_BOOKMARKED: "ACTIVITY409_1", +} as const; + +export type CommonErrorCode = (typeof COMMON_ERROR)[keyof typeof COMMON_ERROR]; +export type AuthErrorCode = (typeof AUTH_ERROR)[keyof typeof AUTH_ERROR]; +export type PostErrorCode = (typeof POST_ERROR)[keyof typeof POST_ERROR]; +export type UserErrorCode = (typeof USER_ERROR)[keyof typeof USER_ERROR]; +export type ActivityErrorCode = + (typeof ACTIVITY_ERROR)[keyof typeof ACTIVITY_ERROR]; + +export type ErrorCode = + | CommonErrorCode + | AuthErrorCode + | PostErrorCode + | UserErrorCode + | ActivityErrorCode; From 63c0feb5b5b249b3354fb18f3685e7b030ad23a9 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Mon, 11 May 2026 14:02:16 +0900 Subject: [PATCH 03/13] =?UTF-8?q?refactor:=20=EB=B6=81=EB=A7=88=ED=81=AC?= =?UTF-8?q?=20=EC=83=81=ED=83=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=83=80=EC=9E=85=20=EC=95=88=EC=A0=95?= =?UTF-8?q?=EC=84=B1=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/lib/updateBookmarkState.ts | 96 ++++++++++++++------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/src/shared/lib/updateBookmarkState.ts b/src/shared/lib/updateBookmarkState.ts index 40a7f38..17813e0 100644 --- a/src/shared/lib/updateBookmarkState.ts +++ b/src/shared/lib/updateBookmarkState.ts @@ -1,79 +1,83 @@ +type AnyRecord = Record; + export const updateBookmarkState = ( - old: any, + old: unknown, postId: number, isBookmarked: boolean, -) => { +): unknown => { if (!old) return old; + const data = old as AnyRecord; - if (old.pages && Array.isArray(old.pages)) { - return { - ...old, - pages: old.pages.map((page: any) => { - const dataKey = page.data?.posts - ? "posts" - : page.data?.readPosts - ? "readPosts" - : page.data?.bookmarks - ? "bookmarks" - : null; - - if (!dataKey || !page.data[dataKey]) return page; + if (Array.isArray((data as AnyRecord).pages)) { + const pages = (data.pages as AnyRecord[]).map((page: AnyRecord) => { + const pageData = page.data as AnyRecord; + const dataKey = pageData?.posts + ? "posts" + : pageData?.readPosts + ? "readPosts" + : pageData?.bookmarks + ? "bookmarks" + : null; - if (dataKey === "bookmarks" && !isBookmarked) { - return { - ...page, - data: { - ...page.data, - [dataKey]: page.data[dataKey].filter( - (post: any) => post.id !== postId && post.postId !== postId, - ), - }, - }; - } + if (!dataKey || !pageData[dataKey]) return page; + if (dataKey === "bookmarks" && !isBookmarked) { return { ...page, data: { - ...page.data, - [dataKey]: page.data[dataKey].map((post: any) => - post.id === postId || post.postId === postId - ? { ...post, isBookmarked } - : post, + ...pageData, + [dataKey]: (pageData[dataKey] as AnyRecord[]).filter( + (post: AnyRecord) => post.id !== postId && post.postId !== postId, ), }, }; - }), - }; + } + + return { + ...page, + data: { + ...pageData, + [dataKey]: (pageData[dataKey] as AnyRecord[]).map((post: AnyRecord) => + post.id === postId || post.postId === postId + ? { ...post, isBookmarked } + : post, + ), + }, + }; + }); + return { ...data, pages }; } - const isRec = old.recommendations || (old.data && old.data.recommendations); + const isRec = + data.recommendations || + ((data.data as AnyRecord)?.recommendations); if (isRec) { - const isRoot = !!old.recommendations; - const target = isRoot ? old : old.data; - + const isRoot = !!data.recommendations; + const target = (isRoot ? data : data.data) as AnyRecord; const updated = { ...target, - recommendations: target.recommendations.map((post: any) => - post.postId === postId || post.id === postId - ? { ...post, isBookmarked } - : post, + recommendations: (target.recommendations as AnyRecord[]).map( + (post: AnyRecord) => + post.postId === postId || post.id === postId + ? { ...post, isBookmarked } + : post, ), }; - return isRoot ? updated : { ...old, data: updated }; + return isRoot ? updated : { ...data, data: updated }; } if (Array.isArray(old)) { - return old.map((post: any) => + return (old as AnyRecord[]).map((post: AnyRecord) => post.id === postId || post.postId === postId ? { ...post, isBookmarked } : post, ); } - if (old.data && Array.isArray(old.data)) { + if (data.data && Array.isArray(data.data)) { return { - ...old, - data: old.data.map((post: any) => + ...data, + data: (data.data as AnyRecord[]).map((post: AnyRecord) => post.id === postId || post.postId === postId ? { ...post, isBookmarked } : post, From 32bb8744a4538a3f6d3dcded080e71f50a7fd6ce Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Mon, 11 May 2026 15:00:15 +0900 Subject: [PATCH 04/13] =?UTF-8?q?design:=20inputField=20darkmode=EB=A5=BC?= =?UTF-8?q?=20=EA=B3=A0=EB=A0=A4=ED=95=9C=20text=EC=83=89=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/ui/InputField.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shared/ui/InputField.tsx b/src/shared/ui/InputField.tsx index eabb255..92116e2 100644 --- a/src/shared/ui/InputField.tsx +++ b/src/shared/ui/InputField.tsx @@ -35,8 +35,8 @@ export const InputField = ({ ) : (