refactor: add service layer to centralize business logic
- 코드 가독성 및 유지보수성 향상을 위한 서비스 레이어 도입
This commit is contained in:
parent
2edde77bae
commit
f6729069d7
@ -1,45 +0,0 @@
|
|||||||
import { prisma } from '@/libs/prisma'
|
|
||||||
import { NextRequest, NextResponse } from 'next/server'
|
|
||||||
import { loggerWrapper } from '@/libs/api-wrapper'
|
|
||||||
import { SubmitTargetResponse } from '@/types/Survey'
|
|
||||||
import { ERROR_MESSAGES } from '@/utils/common-utils'
|
|
||||||
import { HttpStatusCode } from 'axios'
|
|
||||||
|
|
||||||
// 2차점이 자신에게 매핑 된 1차 판매점과 관리자 정보 조회
|
|
||||||
async function getSubMissionAdminSub(request: NextRequest): Promise<NextResponse> {
|
|
||||||
try {
|
|
||||||
const { searchParams } = new URL(request.url)
|
|
||||||
const storeId = searchParams.get('storeId')
|
|
||||||
|
|
||||||
if (!storeId) {
|
|
||||||
return NextResponse.json({ error: ERROR_MESSAGES.BAD_REQUEST }, { status: HttpStatusCode.BadRequest })
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = `
|
|
||||||
OPEN SYMMETRIC KEY SYMMETRICKEY DECRYPTION BY CERTIFICATE CERTI_QSPJP;
|
|
||||||
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 = (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;
|
|
||||||
`
|
|
||||||
const data: SubmitTargetResponse[] = await prisma.$queryRawUnsafe(query)
|
|
||||||
return NextResponse.json(data)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ API ROUTE ERROR:', error)
|
|
||||||
return NextResponse.json({ error: ERROR_MESSAGES.FETCH_ERROR }, { status: HttpStatusCode.InternalServerError })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GET = loggerWrapper(getSubMissionAdminSub)
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
import { prisma } from '@/libs/prisma'
|
|
||||||
import { NextRequest, NextResponse } from 'next/server'
|
|
||||||
import { loggerWrapper } from '@/libs/api-wrapper'
|
|
||||||
import { ERROR_MESSAGES } from '@/utils/common-utils'
|
|
||||||
import { HttpStatusCode } from 'axios'
|
|
||||||
|
|
||||||
type SuperPerson = {
|
|
||||||
storeId: string
|
|
||||||
salesOfficeCd: string
|
|
||||||
fromEmail: string
|
|
||||||
toEmail: string
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSubmissionAdmin(request: NextRequest): Promise<NextResponse> {
|
|
||||||
try {
|
|
||||||
const { searchParams } = new URL(request.url)
|
|
||||||
const storeId = searchParams.get('storeId')
|
|
||||||
|
|
||||||
const query = `
|
|
||||||
OPEN SYMMETRIC KEY SYMMETRICKEY DECRYPTION BY CERTIFICATE CERTI_QSPJP;
|
|
||||||
SELECT
|
|
||||||
MCSA.STORE_ID
|
|
||||||
, BCL.CODE AS SALES_OFFICE_CD
|
|
||||||
, REF_CHR1 AS FROM_E_MAIL
|
|
||||||
, REF_CHR2 AS TO_E_MAIL
|
|
||||||
FROM MS_CUST_STOREID_ADDITNL MCSA WITH(NOLOCK)
|
|
||||||
LEFT OUTER JOIN IF_PERSON_OFFICE_MAPPING IPOM WITH(NOLOCK)
|
|
||||||
ON MCSA.KAM_ID = IPOM.LIFNR
|
|
||||||
AND IF_STS = 'R'
|
|
||||||
AND VKBUR IS NOT NULL
|
|
||||||
AND VKBUR != ''
|
|
||||||
INNER JOIN BC_COMM_L BCL WITH(NOLOCK)
|
|
||||||
ON BCL.CODE = IPOM.VKBUR
|
|
||||||
AND BCL.HEAD_CD = '103200'
|
|
||||||
AND BCL.DEL_YN = 'N'
|
|
||||||
WHERE MCSA.COMP_CD = '5200'
|
|
||||||
AND MCSA.STORE_ID = '${storeId}'
|
|
||||||
AND MCSA.DEL_YN = 'N'
|
|
||||||
;
|
|
||||||
CLOSE SYMMETRIC KEY SYMMETRICKEY;
|
|
||||||
`
|
|
||||||
const data: SuperPerson[] = await prisma.$queryRawUnsafe(query)
|
|
||||||
return NextResponse.json(data)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ API ROUTE ERROR:', error)
|
|
||||||
return NextResponse.json({ error: ERROR_MESSAGES.FETCH_ERROR }, { status: HttpStatusCode.InternalServerError })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GET = loggerWrapper(getSubmissionAdmin)
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
import { prisma } from '@/libs/prisma'
|
|
||||||
import { SubmitTargetResponse } from '@/types/Survey'
|
|
||||||
import { NextRequest, NextResponse } from 'next/server'
|
|
||||||
import { loggerWrapper } from '@/libs/api-wrapper'
|
|
||||||
import { ERROR_MESSAGES } from '@/utils/common-utils'
|
|
||||||
import { HttpStatusCode } from 'axios'
|
|
||||||
|
|
||||||
// 2차점의 시공권한 user가 해당 판매점의 관리자 정보 조회
|
|
||||||
// N == 일반유저, S == 수퍼유저, B == 시공권한유저
|
|
||||||
async function getSubmissionBuilder(request: NextRequest): Promise<NextResponse> {
|
|
||||||
try {
|
|
||||||
const { searchParams } = new URL(request.url)
|
|
||||||
const id = searchParams.get('id')
|
|
||||||
|
|
||||||
if (!id) {
|
|
||||||
return NextResponse.json({ error: ERROR_MESSAGES.BAD_REQUEST }, { status: HttpStatusCode.BadRequest })
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = `
|
|
||||||
OPEN SYMMETRIC KEY SYMMETRICKEY DECRYPTION BY CERTIFICATE CERTI_QSPJP;
|
|
||||||
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 = '${id}'
|
|
||||||
AND BQU.EMAIL IS NOT NULL
|
|
||||||
AND BQU.USER_AUTH_CD != 'B'
|
|
||||||
AND MCAS.DEL_YN = 'N';
|
|
||||||
CLOSE SYMMETRIC KEY SYMMETRICKEY;
|
|
||||||
`
|
|
||||||
const data: SubmitTargetResponse[] = await prisma.$queryRawUnsafe(query)
|
|
||||||
return NextResponse.json(data)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ API ROUTE ERROR:', error)
|
|
||||||
return NextResponse.json({ error: ERROR_MESSAGES.FETCH_ERROR }, { status: HttpStatusCode.InternalServerError })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GET = loggerWrapper(getSubmissionBuilder)
|
|
||||||
@ -1,17 +1,20 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server'
|
import { NextRequest, NextResponse } from 'next/server'
|
||||||
import { loggerWrapper } from '@/libs/api-wrapper'
|
import { SubmissionService } from './service'
|
||||||
import { ERROR_MESSAGES } from '@/utils/common-utils'
|
|
||||||
import { HttpStatusCode } from 'axios'
|
import { HttpStatusCode } from 'axios'
|
||||||
import { SubmissionService } from '../service'
|
import { ERROR_MESSAGES } from '@/utils/common-utils'
|
||||||
|
import { loggerWrapper } from '@/libs/api-wrapper'
|
||||||
|
|
||||||
async function getSubmissionSuper(request: NextRequest): Promise<NextResponse> {
|
async function getSubmitTargetData(request: NextRequest): Promise<NextResponse> {
|
||||||
try {
|
try {
|
||||||
const { searchParams } = new URL(request.url)
|
const { searchParams } = new URL(request.url)
|
||||||
const storeId = searchParams.get('storeId')
|
const storeId = searchParams.get('storeId')
|
||||||
if (!storeId) {
|
const role = searchParams.get('role')
|
||||||
|
|
||||||
|
if (!storeId || !role) {
|
||||||
return NextResponse.json({ error: ERROR_MESSAGES.BAD_REQUEST }, { status: HttpStatusCode.BadRequest })
|
return NextResponse.json({ error: ERROR_MESSAGES.BAD_REQUEST }, { status: HttpStatusCode.BadRequest })
|
||||||
}
|
}
|
||||||
const submissionService = new SubmissionService(storeId, 'Super')
|
|
||||||
|
const submissionService = new SubmissionService(storeId, role)
|
||||||
const data = await submissionService.getSubmissionTarget()
|
const data = await submissionService.getSubmissionTarget()
|
||||||
return NextResponse.json(data)
|
return NextResponse.json(data)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -20,4 +23,4 @@ async function getSubmissionSuper(request: NextRequest): Promise<NextResponse> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GET = loggerWrapper(getSubmissionSuper)
|
export const GET = loggerWrapper(getSubmitTargetData)
|
||||||
126
src/app/api/submission/service.ts
Normal file
126
src/app/api/submission/service.ts
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
import { prisma } from '@/libs/prisma'
|
||||||
|
import { SubmitTargetResponse } from '@/types/Survey'
|
||||||
|
|
||||||
|
export class SubmissionService {
|
||||||
|
private storeId: string
|
||||||
|
private role: string
|
||||||
|
|
||||||
|
constructor(storeId: string, role: string) {
|
||||||
|
this.storeId = storeId
|
||||||
|
this.role = role
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSubmissionTarget(): Promise<SubmitTargetResponse[] | null> {
|
||||||
|
switch (this.role) {
|
||||||
|
case 'Admin':
|
||||||
|
return this.getSubmissionTargetAdmin()
|
||||||
|
case 'Admin_Sub':
|
||||||
|
return this.getSubmissionTargetAdminSub()
|
||||||
|
case 'Builder':
|
||||||
|
return this.getSubmissionTargetBuilder()
|
||||||
|
case 'Super':
|
||||||
|
return this.getSubmissionTargetSuper()
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getSubmissionTargetAdmin(): Promise<SubmitTargetResponse[] | null> {
|
||||||
|
const query = `
|
||||||
|
OPEN SYMMETRIC KEY SYMMETRICKEY DECRYPTION BY CERTIFICATE CERTI_QSPJP;
|
||||||
|
SELECT
|
||||||
|
MCSA.STORE_ID AS targetStoreId
|
||||||
|
, BCL.CODE AS salesOfficeCd
|
||||||
|
, REF_CHR1 AS fromEmail
|
||||||
|
, REF_CHR2 AS toEmail
|
||||||
|
FROM MS_CUST_STOREID_ADDITNL MCSA WITH(NOLOCK)
|
||||||
|
LEFT OUTER JOIN IF_PERSON_OFFICE_MAPPING IPOM WITH(NOLOCK)
|
||||||
|
ON MCSA.KAM_ID = IPOM.LIFNR
|
||||||
|
AND IF_STS = 'R'
|
||||||
|
AND VKBUR IS NOT NULL
|
||||||
|
AND VKBUR != ''
|
||||||
|
INNER JOIN BC_COMM_L BCL WITH(NOLOCK)
|
||||||
|
ON BCL.CODE = IPOM.VKBUR
|
||||||
|
AND BCL.HEAD_CD = '103200'
|
||||||
|
AND BCL.DEL_YN = 'N'
|
||||||
|
WHERE MCSA.COMP_CD = '5200'
|
||||||
|
AND MCSA.STORE_ID = '${this.storeId}'
|
||||||
|
AND MCSA.DEL_YN = 'N';
|
||||||
|
CLOSE SYMMETRIC KEY SYMMETRICKEY;
|
||||||
|
`
|
||||||
|
const data: SubmitTargetResponse[] = await prisma.$queryRawUnsafe(query)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async getSubmissionTargetAdminSub(): Promise<SubmitTargetResponse[] | null> {
|
||||||
|
const query = `
|
||||||
|
OPEN SYMMETRIC KEY SYMMETRICKEY DECRYPTION BY CERTIFICATE CERTI_QSPJP;
|
||||||
|
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 = (SELECT STORE_ID FROM MS_CUST_AGENCY_STOREID WHERE AGENCY_STORE_ID = '${this.storeId}' AND DEL_YN = 'N')
|
||||||
|
AND MCP.EMAIL IS NOT NULL
|
||||||
|
AND MCS.DEL_YN = 'N';
|
||||||
|
CLOSE SYMMETRIC KEY SYMMETRICKEY;
|
||||||
|
`
|
||||||
|
const data: SubmitTargetResponse[] = await prisma.$queryRawUnsafe(query)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getSubmissionTargetBuilder(): Promise<SubmitTargetResponse[] | null> {
|
||||||
|
const query = `
|
||||||
|
OPEN SYMMETRIC KEY SYMMETRICKEY DECRYPTION BY CERTIFICATE CERTI_QSPJP;
|
||||||
|
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 = '${this.storeId}'
|
||||||
|
AND BQU.EMAIL IS NOT NULL
|
||||||
|
AND BQU.USER_AUTH_CD != 'B'
|
||||||
|
AND MCAS.DEL_YN = 'N';
|
||||||
|
CLOSE SYMMETRIC KEY SYMMETRICKEY;
|
||||||
|
`
|
||||||
|
const data: SubmitTargetResponse[] = await prisma.$queryRawUnsafe(query)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getSubmissionTargetSuper(): Promise<SubmitTargetResponse[] | null> {
|
||||||
|
const query = `
|
||||||
|
OPEN SYMMETRIC KEY SYMMETRICKEY DECRYPTION BY CERTIFICATE CERTI_QSPJP;
|
||||||
|
SELECT
|
||||||
|
MCSA.STORE_ID AS targetStoreId
|
||||||
|
, BU.USER_ID AS repUserId
|
||||||
|
, CONVERT(NVARCHAR(100), DecryptByKey(BU.E_MAIL)) AS repUserEmail
|
||||||
|
FROM MS_CUST_STOREID_ADDITNL MCSA WITH(NOLOCK)
|
||||||
|
LEFT OUTER JOIN BC_USER bu WITH(NOLOCK)
|
||||||
|
ON MCSA.COMP_CD = BU.COMP_CD
|
||||||
|
AND MCSA.KAM_ID = BU.KAM_ID
|
||||||
|
AND BU.STAT_CD = 'A'
|
||||||
|
AND BU.DEL_YN = 'N'
|
||||||
|
WHERE MCSA.COMP_CD = '5200'
|
||||||
|
AND MCSA.STORE_ID = '${this.storeId}'
|
||||||
|
AND MCSA.DEL_YN = 'N';
|
||||||
|
CLOSE SYMMETRIC KEY SYMMETRICKEY;
|
||||||
|
`
|
||||||
|
const data: SubmitTargetResponse[] = await prisma.$queryRawUnsafe(query)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -393,21 +393,16 @@ export function useSurvey(
|
|||||||
const getSubmitTarget = async (params: { storeId: string; role: string }): Promise<SubmitTargetResponse[] | null> => {
|
const getSubmitTarget = async (params: { storeId: string; role: string }): Promise<SubmitTargetResponse[] | null> => {
|
||||||
try {
|
try {
|
||||||
if (!params.storeId) {
|
if (!params.storeId) {
|
||||||
|
/** 판매점 ID 없는 경우 */
|
||||||
alert('販売店IDがありません。')
|
alert('販売店IDがありません。')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
const endpoint = `/api/submission?storeId=${params.storeId}&role=${params.role}`
|
||||||
const endpoints = {
|
|
||||||
Admin_Sub: `/api/submission/admin-sub?id=${params.storeId}`,
|
|
||||||
Builder: `/api/submission/builder?id=${params.storeId}`,
|
|
||||||
} as const
|
|
||||||
|
|
||||||
const endpoint = endpoints[params.role as keyof typeof endpoints]
|
|
||||||
if (!endpoint) {
|
if (!endpoint) {
|
||||||
|
/** 권한 오류 */
|
||||||
alert('権限が間違っています。')
|
alert('権限が間違っています。')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await axiosInstance(null).get<SubmitTargetResponse[]>(endpoint)
|
const { data } = await axiosInstance(null).get<SubmitTargetResponse[]>(endpoint)
|
||||||
return data
|
return data
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user