Merge branch 'dev' of https://git.hanasys.jp/qcast3/onsitesurvey into feature/suitable
This commit is contained in:
commit
e736dc555d
11
README.md
11
README.md
@ -31,9 +31,6 @@ npm install
|
|||||||
# 환경 변수 설정
|
# 환경 변수 설정
|
||||||
cp .env.example .env.local
|
cp .env.example .env.local
|
||||||
|
|
||||||
# 데이터베이스 초기화 <- 절대 함부로 실행하지 마시오
|
|
||||||
# npx prisma migrate dev
|
|
||||||
# npx prisma generate
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 개발 서버 실행
|
### 개발 서버 실행
|
||||||
@ -126,7 +123,7 @@ session에 있는 role 키로 구분한다
|
|||||||
session.role === 'Builder'
|
session.role === 'Builder'
|
||||||
- teshg44 / 1234 -> 시공사\
|
- teshg44 / 1234 -> 시공사\
|
||||||
session.role === 'Builder'
|
session.role === 'Builder'
|
||||||
- partners -> Q.Partners 계정\
|
- isogai@yanegiken.co.jp / password -> Q.Partners 계정\
|
||||||
session.role === 'Partner'
|
session.role === 'Partner'
|
||||||
- 이외의 경우 -> 굳이 체크할 필요 없어보임\
|
- 이외의 경우 -> 굳이 체크할 필요 없어보임\
|
||||||
session.role === 'User'
|
session.role === 'User'
|
||||||
@ -155,17 +152,17 @@ const suitableCheckMemo = (value: string): string => {
|
|||||||
|
|
||||||
# 주의
|
# 주의
|
||||||
|
|
||||||
## Prisma ORM 사용 시 주의사항
|
## <span style="color: red">Prisma ORM 사용 시 주의사항</span>
|
||||||
|
|
||||||
현재 프로젝트는 Prisma ORM을 통해 데이터베이스의 일부 테이블만 관리하고 있습니다. 이로 인해 `prisma db pull` 또는 `prisma db push` 명령어 사용 시 주의가 필요합니다.
|
현재 프로젝트는 Prisma ORM을 통해 데이터베이스의 일부 테이블만 관리하고 있습니다. 이로 인해 `prisma db pull` 또는 `prisma db push` 명령어 사용 시 주의가 필요합니다.
|
||||||
|
|
||||||
### 잠재적 위험성
|
### <span style="color: red">잠재적 위험성</span>
|
||||||
|
|
||||||
- `schema.prisma` 파일에 정의된 모델이 의도치 않게 수정될 수 있습니다.
|
- `schema.prisma` 파일에 정의된 모델이 의도치 않게 수정될 수 있습니다.
|
||||||
- 기존에 정의된 모델의 속성이나 관계가 손상될 수 있습니다.
|
- 기존에 정의된 모델의 속성이나 관계가 손상될 수 있습니다.
|
||||||
- 데이터베이스 스키마와 Prisma 스키마 간의 불일치가 발생할 수 있습니다.
|
- 데이터베이스 스키마와 Prisma 스키마 간의 불일치가 발생할 수 있습니다.
|
||||||
|
|
||||||
### 권장 사항
|
### <span style="color: red">권장 사항</span>
|
||||||
|
|
||||||
- 데이터베이스 스키마 변경이 필요한 경우, 반드시 팀 내 논의 후 진행하시기 바랍니다.
|
- 데이터베이스 스키마 변경이 필요한 경우, 반드시 팀 내 논의 후 진행하시기 바랍니다.
|
||||||
- `prisma db pull` 실행 전 현재 `schema.prisma` 파일의 백업을 권장합니다.
|
- `prisma db pull` 실행 전 현재 `schema.prisma` 파일의 백업을 권장합니다.
|
||||||
|
|||||||
71
diagram/layout.md
Normal file
71
diagram/layout.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# 루트 레이아웃 구조
|
||||||
|
|
||||||
|
이 문서는 애플리케이션의 모든 페이지에서 공통으로 사용되는 루트 레이아웃(`src/app/layout.tsx`)의 구조를 설명합니다.
|
||||||
|
|
||||||
|
## 컴포넌트 계층 구조
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[RootLayout] --> B[ReactQueryProviders]
|
||||||
|
B --> C[EdgeProvider]
|
||||||
|
C --> D[HTML Structure]
|
||||||
|
|
||||||
|
D --> E[Header]
|
||||||
|
D --> F[Children/Main Content]
|
||||||
|
D --> G[Footer]
|
||||||
|
D --> H[Float Button]
|
||||||
|
D --> I[PopupController]
|
||||||
|
|
||||||
|
J[Session Management] --> |Session Data| C
|
||||||
|
|
||||||
|
subgraph Providers
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Layout Components
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
H
|
||||||
|
I
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Session
|
||||||
|
J
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## 주요 컴포넌트
|
||||||
|
|
||||||
|
### 프로바이더
|
||||||
|
|
||||||
|
- **ReactQueryProviders**: React Query 상태 관리를 위한 최상위 프로바이더
|
||||||
|
- **EdgeProvider**: 세션 데이터를 관리하고 애플리케이션에 제공
|
||||||
|
|
||||||
|
### 레이아웃 컴포넌트
|
||||||
|
|
||||||
|
- **Header**: 공통 헤더 컴포넌트
|
||||||
|
- **Children**: 메인 콘텐츠 영역 (페이지별 콘텐츠)
|
||||||
|
- **Footer**: 공통 푸터 컴포넌트
|
||||||
|
- **Float Button**: 플로팅 액션 버튼
|
||||||
|
- **PopupController**: 팝업/모달 상태 관리
|
||||||
|
|
||||||
|
### 세션 관리
|
||||||
|
|
||||||
|
- `iron-session`을 사용한 서버 사이드 세션 관리
|
||||||
|
- 세션 데이터는 EdgeProvider를 통해 전역적으로 접근 가능
|
||||||
|
|
||||||
|
## 데이터 흐름
|
||||||
|
|
||||||
|
1. 세션 데이터는 서버 사이드에서 관리됨
|
||||||
|
2. 세션 데이터는 EdgeProvider로 전달됨
|
||||||
|
3. 모든 레이아웃 컴포넌트는 세션 컨텍스트에 접근 가능
|
||||||
|
4. React Query는 데이터 페칭과 캐싱 기능을 제공
|
||||||
|
|
||||||
|
## 구현 세부사항
|
||||||
|
|
||||||
|
- 서버 컴포넌트로 구현
|
||||||
|
- Next.js App Router 구조 사용
|
||||||
|
- 서버 사이드 렌더링 지원
|
||||||
|
- 하이드레이션 억제를 통한 성능 최적화
|
||||||
@ -13,6 +13,7 @@ model SD_SURVEY_SALES_BASIC_INFO {
|
|||||||
REPRESENTATIVE String @db.NVarChar(200)
|
REPRESENTATIVE String @db.NVarChar(200)
|
||||||
STORE String? @db.NVarChar(200)
|
STORE String? @db.NVarChar(200)
|
||||||
CONSTRUCTION_POINT String? @db.NVarChar(200)
|
CONSTRUCTION_POINT String? @db.NVarChar(200)
|
||||||
|
CONSTRUCTION_POINT_ID String? @db.NVarChar(200)
|
||||||
INVESTIGATION_DATE String? @db.NVarChar(10)
|
INVESTIGATION_DATE String? @db.NVarChar(10)
|
||||||
BUILDING_NAME String? @db.NVarChar(200)
|
BUILDING_NAME String? @db.NVarChar(200)
|
||||||
CUSTOMER_NAME String? @db.NVarChar(200)
|
CUSTOMER_NAME String? @db.NVarChar(200)
|
||||||
@ -22,6 +23,7 @@ model SD_SURVEY_SALES_BASIC_INFO {
|
|||||||
SUBMISSION_STATUS Boolean @default(false)
|
SUBMISSION_STATUS Boolean @default(false)
|
||||||
SUBMISSION_DATE DateTime? @db.Date
|
SUBMISSION_DATE DateTime? @db.Date
|
||||||
SUBMISSION_TARGET_ID String? @db.NVarChar(200)
|
SUBMISSION_TARGET_ID String? @db.NVarChar(200)
|
||||||
|
SUBMISSION_TARGET_NM String? @db.NVarChar(200)
|
||||||
REG_DT DateTime @default(now())
|
REG_DT DateTime @default(now())
|
||||||
UPT_DT DateTime @updatedAt
|
UPT_DT DateTime @updatedAt
|
||||||
REPRESENTATIVE_ID String? @db.NVarChar(100)
|
REPRESENTATIVE_ID String? @db.NVarChar(100)
|
||||||
|
|||||||
@ -57,6 +57,7 @@ export async function POST(request: Request) {
|
|||||||
session.storeLvl = result.data.data.storeLvl
|
session.storeLvl = result.data.data.storeLvl
|
||||||
session.custCd = result.data.data.custCd
|
session.custCd = result.data.data.custCd
|
||||||
session.builderNo = result.data.data.builderNo
|
session.builderNo = result.data.data.builderNo
|
||||||
|
session.builderNm = ''
|
||||||
session.isLoggedIn = true
|
session.isLoggedIn = true
|
||||||
|
|
||||||
if (result.data.data.userId === 'T01') {
|
if (result.data.data.userId === 'T01') {
|
||||||
@ -104,6 +105,7 @@ export async function POST(request: Request) {
|
|||||||
STORE_LVL: result.data.data.storeLvl,
|
STORE_LVL: result.data.data.storeLvl,
|
||||||
CUST_CD: result.data.data.custCd,
|
CUST_CD: result.data.data.custCd,
|
||||||
BUILDER_NO: result.data.data.builderNo,
|
BUILDER_NO: result.data.data.builderNo,
|
||||||
|
BUILDER_NM: '',
|
||||||
IS_LOGGED_IN: true,
|
IS_LOGGED_IN: true,
|
||||||
ROLE: '',
|
ROLE: '',
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,6 +85,7 @@ export async function POST(request: Request) {
|
|||||||
session.storeLvl = null
|
session.storeLvl = null
|
||||||
session.custCd = null
|
session.custCd = null
|
||||||
session.builderNo = data[0].user_seko_id
|
session.builderNo = data[0].user_seko_id
|
||||||
|
session.builderNm = data[0].supplier_name
|
||||||
session.isLoggedIn = true
|
session.isLoggedIn = true
|
||||||
session.role = 'Partner'
|
session.role = 'Partner'
|
||||||
|
|
||||||
@ -123,6 +124,7 @@ export async function POST(request: Request) {
|
|||||||
STORE_LVL: null,
|
STORE_LVL: null,
|
||||||
CUST_CD: null,
|
CUST_CD: null,
|
||||||
BUILDER_NO: data[0].user_seko_id,
|
BUILDER_NO: data[0].user_seko_id,
|
||||||
|
BUILDER_NM: data[0].supplier_name,
|
||||||
IS_LOGGED_IN: true,
|
IS_LOGGED_IN: true,
|
||||||
ROLE: 'Partner',
|
ROLE: 'Partner',
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,21 +3,19 @@ import Config from '@/config/config.export'
|
|||||||
import { useSpinnerStore } from '@/store/spinnerStore'
|
import { useSpinnerStore } from '@/store/spinnerStore'
|
||||||
|
|
||||||
export function useAxios() {
|
export function useAxios() {
|
||||||
// const { setIsShow } = useSpinnerStore()
|
|
||||||
|
|
||||||
const requestHandler = (config: InternalAxiosRequestConfig) => {
|
const requestHandler = (config: InternalAxiosRequestConfig) => {
|
||||||
// setIsShow(true)
|
useSpinnerStore.getState().setIsShow(true)
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
const responseHandler = (response: AxiosResponse) => {
|
const responseHandler = (response: AxiosResponse) => {
|
||||||
// setIsShow(false)
|
useSpinnerStore.getState().setIsShow(false)
|
||||||
response.data = transferResponse(response)
|
response.data = transferResponse(response)
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
const errorHandler = (error: any) => {
|
const errorHandler = (error: any) => {
|
||||||
// setIsShow(false)
|
useSpinnerStore.getState().setIsShow(false)
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,7 @@ export const defaultSession: SessionData = {
|
|||||||
storeLvl: null,
|
storeLvl: null,
|
||||||
custCd: null,
|
custCd: null,
|
||||||
builderNo: null,
|
builderNo: null,
|
||||||
|
builderNm: null,
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
role: null,
|
role: null,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ export default function ReactQueryProviders({ children }: React.PropsWithChildre
|
|||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
staleTime: 60 * 1000,
|
staleTime: 60 * 1000,
|
||||||
|
retry: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -41,6 +41,7 @@ const initialState: InitialState = {
|
|||||||
storeLvl: null,
|
storeLvl: null,
|
||||||
custCd: null,
|
custCd: null,
|
||||||
builderNo: null,
|
builderNo: null,
|
||||||
|
builderNm: null,
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
role: null,
|
role: null,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -27,6 +27,7 @@ export interface SessionData {
|
|||||||
storeLvl: null
|
storeLvl: null
|
||||||
custCd: null
|
custCd: null
|
||||||
builderNo: null
|
builderNo: null
|
||||||
|
builderNm: null | string
|
||||||
isLoggedIn: boolean
|
isLoggedIn: boolean
|
||||||
role: string | null
|
role: string | null
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user