import { prisma } from '@/libs/prisma' import { ERROR_MESSAGES } from '@/utils/common-utils' import { SubmitTargetResponse } from '@/types/Survey' import { HttpStatusCode } from 'axios' import { ApiError } from 'next/dist/server/api-utils' import { Prisma } from '@prisma/client' export class SubmissionService { private storeId: string private role: string private readonly BASE_QUERY = ` DECLARE @storeId NVARCHAR(50); SET @storeId = @p1; OPEN SYMMETRIC KEY SYMMETRICKEY DECRYPTION BY CERTIFICATE CERTI_QSPJP; ` constructor(storeId: string, role: string) { this.storeId = storeId this.role = role } /** * @description 제출 대상 조회 * @returns {Promise} 제출 대상 데이터 */ async getSubmissionTarget(): Promise { switch (this.role) { case 'Admin_Sub': return this.getSubmissionTargetAdminSub() case 'Builder': return this.getSubmissionTargetBuilder() default: return new ApiError(HttpStatusCode.BadRequest, ERROR_MESSAGES.BAD_REQUEST) } } /** * @description 2차점의 매핑 된 제출 대상 판매점 조회 (Admin_Sub - Musubi) * @returns {Promise} 제출 대상 데이터 */ private async getSubmissionTargetAdminSub(): Promise { const query = ` SELECT MCS.STORE_ID AS targetStoreId , MCS.STORE_QCAST_NM AS targetStoreNm , MCP.EOS_LOGIN_ID AS repUserId , CONVERT(NVARCHAR(100), DecryptByKey(MCP.EMAIL)) AS repUserEmail , MCP.AUTHORITY AS auth FROM MS_CUST_STOREID MCS WITH(NOLOCK) LEFT OUTER JOIN MS_CUST_PERSON MCP WITH(NOLOCK) ON MCS.COMP_CD = MCP.COMP_CD AND MCS.STORE_ID = MCP.STORE_ID AND MCP.DEL_YN = 'N' WHERE MCS.COMP_CD = '5200' AND MCS.STORE_ID IN (SELECT STORE_ID FROM MS_CUST_AGENCY_STOREID WHERE AGENCY_STORE_ID = @storeId AND DEL_YN = 'N') AND MCP.EMAIL IS NOT NULL AND MCS.DEL_YN = 'N'; CLOSE SYMMETRIC KEY SYMMETRICKEY; ` return await prisma.$queryRawUnsafe(this.BASE_QUERY + query, this.storeId) } /** * @description 2차점 시공권한 user의 매핑 된 제출 대상 판매점 조회 (Builder - Musubi) * @returns {Promise} 제출 대상 데이터 */ private async getSubmissionTargetBuilder(): Promise { const query = ` SELECT MCAS.AGENCY_STORE_ID AS targetStoreId , MCAS.AGENCY_QCAST_NM AS targetStoreNm , BQU.USER_ID AS repUserId , CONVERT(NVARCHAR(100), DecryptByKey(BQU.EMAIL)) AS repUserEmail , BQU.USER_AUTH_CD AS auth FROM MS_CUST_AGENCY_STOREID MCAS WITH(NOLOCK) LEFT OUTER JOIN BC_QM_USER BQU WITH(NOLOCK) ON MCAS.COMP_CD = BQU.COMP_CD AND MCAS.AGENCY_STORE_ID = BQU.AGENCY_STORE_ID AND MCAS.DEL_YN = 'N' WHERE MCAS.COMP_CD = '5200' AND MCAS.AGENCY_STORE_ID = @storeId AND BQU.EMAIL IS NOT NULL AND BQU.USER_AUTH_CD != 'B' AND MCAS.DEL_YN = 'N'; CLOSE SYMMETRIC KEY SYMMETRICKEY; ` return await prisma.$queryRawUnsafe(this.BASE_QUERY + query, this.storeId) } /** * @description API ROUTE 에러 처리 * @param error 에러 객체 * @returns {ApiError} 에러 객체 */ handleRouteError(error: any): ApiError { console.error('❌ API ROUTE ERROR : ', error) if ( error instanceof Prisma.PrismaClientInitializationError || error instanceof Prisma.PrismaClientUnknownRequestError || error instanceof Prisma.PrismaClientRustPanicError || error instanceof Prisma.PrismaClientValidationError || error instanceof Prisma.PrismaClientUnknownRequestError ) { return new ApiError(HttpStatusCode.InternalServerError, ERROR_MESSAGES.PRISMA_ERROR) } return new ApiError(error.statusCode ?? HttpStatusCode.InternalServerError, error.message ?? ERROR_MESSAGES.FETCH_ERROR) } /** * @description 비동기 함수 try-catch 처리 함수 * @param func 비동기 함수 * @returns {Promise} 에러 객체 또는 함수 결과 */ async tryFunction(func: () => Promise): Promise { try { return await func() } catch (error) { return this.handleRouteError(error) } } }