# 명명규칙

> `/gen-html`, `/gen-storybook`, `/review` 에서 공통으로 사용하는 프론트엔드 네이밍 규칙이다.

## 참조 조건

- 파일명, 컴포넌트명, 함수명, 변수명, 타입명 규칙을 확인해야 할 때 이 문서를 읽는다.
- 새 이름을 정해야 하거나 기존 이름을 교정해야 할 때 이 문서를 읽는다.

## 수행 계약

- 파일명, 컴포넌트명, 함수명, 변수명, 타입명은 가능한 한 이 문서 표기법을 그대로 따른다.
- 기존 저장소 관례와 충돌하지 않는 한, 임의 약어·축약형·예외 네이밍을 새로 만들지 않는다.

## 기본 명명 규칙

| 구분                       | 표기법           | 예                            |
| :------------------------- | :--------------- | :---------------------------- |
| 1. 프로젝트명              | kebab case       | hli-nxl-dsp-{업무구분코드}-fe |
| 2. 경로명(pathname 포함)   | kebab case       | /user-info/user-name          |
| 3. 컴포넌트 함수명         | Pascal case      | UserName                      |
| 4. 클래스명 / 네임스페이스 | Pascal case      | DataUtil, StringUtil          |
| 5. 함수명(일반)            | camel case       | getUserName                   |
| 6. 변수명(일반)            | camel case       | userName                      |
| 7. 상수명                  | upper snake case | BASE_URL                      |
| 8. type명                  | Pascal case      | NetworkStatus                 |
| 9. interface명             | Pascal case      | UserName, ProductName         |
| 10. enum                   | Pascal case      |                               |

## 파일 명명 규칙

| 구분         | 표기법             | 확장자        | 예                                                                                      |
| :----------- | :----------------- | :------------ | :-------------------------------------------------------------------------------------- |
| 1. 컴포넌트  | kebab case         | .tsx          | user-name.tsx                                                                           |
| 2. 커스텀 훅 | kebab case         | .tsx          | use-user-name.tsx                                                                       |
| 3. 스타일    | kebab case         | .scss or .css | user-name.module.scss<br>global.css                                                     |
| 4. 스토리북  | kebab case or 한글 | .stories.tsx  | user-name.stories.tsx or 1\_개인정보처리동의.stories.tsx<br>(관리하기 쉬운 네이밍)      |
| 5. 유틸리티  | kebab case         | .ts           | user-name-utils.ts<br>{유틸리티명}-utils.ts                                             |
| 6. 타입      | kebab case         | .ts           | user-name.types.ts<br>{이름}.types.ts<br>(외부 사용이 필요한 부분은 별도의 파일로 분리) |
| 7. dto 타입  | kebab case         | .ts           | user-name.dto.ts<br>{백엔드 주제영역명}.dto.ts                                          |
| 8. declare   | kebab case         | .d.ts         | user-name.d.ts                                                                          |

- 리액트와 관련된 것들은 .tsx로 통일 (커스텀 훅, 컨텍스트 등)

## 컴포넌트 명명 규칙

- 표기법: Pascal case
- 단일 책임 원칙을 기반으로 한 컴포넌트 이름(특히 공통)
- 숫자, 특수문자 사용 X, 의미와 목적이 드러나는 네이밍, 두문자어도 파스칼 케이스 사용

```javascript
// ✅ 목적/의미 분명, Full Name
export const LoginForm = ({}: LoginFormProps) => {
  ...
}

// ❌ 숫자
export const UserView1 = () => {
  ...
}

// ✅ 두문자어
export const HtmlEditor = () => {
  ...
}
// ❌ 두문자어
export const HTMLEditor = () => {
  ...
}

// ❌ 약어, 축약형
export const UsrPrfl = () => {
  ...
}

// ❌ 특수문자
export const User_Profile = () => {
  ...
}
```

## 함수 명명 규칙

- 표기법: camel case

```javascript
// ✅ camel case
const getCamelCase = () => { ... }

// ❌
const Get_Camel_Case = () => { ... }

// ❌
const GetCamelCase = () => { ... }
```

- 동사로 시작

```javascript
// ✅ 동사로 시작
const getCamelCase = () => { ... }

// ❌ non 동사
const camelCase = () => { ... }
```

- 최대한 구체적 + 목표분명 + 한 가지 책임을 담당하는 함수명
- 함수의 역할을 명확히 알 수 있도록 하고 로직이 과도하게 몰리는 걸 방지하기 위함

```javascript
// ✅ 구체적이고 단일목적
const formatDateToKorean = () => { ... }

// ❌ 추상, 줄임
const format = () => { ... }
```

- 조건부
- is/has/should + 조건

```javascript
// ✅ 조건부 (is/has/should + 대상)
const isTablet = () => { ... }
const hasChildren = () => { ... }
const shouldPreventEvent = () => { ... }
```

