🕐 커밋 시간: 2025. 11. 24. 17:07:32 📊 변경 통계: • 총 파일: 5개 • 추가: +64줄 • 삭제: -65줄 📁 추가된 파일: + com.twin.app.shoptime/REFACTORING_SUMMARY.md + com.twin.app.shoptime/src/actions/logActions.new.js + com.twin.app.shoptime/src/config/logConfig.js 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/playActions.js 🗑️ 삭제된 파일: - com.twin.app.shoptime/docs/todo/251122-detailpanel-diff.md 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선 • 개발 문서 및 가이드 개선 • 로깅 시스템 개선 • 소규모 기능 개선 • 코드 정리 및 최적화 Performance: 코드 최적화로 성능 개선 기대
401 lines
11 KiB
JavaScript
401 lines
11 KiB
JavaScript
/**
|
||
* 통합 로그 액션 (신규)
|
||
*
|
||
* 기존 logActions.js의 34개 함수를 하나의 sendLog() 함수로 통합
|
||
* 기존 코드는 유지하며, 새로운 코드부터 이 파일 사용
|
||
*
|
||
* 사용 예:
|
||
* dispatch(sendLog('LIVE', { patncNm: 'Samsung', patnrId: 'PAR001', ... }))
|
||
* dispatch(sendLog('PRODUCT_DETAIL', { prdtId: 'P123', patncNm: 'Samsung', ... }))
|
||
*/
|
||
|
||
import { TLogEvent } from '../api/TLogEvent';
|
||
import {
|
||
LOG_SCHEMA,
|
||
LOG_TYPES,
|
||
LOG_PREPROCESSORS,
|
||
isValidLogType,
|
||
getMissingFields,
|
||
getLogSchema,
|
||
getLogEndpoint,
|
||
getLogTpNo,
|
||
requiresTimeValidation,
|
||
isTotalLog,
|
||
} from '../config/logConfig';
|
||
import { formatGMTString, getTimeDifferenceByMilliseconds } from '../utils/helperMethods';
|
||
import { createDebugHelpers } from '../utils/debug';
|
||
import { URLS } from '../api/apiConfig';
|
||
|
||
// 디버그 헬퍼 설정
|
||
const DEBUG_MODE = false;
|
||
const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE);
|
||
|
||
/**
|
||
* 통합 로그 전송 함수
|
||
*
|
||
* @param {string} logType - 로그 타입 (LOG_TYPES의 상수 사용)
|
||
* @param {object} params - 로그 파라미터
|
||
* @param {function} callback - 성공 콜백 (선택사항)
|
||
* @returns {function} Redux thunk
|
||
*
|
||
* 예시:
|
||
* dispatch(sendLog('LIVE', {
|
||
* patncNm: 'Samsung',
|
||
* patnrId: 'PAR001',
|
||
* showId: 'SHW123',
|
||
* watchStrtDt: '2024-11-24T10:00:00Z',
|
||
* watchEndDt: '2024-11-24T10:05:00Z'
|
||
* }, () => {
|
||
* console.log('로그 전송 완료');
|
||
* }))
|
||
*/
|
||
export const sendLog = (logType, params = {}, callback) => (dispatch, getState) => {
|
||
// 1️⃣ 로그 타입 검증
|
||
if (!logType) {
|
||
derror('[sendLog] logType is required');
|
||
return;
|
||
}
|
||
|
||
if (!isValidLogType(logType)) {
|
||
derror(`[sendLog] Unknown log type: ${logType}`);
|
||
return;
|
||
}
|
||
|
||
const schema = getLogSchema(logType);
|
||
|
||
// 2️⃣ 필수 필드 검증
|
||
const missingFields = getMissingFields(logType, params);
|
||
if (missingFields.length > 0) {
|
||
dlog(
|
||
`[sendLog] Missing required fields for ${logType}:`,
|
||
missingFields,
|
||
`Expected: ${schema.requiredFields.join(', ')}`
|
||
);
|
||
return;
|
||
}
|
||
|
||
// 3️⃣ Redux state에서 자동 추가할 필드 조회
|
||
const commonState = getState().common;
|
||
const { entryMenu, nowMenu } = commonState?.menu || {};
|
||
|
||
// 4️⃣ 데이터 전처리 (타입별 커스텀 로직)
|
||
let processedParams = params;
|
||
if (LOG_PREPROCESSORS[logType]) {
|
||
processedParams = LOG_PREPROCESSORS[logType](params, getState);
|
||
}
|
||
|
||
// 5️⃣ 최종 파라미터 구성
|
||
let finalParams = {
|
||
...processedParams,
|
||
entryMenu: processedParams.entryMenu ?? entryMenu,
|
||
nowMenu: processedParams.nowMenu ?? nowMenu,
|
||
};
|
||
|
||
// 6️⃣ 로그 타입번호 추가 (TotalLog가 아닌 경우)
|
||
if (!isTotalLog(logType) && schema.logTpNo) {
|
||
finalParams.logTpNo = getLogTpNo(logType);
|
||
}
|
||
|
||
// 7️⃣ 시간 검증이 필요한 경우 처리 (LIVE, VOD)
|
||
if (requiresTimeValidation(logType)) {
|
||
const { watchStrtDt } = processedParams;
|
||
|
||
if (!watchStrtDt) {
|
||
dlog(`[sendLog] watchStrtDt is required for ${logType}`);
|
||
return;
|
||
}
|
||
|
||
// watchEndDt 자동 설정 (제공되지 않은 경우)
|
||
if (!finalParams.watchEndDt) {
|
||
finalParams.watchEndDt = formatGMTString(new Date());
|
||
}
|
||
|
||
// 시간 차이 검증
|
||
if (!getTimeDifferenceByMilliseconds(watchStrtDt, finalParams.watchEndDt)) {
|
||
dlog(
|
||
`[sendLog] Invalid time difference for ${logType}:`,
|
||
`startDt: ${watchStrtDt}, endDt: ${finalParams.watchEndDt}`
|
||
);
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 8️⃣ 에러 콜백
|
||
const onFail = (error) => {
|
||
derror(`[sendLog] onFail for ${logType}:`, error);
|
||
};
|
||
|
||
// 9️⃣ API 호출
|
||
const endpoint = getLogEndpoint(logType);
|
||
if (!endpoint) {
|
||
derror(`[sendLog] No endpoint found for ${logType}`);
|
||
return;
|
||
}
|
||
|
||
TLogEvent(
|
||
dispatch,
|
||
getState,
|
||
'post',
|
||
endpoint,
|
||
{},
|
||
finalParams,
|
||
callback,
|
||
onFail,
|
||
isTotalLog(logType) // totalLogFlag
|
||
);
|
||
};
|
||
|
||
/**
|
||
* 편의 함수: LIVE 로그
|
||
* 기존 sendLogLive()와 호환
|
||
*/
|
||
export const sendLogLiveNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.LIVE, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: VOD 로그
|
||
* 기존 sendLogVOD()와 호환
|
||
*/
|
||
export const sendLogVODNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.VOD, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: CURATION 로그
|
||
* 기존 sendLogCuration()와 호환
|
||
*/
|
||
export const sendLogCurationNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.CURATION, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: SECOND_LAYER 로그
|
||
* 기존 sendLogSecondLayer()와 호환
|
||
*/
|
||
export const sendLogSecondLayerNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.SECOND_LAYER, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: GNB 로그
|
||
* 기존 sendLogGNB()와 호환
|
||
*/
|
||
export const sendLogGNBNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.GNB, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: PRODUCT_DETAIL 로그
|
||
* 기존 sendLogProductDetail()와 호환
|
||
*/
|
||
export const sendLogProductDetailNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.PRODUCT_DETAIL, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: DETAIL 로그
|
||
* 기존 sendLogDetail()와 호환
|
||
*/
|
||
export const sendLogDetailNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.DETAIL, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: SHOP_BY_MOBILE 로그
|
||
* 기존 sendLogShopByMobile()와 호환
|
||
*/
|
||
export const sendLogShopByMobileNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.SHOP_BY_MOBILE, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: PARTNERS 로그
|
||
* 기존 sendLogPartners()와 호환
|
||
*/
|
||
export const sendLogPartnersNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.PARTNERS, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: MY_PAGE_ALERT_FLAG 로그
|
||
* 기존 sendLogMyPageAlertFlag()와 호환
|
||
*/
|
||
export const sendLogMyPageAlertFlagNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.MY_PAGE_ALERT_FLAG, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: MY_PAGE_MY_DELETE 로그
|
||
* 기존 sendLogMyPageMyDelete()와 호환
|
||
*/
|
||
export const sendLogMyPageMyDeleteNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.MY_PAGE_MY_DELETE, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: MY_PAGE_NOTICE 로그
|
||
* 기존 sendLogMyPageNotice()와 호환
|
||
*/
|
||
export const sendLogMyPageNoticeNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.MY_PAGE_NOTICE, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: SEARCH 로그
|
||
* 기존 sendLogSearch()와 호환
|
||
*/
|
||
export const sendLogSearchNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.SEARCH, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: SEARCH_CLICK 로그
|
||
* 기존 sendLogSearchClick()와 호환
|
||
*/
|
||
export const sendLogSearchClickNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.SEARCH_CLICK, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: UPCOMING_FLAG 로그
|
||
* 기존 sendLogUpcomingFlag()와 호환
|
||
*/
|
||
export const sendLogUpcomingFlagNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.UPCOMING_FLAG, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: ALARM_POP 로그
|
||
* 기존 sendLogAlarmPop()와 호환
|
||
*/
|
||
export const sendLogAlarmPopNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.ALARM_POP, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: ALARM_CLICK 로그
|
||
* 기존 sendLogAlarmClick()와 호환
|
||
*/
|
||
export const sendLogAlarmClickNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.ALARM_CLICK, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: THEME_PRODUCT 로그
|
||
* 기존 sendLogThemeProduct()와 호환
|
||
*/
|
||
export const sendLogThemeProductNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.THEME_PRODUCT, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: TOP_CONTENTS 로그
|
||
* 기존 sendLogTopContents()와 호환
|
||
*/
|
||
export const sendLogTopContentsNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.TOP_CONTENTS, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: TERMS 로그
|
||
* 기존 sendLogTerms()와 호환
|
||
*/
|
||
export const sendLogTermsNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.TERMS, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: LG_ACCOUNT_LOGIN 로그
|
||
* 기존 sendLogLgAccountLogin()와 호환
|
||
*/
|
||
export const sendLogLgAccountLoginNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.LG_ACCOUNT_LOGIN, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: ORDER_BTN_CLICK 로그
|
||
* 기존 sendLogOrderBtnClick()와 호환
|
||
*/
|
||
export const sendLogOrderBtnClickNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.ORDER_BTN_CLICK, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: ORDER_CHANGE 로그
|
||
* 기존 sendLogOrderChange()와 호환
|
||
*/
|
||
export const sendLogOrderChangeNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.ORDER_CHANGE, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: COUPON_USE 로그
|
||
* 기존 sendLogCouponUse()와 호환
|
||
*/
|
||
export const sendLogCouponUseNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.COUPON_USE, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: PAYMENT_ENTRY 로그
|
||
* 기존 sendLogPaymentEntry()와 호환
|
||
*/
|
||
export const sendLogPaymentEntryNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.PAYMENT_ENTRY, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: PAYMENT_COMPLETE 로그
|
||
* 기존 sendLogPaymentComplete()와 호환
|
||
*/
|
||
export const sendLogPaymentCompleteNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.PAYMENT_COMPLETE, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: FEATURED_BRANDS 로그
|
||
* 기존 sendLogFeaturedBrands()와 호환
|
||
*/
|
||
export const sendLogFeaturedBrandsNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.FEATURED_BRANDS, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: MY_INFO_EDIT 로그
|
||
* 기존 sendLogMyInfoEdit()와 호환
|
||
*/
|
||
export const sendLogMyInfoEditNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.MY_INFO_EDIT, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: CHECKOUT_BTN_CLICK 로그
|
||
* 기존 sendLogCheckOutBtnClick()와 호환
|
||
*/
|
||
export const sendLogCheckOutBtnClickNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.CHECKOUT_BTN_CLICK, params, callback);
|
||
|
||
/**
|
||
* 편의 함수: TOTAL_RECOMMEND 로그
|
||
* 기존 sendLogTotalRecommend()와 호환
|
||
*/
|
||
export const sendLogTotalRecommendNew = (params, callback) => (dispatch, getState) => {
|
||
const onSuccess = callback;
|
||
const onFail = (error) => {
|
||
derror('[sendLogTotalRecommendNew] onFail', error);
|
||
};
|
||
|
||
// TotalLog는 특별히 postTotalLog처럼 처리
|
||
TLogEvent(
|
||
dispatch,
|
||
getState,
|
||
'post',
|
||
URLS.LOG_TOTAL_RECOMMEND,
|
||
{},
|
||
params,
|
||
onSuccess,
|
||
onFail,
|
||
true // totalLogFlag = true
|
||
);
|
||
};
|
||
|
||
/**
|
||
* 편의 함수: DEEPLINK_FLAG 로그
|
||
* 기존 sendLogDeepLinkFlag()와 호환
|
||
*/
|
||
export const sendLogDeepLinkFlagNew = (params, callback) =>
|
||
sendLog(LOG_TYPES.DEEPLINK_FLAG, params, callback);
|
||
|
||
/**
|
||
* ========================================
|
||
* 내보내기 정리
|
||
* ========================================
|
||
*
|
||
* 사용 방법:
|
||
*
|
||
* 1️⃣ 통합 함수 직접 사용 (권장):
|
||
* dispatch(sendLog('LIVE', { patncNm: '...', ... }))
|
||
* dispatch(sendLog('PRODUCT_DETAIL', { prdtId: '...', ... }))
|
||
*
|
||
* 2️⃣ 편의 함수 사용 (기존 코드와 유사):
|
||
* dispatch(sendLogLiveNew({ patncNm: '...', ... }))
|
||
* dispatch(sendLogProductDetailNew({ prdtId: '...', ... }))
|
||
*
|
||
* 3️⃣ 로그 타입 상수 사용:
|
||
* import { LOG_TYPES } from '../config/logConfig'
|
||
* dispatch(sendLog(LOG_TYPES.LIVE, params))
|
||
*/
|