'use server'; import { isNextRedirectError } from '@/lib/utils/redirect-error'; import { serverFetch } from '@/lib/api/fetch-wrapper'; import type { NotificationSettings } from './types'; import { DEFAULT_NOTIFICATION_SETTINGS } from './types'; // ===== 알림 설정 조회 ===== export async function getNotificationSettings(): Promise<{ success: boolean; data: NotificationSettings; error?: string; __authError?: boolean; }> { try { const { response, error } = await serverFetch( `${process.env.NEXT_PUBLIC_API_URL}/api/v1/settings/notifications`, { method: 'GET', cache: 'no-store', } ); if (error) { return { success: false, data: DEFAULT_NOTIFICATION_SETTINGS, error: error.message, __authError: error.code === 'UNAUTHORIZED', }; } if (!response || !response.ok) { console.warn('[NotificationActions] GET settings error:', response?.status); return { success: true, data: DEFAULT_NOTIFICATION_SETTINGS, }; } const result = await response.json(); if (!result.success || !result.data) { return { success: true, data: DEFAULT_NOTIFICATION_SETTINGS, }; } // API → Frontend 변환 return { success: true, data: transformApiToFrontend(result.data), }; } catch (error) { if (isNextRedirectError(error)) throw error; console.error('[NotificationActions] getNotificationSettings error:', error); return { success: true, data: DEFAULT_NOTIFICATION_SETTINGS, }; } } // ===== 알림 설정 저장 ===== export async function saveNotificationSettings( settings: NotificationSettings ): Promise<{ success: boolean; error?: string; __authError?: boolean }> { try { const apiData = transformFrontendToApi(settings); const { response, error } = await serverFetch( `${process.env.NEXT_PUBLIC_API_URL}/api/v1/settings/notifications`, { method: 'PUT', body: JSON.stringify(apiData), } ); if (error) { return { success: false, error: error.message, __authError: error.code === 'UNAUTHORIZED', }; } if (!response) { return { success: false, error: '알림 설정 저장에 실패했습니다.', }; } const result = await response.json(); if (!response.ok || !result.success) { return { success: false, error: result.message || '알림 설정 저장에 실패했습니다.', }; } return { success: true }; } catch (error) { if (isNextRedirectError(error)) throw error; console.error('[NotificationActions] saveNotificationSettings error:', error); return { success: false, error: '서버 오류가 발생했습니다.', }; } } // ===== API → Frontend 변환 (기본값과 병합) ===== function transformApiToFrontend(apiData: Record): NotificationSettings { // API 응답에 soundType이 없을 수 있으므로 기본값과 병합 const data = apiData as Partial; return { notice: { enabled: data.notice?.enabled ?? DEFAULT_NOTIFICATION_SETTINGS.notice.enabled, notice: { ...DEFAULT_NOTIFICATION_SETTINGS.notice.notice, ...data.notice?.notice }, event: { ...DEFAULT_NOTIFICATION_SETTINGS.notice.event, ...data.notice?.event }, }, schedule: { enabled: data.schedule?.enabled ?? DEFAULT_NOTIFICATION_SETTINGS.schedule.enabled, vatReport: { ...DEFAULT_NOTIFICATION_SETTINGS.schedule.vatReport, ...data.schedule?.vatReport }, incomeTaxReport: { ...DEFAULT_NOTIFICATION_SETTINGS.schedule.incomeTaxReport, ...data.schedule?.incomeTaxReport }, }, vendor: { enabled: data.vendor?.enabled ?? DEFAULT_NOTIFICATION_SETTINGS.vendor.enabled, newVendor: { ...DEFAULT_NOTIFICATION_SETTINGS.vendor.newVendor, ...data.vendor?.newVendor }, creditRating: { ...DEFAULT_NOTIFICATION_SETTINGS.vendor.creditRating, ...data.vendor?.creditRating }, }, attendance: { enabled: data.attendance?.enabled ?? DEFAULT_NOTIFICATION_SETTINGS.attendance.enabled, annualLeave: { ...DEFAULT_NOTIFICATION_SETTINGS.attendance.annualLeave, ...data.attendance?.annualLeave }, clockIn: { ...DEFAULT_NOTIFICATION_SETTINGS.attendance.clockIn, ...data.attendance?.clockIn }, late: { ...DEFAULT_NOTIFICATION_SETTINGS.attendance.late, ...data.attendance?.late }, absent: { ...DEFAULT_NOTIFICATION_SETTINGS.attendance.absent, ...data.attendance?.absent }, }, order: { enabled: data.order?.enabled ?? DEFAULT_NOTIFICATION_SETTINGS.order.enabled, salesOrder: { ...DEFAULT_NOTIFICATION_SETTINGS.order.salesOrder, ...data.order?.salesOrder }, purchaseOrder: { ...DEFAULT_NOTIFICATION_SETTINGS.order.purchaseOrder, ...data.order?.purchaseOrder }, approvalRequest: { ...DEFAULT_NOTIFICATION_SETTINGS.order.approvalRequest, ...data.order?.approvalRequest }, }, approval: { enabled: data.approval?.enabled ?? DEFAULT_NOTIFICATION_SETTINGS.approval.enabled, approvalRequest: { ...DEFAULT_NOTIFICATION_SETTINGS.approval.approvalRequest, ...data.approval?.approvalRequest }, draftApproved: { ...DEFAULT_NOTIFICATION_SETTINGS.approval.draftApproved, ...data.approval?.draftApproved }, draftRejected: { ...DEFAULT_NOTIFICATION_SETTINGS.approval.draftRejected, ...data.approval?.draftRejected }, draftCompleted: { ...DEFAULT_NOTIFICATION_SETTINGS.approval.draftCompleted, ...data.approval?.draftCompleted }, }, production: { enabled: data.production?.enabled ?? DEFAULT_NOTIFICATION_SETTINGS.production.enabled, safetyStock: { ...DEFAULT_NOTIFICATION_SETTINGS.production.safetyStock, ...data.production?.safetyStock }, productionComplete: { ...DEFAULT_NOTIFICATION_SETTINGS.production.productionComplete, ...data.production?.productionComplete }, }, }; } // ===== Frontend → API 변환 ===== function transformFrontendToApi(settings: NotificationSettings): Record { // 프론트엔드 형식이 이미 API 형식과 동일하다고 가정 // 필요시 camelCase → snake_case 변환 return settings as Record; }