Skip to content

Coding Conventions

JEONG edited this page Aug 24, 2026 · 2 revisions

Coding Conventions

위반 시 컴파일 에러·런타임 크래시·리뷰 반려로 이어지는 절대 규칙과 코딩 스타일·네이밍 규칙입니다. 이 규칙은 활성 코드베이스 UMCApp/ 에 적용됩니다. (AppProduct/v2.2.0에 동결)

🚨 절대 규칙 (예외 없이 적용)

  1. 상태 관리는 @Observable 매크로만@StateObject/@ObservedObject/@Published 금지. 예외: 앱 생명주기 전역 관리자(AppFlowViewModel). View는 @State private var viewModel 패턴.
  2. 서버 응답 정수는 전 레이어 String 통일 — 서버가 모든 정수를 String으로 직렬화한다. Response DTO·Domain Model·Repository Protocol 파라미터까지 String. Int 변환은 연산 시점에만.
  3. Response DTO는 synthesized Codable 금지 — custom init(from:) + encode(to:) 필수. 정수 필드는 decode(Int.self) 직접 호출 금지 → import UMCFoundationdecodeIntFlexibleIfPresent 등 공용 헬퍼 사용 (파일마다 다시 정의하지 않는다). (Request/Encodable DTO는 제외 — Int 그대로 OK) · 상세: Networking
  4. 모듈 간 노출 타입은 public — Domain Model의 프로퍼티/이니셜라이저에 public 필수.
  5. Mock 데이터는 #if DEBUG 가드 — 릴리스 빌드 미포함.
  6. Network Router에 인라인 딕셔너리 금지 — 파라미터는 Query/Body DTO로 캡슐화. 상세: Networking
  7. 식별자에 의미 없는 숫자 접미사 금지text1/btn2Color 등 금지, 역할이 드러나는 이름 부여.
  8. 모든 Git/GitHub 산출물에 AI 작성 흔적(attribution) 금지 — 커밋 메시지·PR 제목/본문· 이슈 제목/본문·리뷰 코멘트 어디에도 Co-Authored-By: Claude …, 🤖 Generated with [Claude Code](...), "AI-generated" 같은 문구를 넣지 않는다.
  9. AppProduct/(레거시)는 v2.2.0 릴리즈 상태로 동결 — 절대 수정 금지. 모든 신규·유지보수·이식 작업은 UMCApp/(Tuist)에서만 수행한다.

✍️ 코딩 스타일

  • 들여쓰기: 4 spaces (탭 금지)
  • 줄 길이: 최대 99자
  • 접근 제어자: 외부에서 불필요한 상태는 private 필수
  • 상수: View 내부 전용은 fileprivate enum Constants

MARK 구분

// MARK: - Property
// MARK: - Body
// MARK: - Function

🔤 네이밍 규칙

식별자(상수·변수·프로퍼티·함수·case·타입)는 무엇인지·왜 존재하는지를 이름만으로 읽을 수 있어야 합니다.

  1. 의미 없는 숫자 접미사 금지text1, value2, section3처럼 카운터로 구분 금지. 각자 역할을 드러내는 이름 부여.
  2. 연속 인덱스가 본질인 경우만 예외step1, phase1처럼 순서 자체가 의미일 때만.
  3. 컬렉션이면 컬렉션으로 — 같은 종류 데이터는 [Type] 배열 또는 enum + 매핑. xxx1/xxx2로 펼치지 않는다.
  4. 약어 금지(도메인 표준 제외)usr/cnt/tmp 대신 user/count/temporary. 단 id, URL, API는 허용.
  5. 타입을 이름에 박지 않기userArray/nameString 대신 users/name. 의미 충돌 시에만 한정사 부여.

❌ 안티패턴

fileprivate enum Constants {
    static let supportText1: String = "이용 중 불편사항이 있으신가요?"
    static let supportText2: String = "고객센터 운영시간 09:00 - 18:00"
    static let btn1Color: Color = .indigo500
    static let btn2Color: Color = .grey400
}

카운터만으로는 어떤 값이 어떤 역할인지 알 수 없다. 본문을 봐도 정의로 점프해야 파악된다.

✅ 권장 패턴

fileprivate enum Constants {
    static let supportInquiryPrompt: String = "이용 중 불편사항이 있으신가요?"
    static let supportOperatingHours: String = "고객센터 운영시간 09:00 - 18:00"
    static let primaryActionColor: Color = .indigo500
    static let disabledActionColor: Color = .grey400
}

호출부(Text(Constants.supportInquiryPrompt))만 봐도 표시 의도가 드러난다.


관련 문서: Architecture · Networking · Design System · Git Workflow

Clone this wiki locally