- ApiResponse 타입에 authError 플래그 추가 - today-issue.ts에 인증 에러 감지 로직 추가 - AuthenticatedLayout에서 authError 시 토큰 갱신 후 재시도 - 토큰 갱신 실패 시 폴링 중지하여 반복 에러 방지
120 lines
3.3 KiB
TypeScript
120 lines
3.3 KiB
TypeScript
'use server';
|
|
|
|
/**
|
|
* TodayIssue API 서비스
|
|
* 헤더 알림 기능을 위한 API 호출 함수
|
|
*/
|
|
|
|
import { apiClient } from './index';
|
|
import { AuthError } from './errors';
|
|
import type {
|
|
ApiResponse,
|
|
TodayIssueUnreadResponse,
|
|
TodayIssueUnreadCountResponse,
|
|
TodayIssueMarkAllReadResponse,
|
|
} from '@/types/today-issue';
|
|
|
|
/**
|
|
* 인증 에러인지 확인
|
|
*/
|
|
function isAuthenticationError(error: unknown): boolean {
|
|
if (error instanceof AuthError) return true;
|
|
if (error && typeof error === 'object') {
|
|
const err = error as { status?: number; code?: string; message?: string };
|
|
if (err.status === 401) return true;
|
|
if (err.code === 'AUTH_ERROR') return true;
|
|
if (err.message?.includes('회원정보') || err.message?.includes('인증')) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 읽지 않은 이슈 목록 조회 (헤더 알림용)
|
|
* @param limit 조회할 최대 항목 수 (기본 10)
|
|
*/
|
|
export async function getUnreadTodayIssues(limit: number = 10): Promise<ApiResponse<TodayIssueUnreadResponse>> {
|
|
try {
|
|
const response = await apiClient.get<ApiResponse<TodayIssueUnreadResponse>>(
|
|
'/today-issues/unread',
|
|
{ params: { limit: String(limit) } }
|
|
);
|
|
return response;
|
|
} catch (error) {
|
|
console.error('[TodayIssue] getUnreadTodayIssues error:', error);
|
|
|
|
// 인증 에러인 경우 authError 플래그 설정
|
|
if (isAuthenticationError(error)) {
|
|
return {
|
|
success: false,
|
|
message: '인증이 만료되었습니다.',
|
|
data: { items: [], total: 0 },
|
|
authError: true,
|
|
};
|
|
}
|
|
|
|
// 일반 에러
|
|
return {
|
|
success: false,
|
|
message: '알림을 불러오는데 실패했습니다.',
|
|
data: { items: [], total: 0 },
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 읽지 않은 이슈 개수 조회 (헤더 뱃지용)
|
|
*/
|
|
export async function getUnreadTodayIssueCount(): Promise<ApiResponse<TodayIssueUnreadCountResponse>> {
|
|
try {
|
|
const response = await apiClient.get<ApiResponse<TodayIssueUnreadCountResponse>>(
|
|
'/today-issues/unread/count'
|
|
);
|
|
return response;
|
|
} catch (error) {
|
|
console.error('[TodayIssue] getUnreadTodayIssueCount error:', error);
|
|
return {
|
|
success: false,
|
|
message: '알림 개수를 불러오는데 실패했습니다.',
|
|
data: { count: 0 },
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 이슈 읽음 처리
|
|
* @param id 이슈 ID
|
|
*/
|
|
export async function markTodayIssueAsRead(id: number): Promise<ApiResponse<null>> {
|
|
try {
|
|
const response = await apiClient.post<ApiResponse<null>>(
|
|
`/today-issues/${id}/read`
|
|
);
|
|
return response;
|
|
} catch (error) {
|
|
console.error('[TodayIssue] markTodayIssueAsRead error:', error);
|
|
return {
|
|
success: false,
|
|
message: '읽음 처리에 실패했습니다.',
|
|
data: null,
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 모든 이슈 읽음 처리
|
|
*/
|
|
export async function markAllTodayIssuesAsRead(): Promise<ApiResponse<TodayIssueMarkAllReadResponse>> {
|
|
try {
|
|
const response = await apiClient.post<ApiResponse<TodayIssueMarkAllReadResponse>>(
|
|
'/today-issues/read-all'
|
|
);
|
|
return response;
|
|
} catch (error) {
|
|
console.error('[TodayIssue] markAllTodayIssuesAsRead error:', error);
|
|
return {
|
|
success: false,
|
|
message: '모두 읽음 처리에 실패했습니다.',
|
|
data: { count: 0 },
|
|
};
|
|
}
|
|
} |