- API 호출함수
- C(create): create + 대상 + (상세정보) (예: createUserProfile)
- R(read): 단건: get + 대상 + (상세정보) (예: getUserProfile), 다건: getList + 대상 + (상세정보) (예: getListUserProfile)
- U(update): update + 대상 + (상세정보) (예: updateUserProfile)
- D(delete): delete + 대상 + (상세정보) (예: deleteUserProfile)

```javascript
// ✅ 단건 조회 API 호출 (get + 대상)
const getUserName = () => { ... }

// ✅ 다건 조회 API 호출 (getList + 대상)
const getListUserName = () => { ... }

// ✅ update 성격의 API 호출 (update + 대상)
const updateUserName = () => { ... }

// ✅ 삭제 성격의 API 호출 (delete + 대상)
const deleteUserName = () => { ... }

// ✅ insert 성격의 API 호출 (create + 대상)
const createUserName = () => { ... }
```

- 데이터 변환
- convert / format / parse + 대상

```javascript
// ✅ 변환 함수 (convert/format/parse + 대상)
const convertUserName = () => { ... }
const formatUserName = () => { ... }
const parseUserName = () => { ... }
```

- 검증
- validate + 대상

```javascript
// ✅ 데이터 검증 (validate + 대상)
const validateUserName = () => { ... }
```

- 이벤트 핸들러
- handle + 대상

```javascript
// ✅ 이벤트 핸들러 (handle + 이벤트타입 + 대상)
const handleUserNameClick = () => { ... }
const handleModalClose = () => { ... }

// ✅ 이벤트 핸들러를 Props로 넘길 땐 (on + 핸들러 함수)
<UserName onUserNameClick={handleUserNameClick} onModalClose={handleModalClose} />
```

- 초기화 / 생성
- create / initialize + 대상

```javascript
// ✅ 초기화 및 객체 생성 (create/initialize + 대상)
const createApiInstance = () => { ... }
const initializeLoginInformation = () => { ... }
```

## 변수 명명 규칙

- 단, 백엔드에서 정의된 필드는 그대로 따른다.
- 기본 표기법: camel case (object 포함)
- 상수: Upper Snake case

```javascript
// ✅ camel case
const userName = '김한화';

// ✅ 상수 case
const USER_NAME = '김한화';

// ✅ object case
const testUtils = {
  convertCurrency() {...}
}

// ❌
const user_name = '';
const UserName = '';
const User_Name = '';
const TestUtils = {...};
```

- 의미 있고 구체적인 이름

```javascript
// ✅ 구체적
const userName = '김한화';
const isEmailValidated = false;

// ❌
const un = ''
const total = 0;
const item = [];

// ❌ 진짜 금지
const flag = false;
```

- 숫자

```javascript
// ✅ 개수 관련 count, total, num 접두사/접미사 활용
const userCount = 100;
const totalUsers = 1000;
const numPages = 100;

// ✅ 크기/양 관련 size, amount, length 접미사 활용
const fileSize = 100;
const fileAmount = 100;
const fileLength = 100;
```

- 배열

```javascript
// ✅ 복수형으로 내용을 정확하게 표현
const selectedUsers = [];
const errorMessages = [];

// ❌ 단수, 추상적 영문명
const user = [];
const data = [];
```

- boolean

```javascript
// ✅ is/has/should 접두사 활용

// ~이다, 아니다
const isLoading = false;
const isValid = false;

// 갖다, 아니다
const hasError = false;

// 해야할지, 말아야할지
const shouldUpdate = false;
```

- Class

```javascript
// ✅ pascal case
class BridgeCore {}

// ❌
class bridgeCore {}
```

## Type, Interface 명명 규칙

- 기본 표기법: Pascal Case

```typescript
// ✅ Pascal case
interface UserInfo {
  id: string;
  name: string;
}

// ✅ Swagger DTO 명 그대로 승계
interface ApiResponse<T> {
  data: T;
  message: string;
}

// ❌
interface User_Info {}

// ❌
interface I_User_ {}
```

- Type: Pascal Case

```typescript
// ✅ Pascal case
type UserName = 'user' | 'admin';

// ✅
type ApiStatus = 'success' | 'loading' | 'error';

// ❌
type TUserName = 'user' | 'admin';

// ❌
type API_STATUS = 'success' | 'loading' | 'error';
```

- interface 사용 case
- DTO: Swagger에 정의된 Request/Response 명을 그대로 따른다.

```typescript
// ✅ 객체 구조 정의
interface UserInfo {}

// ✅ class 구현을 위한 정의
interface BridgeController {
  call: () => void;
  open: () => void;
}

// ✅ 확장 가능한 구조
interface BaseConfig {}
interface ApiClient extends BaseConfig {}

// ✅ Swagger에 UserInfoRequest/UserInfoResponse 라고 정의된 경우
interface UserInfoRequest {}
interface UserInfoResponse {}
```

- Type 사용 case

```typescript
// 유니온 타입
type Status = 'success' | 'loading' | 'reject';

// 조건 케이스
type NonNullable<T> = T extends null | undefined ? never : T;
```
