refactor: modify member permission verification logic

- 매물 조회 권한 검증 로직 리팩토링
This commit is contained in:
Dayoung 2025-06-04 10:51:11 +09:00
parent e756465250
commit 0c27c19341
4 changed files with 55 additions and 23 deletions

View File

@ -3,30 +3,63 @@ import { prisma } from '@/libs/prisma'
import { convertToSnakeCase } from '@/utils/common-utils'
import { SessionData } from '@/types/Auth'
type SessionParams = {
interface Survey {
SRL_NO: string
SUBMISSION_STATUS: boolean
SUBMISSION_TARGET_ID: string | null
STORE_ID: string | null
CONSTRUCTION_POINT_ID: string | null
}
interface SessionParams {
role: string | null
storeId: string | null
builderNo: string | null
isLoggedIn: string | null
}
const checkRole = (survey: any, sessionParams: SessionParams) => {
const checkT01Role = (survey: Survey): boolean => survey.SRL_NO !== '一時保存'
const checkAdminRole = (survey: Survey, storeId: string | null): boolean => {
if (!storeId) return false
if (survey.SUBMISSION_STATUS) {
return survey.SUBMISSION_TARGET_ID === storeId || survey.STORE_ID === storeId
}
return survey.STORE_ID === storeId
}
const checkAdminSubRole = (survey: Survey, storeId: string | null): boolean => {
if (!storeId) return false
if (survey.SUBMISSION_STATUS) {
return survey.SUBMISSION_TARGET_ID === storeId || (survey.STORE_ID === storeId && survey.CONSTRUCTION_POINT_ID === null)
}
return survey.STORE_ID === storeId && survey.CONSTRUCTION_POINT_ID === null
}
const checkPartnerOrBuilderRole = (survey: Survey, builderNo: string | null): boolean => {
if (!builderNo) return false
return survey.CONSTRUCTION_POINT_ID === builderNo
}
const checkRole = (survey: Survey, sessionParams: SessionParams): boolean => {
if (!survey || !sessionParams.role) return false
switch (sessionParams.role) {
case 'T01':
return true
return checkT01Role(survey)
// T01 이외 1차점
case 'Admin':
if (survey.SUBMISSION_STATUS) {
return survey.SUBMISSION_TARGET_ID === sessionParams.storeId
}
return survey.STORE_ID === sessionParams.storeId
return checkAdminRole(survey, sessionParams.storeId)
// 2차점
case 'Admin_Sub':
if (survey.SUBMISSION_STATUS) {
return survey.SUBMISSION_TARGET_ID === sessionParams.builderNo
}
return survey.STORE_ID === sessionParams.storeId && survey.CONSTRUCTION_POINT_ID === sessionParams.builderNo
return checkAdminSubRole(survey, sessionParams.storeId)
// partner
case 'Partner':
// 2차점 시공권한 user
case 'Builder':
return survey.CONSTRUCTION_POINT_ID === sessionParams.builderNo
return checkPartnerOrBuilderRole(survey, sessionParams.builderNo)
default:
return false
}
@ -54,6 +87,8 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
})
if (checkRole(survey, sessionParams)) {
return NextResponse.json(survey)
} else {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
}
} catch (error) {
console.error('Error fetching survey:', error)

View File

@ -90,12 +90,7 @@ const createMemberRoleCondition = (params: SearchParams): WhereCondition => {
where.OR = [
{
// MUSUBI (시공권한 X) 같은 판매점에서 작성한 제출/제출되지 않은 매물
AND: [
{ STORE_ID: { equals: params.storeId } },
{
OR: [{ CONSTRUCTION_POINT_ID: { equals: null } }, { CONSTRUCTION_POINT_ID: { equals: '' } }],
},
],
AND: [{ STORE_ID: { equals: params.storeId } }, { CONSTRUCTION_POINT_ID: { equals: params.builderNo } }],
},
{
// MUSUBI (시공권한 O) 가 MUSUBI 에 제출한 매물 + PARTNER 가 제출한 매물

View File

@ -5,7 +5,7 @@ import { useEffect, useState } from 'react'
import ButtonForm from './ButtonForm'
import BasicForm from './BasicForm'
import RoofForm from './RoofForm'
import { useParams, useSearchParams } from 'next/navigation'
import { useParams, useSearchParams, useRouter } from 'next/navigation'
import { useSurvey } from '@/hooks/useSurvey'
import { useSessionStore } from '@/store/session'
@ -71,10 +71,12 @@ export default function DetailForm() {
const idParam = useSearchParams().get('id')
const routeId = useParams().id
const router = useRouter()
const modeset = Number(routeId) ? 'READ' : idParam ? 'EDIT' : 'CREATE'
const id = Number(routeId) ? Number(routeId) : Number(idParam)
const { surveyDetail, validateSurveyDetail } = useSurvey(Number(id))
const { surveyDetail, isLoadingSurveyDetail, validateSurveyDetail } = useSurvey(Number(id))
const { session } = useSessionStore()
const [mode, setMode] = useState<Mode>(modeset)
@ -82,9 +84,10 @@ export default function DetailForm() {
const [roofInfoData, setRoofInfoData] = useState<SurveyDetailRequest>(roofInfoForm)
useEffect(() => {
if (Number(idParam) !== 0 || surveyDetail === null) {
if (isLoadingSurveyDetail) return
if (surveyDetail === null) {
alert('権限がありません。')
window.location.href = '/survey-sale'
router.replace('/survey-sale')
}
if (surveyDetail && (mode === 'EDIT' || mode === 'READ')) {
const { id, uptDt, regDt, detailInfo, ...rest } = surveyDetail

View File

@ -5,7 +5,6 @@ import { useSurveyFilterStore } from '@/store/surveyFilterStore'
import { useSessionStore } from '@/store/session'
import { useAxios } from './useAxios'
import { queryStringFormatter } from '@/utils/common-utils'
import { AxiosError } from 'axios'
export const requiredFields = [
{