명명 규칙
본 문서는 파일명, 클래스명, 선택자, 슬라이스명의 규약을 정의합니다.
두 개의 규약을 결합합니다. 파일과 클래스는 Angular 스타일 가이드를 따르고, 세그먼트 내부의 파일 분할은 FSD의 도메인 기반 명명을 따릅니다.
1. 기준판 고정
Angular 스타일 가이드는 2025년 개정판을 기준으로 합니다.
이 개정에서 파일명의 타입 접미사(.component.ts, .service.ts, .directive.ts)가 제거되었습니다. Angular CLI의 fileNameStyleGuide 옵션 값 2025에 해당하며, ng new가 생성하는 루트 컴포넌트가 app.component.ts가 아니라 app.ts인 것이 이 규약의 적용 결과입니다.
기준판을 고정하지 않으면 CLI 생성물과 문서의 규약이 어긋나 생성할 때마다 파일명을 손으로 고치게 됩니다.
2. 파일명
2.1 형식
모든 파일명은 케밥 케이스를 사용합니다. 타입 접미사를 붙이지 않습니다.
| 대상 | 파일명 |
|---|---|
| 컴포넌트 | assessment-list.ts, assessment-list.html |
| 서비스 | session.ts |
| 가드 | auth-guard.ts |
| 인터셉터 | auth-interceptor.ts |
| 파이프 | format-grade.ts |
| 모델·타입 | risk-assessment.ts |
가드와 인터셉터는 접미사를 유지합니다. 이름만으로 역할이 드러나지 않으면 라우트 정의나 프로바이더 배열에서 무엇인지 판별할 수 없기 때문입니다.
2.2 도메인 기반 분할
세그먼트 안에서 파일을 나눌 때는 다루는 도메인으로 이름 짓습니다. 기술적 역할로 짓는 것을 금지합니다.
| 구분 | 준수 지침 (Do) | 금지 지침 (Don't) |
|---|---|---|
| 모델 | model/risk-assessment.ts |
model/types.ts |
| 유틸 | lib/format-grade.ts |
lib/utils.ts |
| 요청 | api/fetch-assessments.ts |
api/api.ts |
| 상수 | config/assessment-grade.ts |
config/constants.ts |
types.ts와 utils.ts가 금지되는 이유는 무관한 도메인이 한 파일에 섞이기 때문입니다. 파일명으로 내용을 알 수 없어 열어 봐야 하고, 시간이 지나면 무엇이든 들어가는 자리가 됩니다.
세그먼트에 도메인 관심사가 하나뿐이면 파일명이 슬라이스명과 같아도 됩니다. features/auth/model/auth.ts 형태입니다.
2.3 요청 함수 파일
동사로 시작해 무엇을 하는지 드러냅니다.
| 동작 | 파일명 |
|---|---|
| 목록 조회 | fetch-assessments.ts |
| 단건 조회 | fetch-assessment.ts |
| 생성 | create-assessment.ts |
| 수정 | update-assessment.ts |
| 삭제 | delete-assessment.ts |
3. 클래스명과 심볼명
3.1 클래스
파스칼 케이스를 사용하며 타입 접미사를 붙이지 않습니다.
| 대상 | 클래스명 |
|---|---|
| 컴포넌트 | AssessmentList |
| 서비스 | SessionStore |
| 디렉티브 | Autofocus |
| 파이프 | FormatGrade |
AssessmentListComponent가 아니라 AssessmentList입니다. 접미사는 정보를 더하지 않으며, 파일 위치(ui/ 세그먼트)가 이미 역할을 드러냅니다.
서비스는 역할을 드러내는 명사로 이름 짓습니다. SessionService처럼 Service로 끝내는 대신 SessionStore, InvalidationBus처럼 무엇을 하는지 담습니다.
3.2 함수
| 대상 | 형식 | 예시 |
|---|---|---|
| 주입 헬퍼 | inject 접두사 |
injectInteractionMode, injectAssessment |
| 조회 요청 | fetch 접두사 |
fetchAssessments |
| 변경 요청 | 동사 | approveAssessment, deleteAssessment |
| 계산 | 동사 | calculateGrade, formatDate |
| 판정 | is · has · can 접두사 |
isExpired, hasPermission |
3.3 타입
생성된 서버 타입은 생성기가 정한 이름을 그대로 사용합니다. 손으로 고치지 않습니다. 서버 어휘가 화면 코드에 드러나는 것은 API 계약 소비에서 감수하기로 한 대가입니다.
직접 정의하는 타입은 파스칼 케이스를 사용하며 I 접두사나 Type 접미사를 붙이지 않습니다.
4. 선택자
컴포넌트 선택자는 app 접두사와 케밥 케이스를 사용합니다.
@Component({ selector: 'app-assessment-list' })접두사는 angular.json의 prefix 설정이 원본입니다. 프로젝트별로 다른 접두사를 쓸 수 있으나, 한 프로젝트 안에서는 일관되어야 합니다.
디렉티브 선택자는 접두사를 붙인 카멜 케이스 속성 형태를 사용합니다.
@Directive({ selector: '[appAutofocus]' })5. 슬라이스명
5.1 형식
케밥 케이스를 사용하며 계층에 따라 품사가 다릅니다.
| 계층 | 품사 | 예시 |
|---|---|---|
| pages | 화면을 나타내는 명사구 | assessment-list, assessment-detail |
| features | 사용자 동작을 나타내는 동사구 | assessment-approve, file-upload |
| entities | 도메인 개념을 나타내는 명사 | assessment, worker |
features와 entities의 품사 차이가 두 계층의 판정 기준입니다. 이름을 지을 때 동사구가 자연스러우면 features, 명사가 자연스러우면 entities입니다.
5.2 pages 슬라이스명
라우트 경로와 대응시킵니다. 라우트를 보고 슬라이스를, 슬라이스를 보고 라우트를 찾을 수 있어야 합니다.
| 라우트 | 슬라이스 |
|---|---|
/assessments |
assessment-list |
/assessments/:id |
assessment-detail |
/assessments/:id/edit |
assessment-edit |
/assessments/new |
assessment-create |
목록·상세·편집·생성은 각각 별도 슬라이스입니다. 접미사를 -list, -detail, -edit, -create로 통일해 화면 성격이 이름에서 드러나게 합니다.
5.3 금지
| 금지 | 사유 |
|---|---|
슬라이스명에 계층명 포함 (assessment-page) |
경로에 이미 pages/가 있습니다 |
지나치게 넓은 슬라이스명 (common, misc, management) |
무엇이든 들어가는 자리가 됩니다 |
축약어 (assmt, usr) |
검색되지 않고 읽는 사람마다 다르게 해석합니다 |
user-management 같은 광범위한 이름은 시간이 지나면 여러 책임이 뒤섞입니다. auth, profile-edit, password-reset처럼 책임 단위로 나눕니다.
6. 상수와 열거값
상수는 대문자 스네이크 케이스를 사용합니다.
export const MAX_UPLOAD_SIZE = 10 * 1024 * 1024;열거 대신 유니온 타입과 as const 객체를 우선합니다. TypeScript의 enum은 런타임 코드를 생성하고 isolatedModules 환경에서 제약이 있습니다.
export const ASSESSMENT_GRADE = {
high: 'HIGH',
medium: 'MEDIUM',
low: 'LOW',
} as const;
export type AssessmentGrade = (typeof ASSESSMENT_GRADE)[keyof typeof ASSESSMENT_GRADE];7. 자동 강제
| 규칙 | 강제 수단 |
|---|---|
| 선택자 접두사와 형식 | angular-eslint 규칙 |
| 클래스 접미사 금지 | angular-eslint 규칙 |
| 도메인 기반 파일명 | Steiger inconsistent-naming, ambiguous-slice-names, segments-by-purpose (부분) |
| 파일명 케밥 케이스 | ESLint 파일명 규칙 |
Steiger의 명명 규칙은 슬라이스와 세그먼트 수준의 위반만 검출합니다. 파일 하나가 여러 도메인을 담고 있는지는 판정하지 못하므로 코드 리뷰에서 확인합니다.