From eaf7df8b37aa0759b45a2c3158d6752cb67e3001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Sat, 15 Aug 2026 23:43:30 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20INCOMPLETE=20=ED=8C=8C=EC=8B=B1=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=ED=83=80=EC=9E=85=C2=B7SSE=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 서버가 파싱이 일부만 끝난 경우 ITEM_PARSING_INCOMPLETE 알림과 status=INCOMPLETE SSE 를 보낸다 (TeamPiKi/core#945). 모르는 타입이라 switch default 로 빠져 딥링크가 동작하지 않았다 - 알림함·푸시·SSE 세 라우팅에 케이스를 더한다. 목적지는 기존 파싱 알림과 같다(위시 또는 토너먼트 담기 화면) - SSE 토스트는 실패와 갱신 대상이 같아 케이스를 합치되 문구만 info 로 가른다 — 실패가 아니라 "채워 주세요" 안내라서다 --- .../src/app/notification/_utils/getNotificationRoute.ts | 1 + apps/web/src/hooks/useNotificationSSE.ts | 8 +++++++- apps/web/src/types/notification.ts | 4 +++- apps/web/src/utils/pushNotificationRoute.ts | 1 + packages/core/src/consts/webBridge.ts | 1 + packages/core/src/types/pushNotification.ts | 2 +- 6 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/web/src/app/notification/_utils/getNotificationRoute.ts b/apps/web/src/app/notification/_utils/getNotificationRoute.ts index 9cc0ac45..bf0e1a11 100644 --- a/apps/web/src/app/notification/_utils/getNotificationRoute.ts +++ b/apps/web/src/app/notification/_utils/getNotificationRoute.ts @@ -18,6 +18,7 @@ export const getNotificationRoute = ( case 'TOURNAMENT_RESULT_READY': return ROUTES.TOURNAMENT_RESULT(refId); case 'ITEM_PARSING_COMPLETED': + case 'ITEM_PARSING_INCOMPLETE': case 'ITEM_PARSING_FAILED': if (extra?.kind === 'TOURNAMENT' && extra.tournamentId) { return ROUTES.TOURNAMENT_CREATE(extra.tournamentId); diff --git a/apps/web/src/hooks/useNotificationSSE.ts b/apps/web/src/hooks/useNotificationSSE.ts index 62071d5e..f1874e6d 100644 --- a/apps/web/src/hooks/useNotificationSSE.ts +++ b/apps/web/src/hooks/useNotificationSSE.ts @@ -167,6 +167,8 @@ export const useNotificationSSE = (enabled: boolean) => { } toast.success(message); break; + /** 미완성은 실패와 갱신 대상이 같고 문구만 다르다 */ + case 'ITEM_PARSING_INCOMPLETE': case 'ITEM_PARSING_FAILED': if (payload.kind === 'TOURNAMENT' && payload.tournamentId != null) { queryClient.invalidateQueries({ @@ -178,7 +180,11 @@ export const useNotificationSSE = (enabled: boolean) => { predicate: query => isWishQueryOfItem(query, payload.refId), }); } - toast.error(message, { duration: 5000 }); + if (payload.type === 'ITEM_PARSING_INCOMPLETE') { + toast.info(message, { duration: 5000 }); + } else { + toast.error(message, { duration: 5000 }); + } break; case 'TOURNAMENT_STARTED': queryClient.invalidateQueries({ queryKey: ['tournament', payload.refId] }); diff --git a/apps/web/src/types/notification.ts b/apps/web/src/types/notification.ts index c7e0d2ee..2a681575 100644 --- a/apps/web/src/types/notification.ts +++ b/apps/web/src/types/notification.ts @@ -7,6 +7,8 @@ export type NotificationTypeT = | 'TOURNAMENT_COMPLETED' | 'TOURNAMENT_RESULT_READY' | 'ITEM_PARSING_COMPLETED' + /** 추출이 일부 필드만 채운 경우 — 사용자가 나머지를 채워야 한다 */ + | 'ITEM_PARSING_INCOMPLETE' | 'ITEM_PARSING_FAILED' | 'ANNOUNCEMENT'; @@ -40,7 +42,7 @@ export type SilentSyncSsePayloadT = type: 'TOURNAMENT_ITEM_PARSED'; tournamentId: number; tournamentItemId: number; - status: 'READY' | 'FAILED'; + status: 'READY' | 'INCOMPLETE' | 'FAILED'; } | { type: 'UNREAD_COUNT_CHANGED'; diff --git a/apps/web/src/utils/pushNotificationRoute.ts b/apps/web/src/utils/pushNotificationRoute.ts index 0a72bb7d..20de0a6d 100644 --- a/apps/web/src/utils/pushNotificationRoute.ts +++ b/apps/web/src/utils/pushNotificationRoute.ts @@ -8,6 +8,7 @@ export const getPushNotificationRoute = (payload: DeepLinkPayloadT) => { case PUSH_NOTIFICATION_TYPE.TOURNAMENT_ITEM_ADDED: return ROUTES.TOURNAMENT_CREATE(payload.refId); case PUSH_NOTIFICATION_TYPE.ITEM_PARSING_COMPLETED: + case PUSH_NOTIFICATION_TYPE.ITEM_PARSING_INCOMPLETE: case PUSH_NOTIFICATION_TYPE.ITEM_PARSING_FAILED: if (payload.kind === 'TOURNAMENT' && payload.tournamentId) { return ROUTES.TOURNAMENT_CREATE(payload.tournamentId); diff --git a/packages/core/src/consts/webBridge.ts b/packages/core/src/consts/webBridge.ts index 225d2f35..1122e5d1 100644 --- a/packages/core/src/consts/webBridge.ts +++ b/packages/core/src/consts/webBridge.ts @@ -60,6 +60,7 @@ export const PUSH_NOTIFICATION_TYPE = { TOURNAMENT_JOINED: 'TOURNAMENT_JOINED', TOURNAMENT_ITEM_ADDED: 'TOURNAMENT_ITEM_ADDED', ITEM_PARSING_COMPLETED: 'ITEM_PARSING_COMPLETED', + ITEM_PARSING_INCOMPLETE: 'ITEM_PARSING_INCOMPLETE', ITEM_PARSING_FAILED: 'ITEM_PARSING_FAILED', } as const; diff --git a/packages/core/src/types/pushNotification.ts b/packages/core/src/types/pushNotification.ts index e0b0caf8..2ec87d50 100644 --- a/packages/core/src/types/pushNotification.ts +++ b/packages/core/src/types/pushNotification.ts @@ -53,7 +53,7 @@ export type DeepLinkPayloadT = refId: number; } | { - type: 'ITEM_PARSING_COMPLETED' | 'ITEM_PARSING_FAILED'; + type: 'ITEM_PARSING_COMPLETED' | 'ITEM_PARSING_INCOMPLETE' | 'ITEM_PARSING_FAILED'; refId: number; kind: 'WISH' | 'TOURNAMENT'; tournamentId?: number; From 351a437f58efc4a255097e50851001858b8f28ee Mon Sep 17 00:00:00 2001 From: kanghaeun Date: Sun, 16 Aug 2026 00:22:05 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=8B=B1=20=EC=83=81=ED=83=9C=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/hooks/useNotificationSSE.ts | 2 +- apps/web/src/types/notification.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/web/src/hooks/useNotificationSSE.ts b/apps/web/src/hooks/useNotificationSSE.ts index f1874e6d..87afea04 100644 --- a/apps/web/src/hooks/useNotificationSSE.ts +++ b/apps/web/src/hooks/useNotificationSSE.ts @@ -167,7 +167,7 @@ export const useNotificationSSE = (enabled: boolean) => { } toast.success(message); break; - /** 미완성은 실패와 갱신 대상이 같고 문구만 다르다 */ + /** 미완성·실패 모두 동일한 데이터를 갱신하고, 사용자 안내만 다르다. */ case 'ITEM_PARSING_INCOMPLETE': case 'ITEM_PARSING_FAILED': if (payload.kind === 'TOURNAMENT' && payload.tournamentId != null) { diff --git a/apps/web/src/types/notification.ts b/apps/web/src/types/notification.ts index 2a681575..29c1edae 100644 --- a/apps/web/src/types/notification.ts +++ b/apps/web/src/types/notification.ts @@ -7,7 +7,6 @@ export type NotificationTypeT = | 'TOURNAMENT_COMPLETED' | 'TOURNAMENT_RESULT_READY' | 'ITEM_PARSING_COMPLETED' - /** 추출이 일부 필드만 채운 경우 — 사용자가 나머지를 채워야 한다 */ | 'ITEM_PARSING_INCOMPLETE' | 'ITEM_PARSING_FAILED' | 'ANNOUNCEMENT';