Commit 92f75048 authored by insun park's avatar insun park
Browse files

initial draft

parents
{
"name": "Accessibility Rules",
"description": "웹 접근성 표준을 준수하기 위한 가이드라인 및 규칙",
"rules": {
"wcag": {
"conformanceLevel": "WCAG 2.1 AA",
"principles": {
"perceivable": {
"textAlternatives": {
"rule": "모든 비텍스트 콘텐츠에 대체 텍스트 제공",
"implementation": [
"이미지에 적절한 alt 속성 제공",
"아이콘 버튼에 접근 가능한 이름 제공",
"복잡한 차트나 그래프에 상세 설명 제공"
],
"examples": {
"good": "<img src=\"logo.png\" alt=\"회사 로고\">",
"bad": "<img src=\"logo.png\">"
}
},
"timeBasedMedia": {
"rule": "시간 기반 미디어에 대체 수단 제공",
"implementation": [
"동영상에 자막 제공",
"오디오 콘텐츠에 대본 제공",
"필요한 경우 수화 통역 제공"
]
},
"adaptable": {
"rule": "다양한 방식으로 표현 가능한 콘텐츠 제작",
"implementation": [
"시맨틱 HTML 요소 사용",
"콘텐츠의 논리적 구조 유지",
"데이터 테이블에 적절한 헤더와 관계 정의"
],
"examples": {
"good": "<button>제출</button>",
"bad": "<div onclick=\"submit()\">제출</div>"
}
},
"distinguishable": {
"rule": "콘텐츠를 보고 듣기 쉽게 만들기",
"implementation": [
"텍스트와 배경 간 충분한 대비(최소 4.5:1)",
"텍스트 크기 조정 시 가독성 유지",
"자동 재생 오디오 제어 기능 제공"
],
"colorContrast": {
"normalText": "최소 4.5:1",
"largeText": "최소 3:1",
"uiComponents": "최소 3:1"
}
}
},
"operable": {
"keyboardAccessible": {
"rule": "모든 기능을 키보드로 사용 가능하게 구현",
"implementation": [
"모든 상호작용 요소를 키보드로 접근 및 조작 가능하게 구현",
"키보드 트랩 방지",
"사용자 정의 컴포넌트에 적절한 키보드 지원 추가"
],
"examples": {
"good": "<a href=\"#\" tabindex=\"0\" role=\"button\" onkeydown=\"handleKeydown(event)\">버튼</a>",
"bad": "<div onclick=\"doSomething()\">클릭 영역</div>"
}
},
"enoughTime": {
"rule": "콘텐츠 읽고 사용할 충분한 시간 제공",
"implementation": [
"시간 제한이 있는 경우 연장 또는 해제 옵션 제공",
"자동 업데이트 콘텐츠 일시 정지 기능 제공",
"자동 슬라이드쇼 제어 기능 제공"
]
},
"seizures": {
"rule": "발작 유발 콘텐츠 방지",
"implementation": [
"초당 3회 이상 깜빡이는 콘텐츠 사용 금지",
"애니메이션 제어 기능 제공"
]
},
"navigable": {
"rule": "사용자가 탐색하고 콘텐츠를 찾을 수 있도록 지원",
"implementation": [
"페이지 타이틀 제공",
"의미 있는 순서로 포커스 이동",
"명확한 링크 텍스트 사용",
"여러 경로로 페이지 접근 제공",
"현재 위치 표시",
"의미 있는 헤딩 구조 사용"
]
},
"inputModalities": {
"rule": "다양한 입력 방식 지원",
"implementation": [
"터치 타겟 충분한 크기 제공 (최소 44x44px)",
"제스처 대체 수단 제공",
"모션 기능 비활성화 옵션 제공"
]
}
},
"understandable": {
"readable": {
"rule": "텍스트 콘텐츠를 읽고 이해할 수 있게 만들기",
"implementation": [
"페이지 언어 지정",
"특이한 단어나 약어 정의 제공",
"적절한 독해 수준 유지"
],
"examples": {
"good": "<html lang=\"ko\">",
"bad": "<html>"
}
},
"predictable": {
"rule": "예측 가능한 방식으로 웹페이지 작동",
"implementation": [
"포커스 시 자동 컨텍스트 변경 방지",
"입력 시 자동 컨텍스트 변경 방지",
"일관된 탐색 및 식별 제공"
]
},
"inputAssistance": {
"rule": "사용자의 실수 방지 및 정정 지원",
"implementation": [
"오류 식별 및 설명 제공",
"입력 지침 제공",
"오류 방지 및 수정 지원",
"중요 거래에 대한 확인 및 취소 기능 제공"
],
"errorHandling": {
"identification": "오류 발생 시 시각적, 텍스트적, 프로그래밍적으로 식별 가능하게 표시",
"suggestion": "오류 수정 방법 제안",
"prevention": "재확인, 검토, 취소 기능을 통한 오류 방지"
}
}
},
"robust": {
"compatible": {
"rule": "현재 및 미래의 기술과 호환성 유지",
"implementation": [
"유효한 HTML/마크업 사용",
"UI 컴포넌트에 적절한 이름, 역할, 값 제공",
"상태 메시지를 프로그래밍적으로 인식 가능하게 구현"
],
"examples": {
"good": "<button aria-pressed=\"false\" aria-label=\"메뉴 열기\">☰</button>",
"bad": "<div class=\"button\">☰</div>"
}
}
}
}
},
"aria": {
"landmarks": {
"required": [
"banner/header",
"navigation",
"main",
"contentinfo/footer"
],
"usage": {
"banner": "사이트 헤더 영역 (role=\"banner\" 또는 <header>)",
"navigation": "주 탐색 메뉴 (role=\"navigation\" 또는 <nav>)",
"main": "메인 콘텐츠 영역 (role=\"main\" 또는 <main>)",
"contentinfo": "푸터 영역 (role=\"contentinfo\" 또는 <footer>)",
"search": "검색 기능 (role=\"search\")",
"complementary": "보조 콘텐츠 (role=\"complementary\" 또는 <aside>)",
"form": "폼 영역 (role=\"form\" 또는 <form>)"
},
"examples": {
"header": "<header role=\"banner\">...</header>",
"nav": "<nav role=\"navigation\">...</nav>",
"main": "<main role=\"main\">...</main>",
"footer": "<footer role=\"contentinfo\">...</footer>"
}
},
"roles": {
"usage": "접근성 트리에 적절한 역할 정보 제공",
"guidelines": [
"시맨틱 HTML을 우선 사용하고 필요한 경우에만 ARIA 역할 추가",
"올바른 ARIA 역할과 속성 조합 사용",
"동적 콘텐츠 변화 시 적절한 역할과 속성 업데이트"
],
"examples": {
"button": "<div role=\"button\" tabindex=\"0\">...</div>",
"heading": "<div role=\"heading\" aria-level=\"2\">...</div>",
"checkbox": "<div role=\"checkbox\" aria-checked=\"false\">...</div>"
}
},
"states": {
"usage": "컴포넌트의 현재 상태를 스크린 리더에 전달",
"common": {
"aria-expanded": "확장 가능한 요소의 상태 (true/false)",
"aria-pressed": "토글 버튼의 상태 (true/false)",
"aria-selected": "선택 가능한 요소의 상태 (true/false)",
"aria-checked": "체크박스, 라디오 버튼의 상태 (true/false/mixed)",
"aria-disabled": "비활성화된 요소 (true/false)",
"aria-hidden": "화면에서 숨겨진 요소 (true/false)"
},
"examples": {
"expanded": "<button aria-expanded=\"false\">메뉴 열기</button>",
"pressed": "<button aria-pressed=\"true\">다크 모드</button>",
"selected": "<div role=\"tab\" aria-selected=\"true\">탭 1</div>"
}
},
"properties": {
"usage": "추가적인 의미 정보 제공",
"common": {
"aria-label": "시각적 레이블이 없을 때 요소 식별",
"aria-labelledby": "다른 요소의 ID를 참조하여 레이블 제공",
"aria-describedby": "다른 요소의 ID를 참조하여 상세 설명 제공",
"aria-controls": "현재 요소가 제어하는 요소의 ID",
"aria-live": "동적으로 변하는 영역 (polite/assertive/off)",
"aria-required": "필수 입력 필드 (true/false)"
},
"examples": {
"label": "<button aria-label=\"닫기\">X</button>",
"labelledby": "<div id=\"label\">이름</div><input aria-labelledby=\"label\">",
"describedby": "<input aria-describedby=\"hint\"><div id=\"hint\">힌트</div>"
}
},
"liveRegions": {
"usage": "동적으로 변하는 콘텐츠를 스크린 리더에 알림",
"attributes": {
"aria-live": "polite (중요하지 않은 업데이트), assertive (중요한 업데이트)",
"aria-atomic": "전체 영역을 읽을지 변경된 부분만 읽을지 지정 (true/false)",
"aria-relevant": "어떤 변경 사항을 알릴지 지정 (additions/removals/text/all)"
},
"examples": {
"notifications": "<div aria-live=\"polite\" aria-atomic=\"true\">알림 메시지</div>",
"alerts": "<div role=\"alert\">오류가 발생했습니다!</div>"
}
}
},
"focus": {
"management": {
"rule": "키보드 포커스의 논리적 이동 경로 제공",
"implementation": [
"탭 순서는 시각적 레이아웃과 일치하게 구성",
"모달 열림 시 포커스 모달로 이동, 닫힘 시 이전 요소로 복귀",
"JavaScript로 새 콘텐츠 추가 시 적절한 포커스 이동",
"스킵 네비게이션 링크 제공"
],
"tabindex": {
"0": "기본 탭 순서에 포함",
"-1": "프로그래밍 방식으로만 포커스 가능",
"positive": "사용을 권장하지 않음 (탭 순서 혼란 야기)"
}
},
"visibility": {
"rule": "포커스된 요소를 시각적으로 명확히 표시",
"implementation": [
"기본 포커스 스타일 유지 또는 명확한 대체 스타일 제공",
":focus-visible 스타일 정의",
"충분한 대비와 시각적 단서 제공"
],
"examples": {
"css": "button:focus-visible { outline: 3px solid #4D90FE; }"
}
}
},
"forms": {
"labels": {
"rule": "모든 폼 컨트롤에 레이블 제공",
"implementation": [
"<label> 요소 사용",
"aria-label 또는 aria-labelledby 속성 사용",
"그룹화된 컨트롤에 <fieldset>과 <legend> 사용"
],
"examples": {
"explicit": "<label for=\"name\">이름</label><input id=\"name\">",
"implicit": "<label>이름 <input></label>",
"aria": "<input aria-label=\"이름\">"
}
},
"instructions": {
"rule": "폼 작성에 필요한 지침 제공",
"implementation": [
"필드 형식 및 제약 사항 설명",
"필수 필드 표시",
"aria-describedby로 지침 연결"
],
"examples": {
"describedby": "<input aria-describedby=\"hint\"><div id=\"hint\">영문 대소문자, 숫자, 특수문자 포함 8자 이상</div>"
}
},
"validation": {
"rule": "오류 식별 및 해결 방법 제공",
"implementation": [
"오류 발생 시 명확한 오류 메시지 제공",
"오류 필드 시각적으로 표시",
"오류 메시지를 해당 필드와 프로그래밍적으로 연결",
"오류 수정 방법 안내"
],
"examples": {
"error": "<input aria-invalid=\"true\" aria-describedby=\"error\"><div id=\"error\">유효한 이메일 주소를 입력하세요.</div>"
}
}
},
"semantics": {
"structure": {
"rule": "콘텐츠의 구조와 관계를 코드에 명확히 표현",
"implementation": [
"적절한 헤딩 구조 사용 (h1-h6)",
"목록에 <ul>, <ol>, <dl> 사용",
"표에 <table>, <th>, <caption> 등 사용",
"관련 요소를 <section>, <article>, <aside> 등으로 그룹화"
],
"headings": {
"usage": "페이지 구조를 표현하는 헤딩 계층 구조 사용",
"hierarchy": "논리적으로 중첩된 수준 사용 (h1 > h2 > h3)",
"example": "<h1>사이트 제목</h1><h2>섹션 제목</h2><h3>하위 섹션</h3>"
}
},
"links": {
"rule": "링크 목적을 명확히 식별 가능하게 제공",
"implementation": [
"의미 있는 링크 텍스트 사용",
"같은 텍스트로 다른 목적지를 가리키는 링크 방지",
"필요시 aria-label로 추가 컨텍스트 제공"
],
"examples": {
"good": "<a href=\"pricing.html\">요금제 보기</a>",
"bad": "<a href=\"pricing.html\">여기를 클릭하세요</a>"
}
}
},
"media": {
"images": {
"rule": "모든 이미지에 적절한 대체 텍스트 제공",
"implementation": [
"의미 있는 이미지에 alt 텍스트 제공",
"복잡한 이미지에 상세 설명 제공",
"장식용 이미지에 alt=\"\" 사용"
],
"examples": {
"informative": "<img src=\"logo.png\" alt=\"회사 로고\">",
"decorative": "<img src=\"divider.png\" alt=\"\">",
"complex": "<img src=\"chart.png\" alt=\"2023년 분기별 매출\" aria-describedby=\"chart-desc\"><div id=\"chart-desc\">...</div>"
}
},
"audio": {
"rule": "오디오 콘텐츠에 대체 형식 제공",
"implementation": [
"자동 재생 제한",
"오디오 콘트롤 제공",
"대본 또는 요약 제공"
]
},
"video": {
"rule": "비디오 콘텐츠에 대체 형식 제공",
"implementation": [
"자막 제공",
"오디오 설명 제공",
"필요한 경우 수화 통역 제공",
"비디오 콘트롤 제공"
]
}
},
"mobile": {
"touchTargets": {
"rule": "터치 타겟 충분한 크기로 제공",
"implementation": [
"최소 터치 영역 44x44px 제공",
"터치 타겟 간 충분한 간격 유지",
"필요시 전체 영역 클릭 가능하게 구현"
]
},
"gestures": {
"rule": "복잡한 제스처에 대체 수단 제공",
"implementation": [
"복잡한 제스처에 버튼 등 대체 UI 제공",
"드래그 앤 드롭에 키보드 대체 수단 제공",
"멀티 포인트/경로 제스처 대체 인터페이스 제공"
]
},
"orientation": {
"rule": "화면 방향 제한 없이 사용 가능하게 구현",
"implementation": [
"콘텐츠를 가로/세로 모드 모두에서 사용 가능하게 디자인",
"방향 제한이 필요한 경우 예외적으로 적용 (게임 등)"
]
}
},
"testing": {
"tooling": {
"automated": [
"Lighthouse",
"axe",
"WAVE",
"Pa11y",
"ESLint-plugin-jsx-a11y"
],
"manual": [
"키보드 테스트",
"스크린 리더 테스트 (NVDA, VoiceOver, JAWS)",
"대비 확인",
"확대/축소 테스트"
]
},
"checklist": {
"keyboard": [
"모든 기능 키보드로 접근 및 조작 가능",
"포커스 순서 논리적",
"포커스 트랩 없음",
"포커스 표시 시각적으로 명확"
],
"screenReader": [
"모든 정보 스크린 리더로 인식 가능",
"정확한 대체 텍스트",
"논리적 읽기 순서",
"적절한 ARIA 역할, 상태, 속성 사용"
],
"visual": [
"텍스트 대비 충분",
"색상에만 의존하지 않는 정보 전달",
"200% 확대 시 가독성 유지",
"모든 포커스 상태 시각적으로 표시"
]
},
"userTesting": {
"target": "다양한 보조 기술 사용자 대상 테스트 권장",
"approach": "주요 사용자 흐름에 대한 테스트 시나리오 개발",
"feedback": "사용자 피드백 수집 및 개선 사항 도출"
}
}
}
}
\ No newline at end of file
{
"name": "Clean Code Rules",
"description": "클린 코드 원칙을 따르기 위한 규칙",
"rules": {
"functions": {
"maxLines": 20,
"maxParameters": 3,
"singleResponsibility": true,
"naming": {
"shouldBeVerb": true,
"shouldBeDescriptive": true
}
},
"classes": {
"maxMethods": 10,
"maxProperties": 10,
"singleResponsibility": true,
"cohesion": "high"
},
"variables": {
"maxLength": 30,
"shouldBeDescriptive": true,
"avoidAbbreviations": true
},
"comments": {
"whenToUse": [
"복잡한 비즈니스 로직 설명",
"API 문서화",
"TODO 주석"
],
"whenNotToUse": [
"자명한 코드 설명",
"사용하지 않는 코드"
]
},
"errorHandling": {
"useCustomExceptions": true,
"avoidNestedTryCatch": true,
"logErrors": true
},
"languageSpecific": {
"typescript": {
"interfaces": "명확한 책임을 가진 인터페이스 설계",
"types": "가능한 한 구체적인 타입 사용 (any 지양)",
"generics": "과도한 복잡성 없이 필요한 경우에만 사용",
"nullHandling": "null/undefined를 명시적으로 처리",
"enums": "연관된 상수 그룹에 열거형 사용",
"asyncAwait": "Promise 체인보다 async/await 선호",
"optionalChaining": "깊은 객체 접근 시 ?. 연산자 활용"
},
"javascript": {
"constUsage": "변경되지 않는 값에 const 사용",
"letUsage": "변경이 필요한 값에만 let 사용 (var 지양)",
"destructuring": "객체/배열 구조 분해 활용",
"spreadOperator": "객체 복사/병합 시 전개 연산자 활용",
"modules": "명확한 모듈 경계와 내보내기",
"asyncOperations": "콜백 대신 Promise 또는 async/await 사용",
"prototypeChain": "프로토타입 직접 수정 지양"
},
"python": {
"comprehensions": "적절한 경우 리스트/딕셔너리 컴프리헨션 사용",
"generators": "대용량 데이터 처리 시 제너레이터 활용",
"docstrings": "모든 함수/클래스에 독스트링 제공",
"typeHints": "타입 힌트로 코드 명확성 향상",
"contextManagers": "리소스 관리에 with문 활용",
"namedTuples": "의미 있는 필드명이 필요한 튜플에 namedtuple 사용",
"exceptions": "구체적인 예외 타입 사용 및 생성"
}
},
"codeComplexity": {
"metrics": {
"cyclomaticComplexity": {
"description": "코드 내 독립적인 경로의 수를 측정",
"maxValue": 10,
"measurement": "if, else, switch, case, for, while, catch 등의 분기문 수"
},
"cognitiveComplexity": {
"description": "코드 이해 난이도 측정",
"maxValue": 15,
"factors": [
"중첩 구조 깊이",
"분기 흐름 복잡도",
"논리적 결합도"
]
},
"maintainabilityIndex": {
"description": "코드 유지보수성 측정",
"minValue": 65,
"calculation": "Halstead Volume, Cyclomatic Complexity, 코드 라인 수 기반"
},
"depthOfInheritance": {
"description": "클래스 상속 구조 깊이",
"maxValue": 3
},
"fanOut": {
"description": "한 모듈이 의존하는 다른 모듈의 수",
"maxValue": 15
}
},
"refactoringTriggers": [
"메서드 복잡도 기준 초과 시 분리 리팩터링",
"함수 파라미터 3개 초과 시 객체 파라미터로 변경",
"중첩 조건문 3단계 이상 시 조기 반환 패턴 적용",
"코드 중복 발견 시 함수/클래스 추출"
],
"tooling": {
"static": ["ESLint", "SonarQube", "Pylint"],
"runtime": ["console.time", "프로파일러"]
}
},
"architecturalPatterns": {
"solid": {
"singleResponsibility": {
"description": "하나의 클래스는 하나의 책임만 가져야 함",
"examples": [
"사용자 인증 로직과 사용자 프로필 로직 분리",
"데이터 액세스 로직과 비즈니스 로직 분리"
]
},
"openClosed": {
"description": "확장에는 열려있고 수정에는 닫혀있어야 함",
"examples": [
"전략 패턴을 통한 알고리즘 확장",
"인터페이스를 통한 새 기능 추가"
]
},
"liskovSubstitution": {
"description": "하위 타입은 상위 타입을 대체할 수 있어야 함",
"examples": [
"공통 인터페이스 구현 클래스들의 일관된 동작",
"예외 발생 패턴 유지"
]
},
"interfaceSegregation": {
"description": "클라이언트는 사용하지 않는 인터페이스에 의존하지 않아야 함",
"examples": [
"큰 인터페이스를 작은 인터페이스로 분리",
"역할에 따른 인터페이스 분리"
]
},
"dependencyInversion": {
"description": "구체적인 것이 아닌 추상화에 의존해야 함",
"examples": [
"의존성 주입을 통한 결합도 감소",
"인터페이스를 통한 구현체 교체 용이성 확보"
]
}
},
"patterns": {
"frontend": [
"컴포넌트 기반 아키텍처",
"Flux/Redux 패턴",
"컨테이너-프레젠테이션 패턴",
"커스텀 훅을 통한 로직 재사용",
"상태 관리 추상화 패턴"
],
"backend": [
"계층형 아키텍처 (컨트롤러-서비스-리포지토리)",
"헥사고날 아키텍처",
"CQRS (명령 쿼리 책임 분리)",
"이벤트 소싱",
"마이크로서비스 패턴"
]
},
"guidelines": [
"모듈 간 명확한 책임 경계 설정",
"순환 의존성 제거",
"적절한 추상화 수준 유지",
"도메인 모델 중심 설계",
"기술적 세부사항 은닉"
]
},
"technicalDebt": {
"identification": {
"code": [
"TODO, FIXME 주석",
"Magic Number/String",
"과도한 복잡도 지표",
"테스트 부재",
"중복 코드"
],
"design": [
"깨진 창문 패턴 (작은 결함 방치)",
"과도한 클래스/모듈 의존성",
"명확하지 않은 아키텍처 경계",
"비일관적인 추상화 수준"
],
"process": [
"문서화 부족",
"자동화 테스트 부족",
"품질 게이트 우회",
"지속적인 통합/배포 부재"
]
},
"management": {
"tracking": {
"method": "이슈 트래커에 기술 부채 항목 등록 및 추적",
"labeling": "각 항목에 영향도, 복잡도, 우선순위 라벨 부여"
},
"prioritization": [
"사용자 경험에 직접 영향을 미치는 항목 우선 처리",
"신규 개발 효율성을 저해하는 항목 우선 처리",
"보안 위험이 있는 항목 최우선 처리"
],
"repayment": {
"strategies": [
"Boy Scout Rule (항상 발견된 코드를 처음보다 깨끗하게 유지)",
"기술 부채 상환 전용 스프린트 운영",
"새 기능 개발 시 관련 영역 기술 부채 함께 해결"
],
"budgeting": "개발 시간의 20-30%를 기술 부채 해결에 할당"
}
}
}
}
}
\ No newline at end of file
{
"name": "Code Style Rules",
"description": "일관된 코드 스타일을 유지하기 위한 규칙",
"rules": {
"indentation": {
"type": "spaces",
"size": 2
},
"maxLineLength": 100,
"namingConventions": {
"variables": "camelCase",
"functions": "camelCase",
"classes": "PascalCase",
"constants": "UPPER_SNAKE_CASE",
"interfaces": "PascalCase",
"typeAliases": "PascalCase",
"enums": "PascalCase",
"enumMembers": "PascalCase",
"generics": "PascalCase",
"privateMembers": "_camelCase",
"booleanVariables": "isPrefixOrHasSuffix",
"testFiles": "{name}.test.{ext} 또는 {name}.spec.{ext}"
},
"imports": {
"order": ["external", "internal", "relative"],
"groupBy": true
},
"comments": {
"fileHeader": {
"required": true,
"format": [
"/**",
" * @file {filename}",
" * @description {파일의 주요 목적과 기능 설명}",
" * @author {작성자}",
" * @date {작성일}",
" * @version {버전}",
" */"
]
},
"classHeader": {
"required": true,
"format": [
"/**",
" * @class {클래스명}",
" * @description {클래스의 주요 목적과 책임 설명}",
" * @example {사용 예시 코드}",
" */"
]
},
"methodHeader": {
"required": true,
"format": [
"/**",
" * @method {메서드명}",
" * @description {메서드의 주요 기능 설명}",
" * @param {파라미터명} {파라미터 설명}",
" * @returns {반환값 설명}",
" * @throws {발생 가능한 예외 설명}",
" * @example {사용 예시 코드}",
" */"
]
},
"inlineComments": {
"whenToUse": [
"복잡한 비즈니스 로직 설명",
"알고리즘 단계 설명",
"비표준 코드 설명",
"성능 최적화 설명"
],
"format": "// {설명}"
},
"todoComments": {
"format": "// TODO: {할 일 설명} - {담당자} - {예상 완료일}",
"requiredFields": ["description", "assignee", "dueDate"]
},
"sectionComments": {
"format": [
"// ============================================================================",
"// {섹션 제목}",
"// ============================================================================"
],
"whenToUse": [
"주요 기능 그룹 구분",
"파일 내 논리적 섹션 구분"
]
},
"documentation": {
"api": {
"required": true,
"format": [
"/**",
" * @api {method} {path} {title}",
" * @apiDescription {설명}",
" * @apiParam {type} {name} {설명}",
" * @apiSuccess {type} {name} {설명}",
" * @apiError {type} {name} {설명}",
" */"
]
},
"types": {
"required": true,
"format": [
"/**",
" * @typedef {Object} {TypeName}",
" * @property {type} {propertyName} {설명}",
" */"
]
}
}
},
"languageSpecific": {
"typescript": {
"strictNullChecks": true,
"noImplicitAny": true,
"preferInterface": false,
"strictFunctionTypes": true,
"useUnknownOverAny": true,
"useTypeAssertions": "as Type 방식 사용",
"importTypeFrom": "type { Type } from 'module'"
},
"javascript": {
"preferConst": true,
"useStrict": true,
"moduleSystem": "ESM",
"optionalChaining": true,
"nullishCoalescing": true
},
"python": {
"indentation": 4,
"maxLineLength": 88,
"stringQuotes": "\"\"\"",
"importStyle": "from module import Class, function",
"typeHints": "모든 함수에 사용",
"docstringStyle": "Google"
}
},
"formatters": {
"eslint": {
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended"
],
"rules": {
"no-console": "warn",
"prefer-const": "error",
"no-unused-vars": "warn",
"react/prop-types": "off",
"react/react-in-jsx-scope": "off"
}
},
"prettier": {
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "always"
}
},
"formattingTriggers": {
"onSave": true,
"preCommit": true,
"inCI": true,
"changedFilesOnly": true,
"automaticFixing": true
}
}
}
\ No newline at end of file
{
"name": "Design Guidelines",
"description": "UI/UX 디자인 가이드라인",
"rules": {
"colors": {
"primary": {
"main": "#1976d2",
"light": "#42a5f5",
"dark": "#1565c0"
},
"secondary": {
"main": "#9c27b0",
"light": "#ba68c8",
"dark": "#7b1fa2"
},
"error": "#d32f2f",
"warning": "#ed6c02",
"info": "#0288d1",
"success": "#2e7d32"
},
"darkMode": {
"colors": {
"background": {
"primary": "#121212",
"secondary": "#1e1e1e",
"paper": "#262626"
},
"text": {
"primary": "rgba(255, 255, 255, 0.87)",
"secondary": "rgba(255, 255, 255, 0.6)",
"disabled": "rgba(255, 255, 255, 0.38)"
},
"action": {
"active": "rgba(255, 255, 255, 0.7)",
"hover": "rgba(255, 255, 255, 0.1)",
"selected": "rgba(255, 255, 255, 0.08)"
}
},
"elevation": {
"ambient": "rgba(0, 0, 0, 0.05)",
"spotLight": "rgba(0, 0, 0, 0.2)"
},
"implementation": {
"strategy": "CSS 변수 기반 테마 전환",
"mediaQuery": "@media (prefers-color-scheme: dark) { ... }",
"userPreference": "localStorage 또는 쿠키에 저장"
}
},
"typography": {
"fontFamily": {
"primary": "Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, sans-serif",
"monospace": "Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace"
},
"fontSizes": {
"h1": "2.5rem",
"h2": "2rem",
"h3": "1.75rem",
"h4": "1.5rem",
"h5": "1.25rem",
"h6": "1rem",
"body": "1rem",
"small": "0.875rem"
},
"lineHeights": {
"tight": 1.2,
"normal": 1.5,
"relaxed": 1.75
}
},
"spacing": {
"base": "8px",
"multipliers": [0, 0.5, 1, 1.5, 2, 3, 4, 5, 6]
},
"breakpoints": {
"xs": "0px",
"sm": "600px",
"md": "900px",
"lg": "1200px",
"xl": "1536px"
},
"responsiveDesign": {
"approach": "모바일 우선(Mobile First) 디자인",
"gridSystem": "CSS Grid 또는 Flexbox 기반 12-column 시스템",
"mediaQueries": {
"xs": "@media (min-width: 0px)",
"sm": "@media (min-width: 600px)",
"md": "@media (min-width: 900px)",
"lg": "@media (min-width: 1200px)",
"xl": "@media (min-width: 1536px)"
},
"layoutPrinciples": [
"모바일에서는 단일 컬럼 레이아웃",
"태블릿에서는 2-3 컬럼 레이아웃",
"데스크톱에서는 다중 컬럼 레이아웃"
],
"adaptiveUI": {
"navigationPatterns": {
"mobile": "햄버거 메뉴 또는 바텀 내비게이션",
"desktop": "가로 메뉴 또는 사이드바"
},
"touchTargets": "모바일에서 최소 44x44px 크기 확보",
"fontSizing": "vw 또는 clamp() 함수를 사용한 반응형 폰트 크기"
},
"images": {
"srcset": "<img srcset=\"image-320w.jpg 320w, image-480w.jpg 480w, image-800w.jpg 800w\" sizes=\"(max-width: 600px) 100vw, 50vw\">",
"pictureElement": "<picture>...<source media=\"(max-width: 600px)\" srcset=\"...\">, ...</picture>"
}
},
"components": {
"buttons": {
"borderRadius": "4px",
"padding": "8px 16px",
"minHeight": "36px"
},
"inputs": {
"borderRadius": "4px",
"padding": "8px 12px",
"minHeight": "40px"
},
"cards": {
"borderRadius": "8px",
"padding": "16px",
"shadow": "0 2px 4px rgba(0,0,0,0.1)"
}
},
"animations": {
"timing": {
"veryFast": "100ms",
"fast": "200ms",
"normal": "300ms",
"slow": "500ms"
},
"easing": {
"standard": "cubic-bezier(0.4, 0.0, 0.2, 1)",
"decelerate": "cubic-bezier(0.0, 0.0, 0.2, 1)",
"accelerate": "cubic-bezier(0.4, 0.0, 1, 1)"
},
"transitions": {
"hover": "background-color {timing} {easing}, color {timing} {easing}, transform {timing} {easing}",
"pageTransition": "opacity {timing} {easing}, transform {timing} {easing}",
"modalOpen": "opacity {timing} {easing}, transform {timing} {easing}"
},
"motion": {
"principles": [
"목적이 있는 애니메이션 사용",
"부드럽고 자연스러운 움직임",
"사용자 제어감 유지",
"상태 변화의 명확한 시각화"
],
"patterns": {
"fadeIn": "opacity: 0 -> 1",
"slideIn": "transform: translateY(20px) -> translateY(0)",
"scale": "transform: scale(0.95) -> scale(1)",
"contentReveal": "height: 0 -> auto, opacity: 0 -> 1"
},
"reducedMotion": "@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }"
}
},
"iconsAndImages": {
"icons": {
"system": "Material Icons, Feather Icons 등 일관된 아이콘 시스템 사용",
"sizes": {
"small": "16x16px",
"medium": "24x24px",
"large": "32x32px"
},
"stroke": {
"width": "1.5-2px",
"linecap": "round",
"linejoin": "round"
},
"formats": ["SVG", "Icon Font"],
"color": "현재 텍스트 색상 상속 또는 명시적 컬러 사용"
},
"images": {
"aspectRatios": {
"standard": "16:9",
"portrait": "3:4",
"square": "1:1",
"wide": "21:9"
},
"quality": {
"web": "JPEG 품질 80%, WebP 품질 85%",
"thumbnail": "최적화된 저용량 이미지"
},
"treatment": {
"cornerRadius": "일관된 모서리 반경 적용",
"shadow": "필요한 경우에만 미묘한 그림자 적용",
"overlay": "텍스트 가독성을 위한 오버레이 적용 시 일관된 패턴 사용"
},
"accessibility": {
"altText": "모든 이미지에 설명적인 대체 텍스트 제공",
"decorative": "장식 이미지는 alt=\"\" 사용"
}
},
"illustrations": {
"style": "브랜드 아이덴티티와 일관된 일러스트레이션 스타일",
"usage": "빈 상태, 오류 상태, 성공 상태 등 주요 UI 상태 표현에 활용",
"principles": [
"단순하고 명확한 메시지 전달",
"다양한 화면 크기에서 가독성 유지",
"주변 UI 요소와의 조화"
]
}
},
"accessibility": {
"colorContrast": "4.5:1",
"focusVisible": true,
"skipLinks": true,
"ariaLabels": true
}
}
}
\ No newline at end of file
{
"name": "Documentation Rules",
"description": "효과적인 코드 및 프로젝트 문서화를 위한 규칙",
"rules": {
"codeDocumentation": {
"comments": {
"inline": {
"purpose": "복잡한 로직 설명, 의도가 명확하지 않은 코드 설명",
"style": "// 한 줄 주석은 간결하게",
"avoidRedundancy": "코드 자체가 명확한 경우 불필요한 주석 지양"
},
"block": {
"purpose": "여러 줄 설명이 필요한 복잡한 알고리즘, 로직",
"style": "/* 여러 줄 주석은 명확한 형식으로 */",
"structure": [
"주석의 맥락 설명",
"핵심 내용 설명",
"필요시 예제 또는 주의사항 추가"
]
},
"todo": {
"format": "// TODO: 설명 - 담당자(선택) - 날짜(선택)",
"usage": "향후 개선, 수정, 추가가 필요한 코드 표시",
"tracking": "TODO 주석은 이슈 트래킹 시스템과 연동 권장"
}
},
"jsDoc": {
"function": {
"required": true,
"template": [
"/**",
" * 함수에 대한 간략한 설명",
" * @param {타입} 파라미터명 - 파라미터 설명",
" * @returns {타입} 반환값 설명",
" * @throws {예외타입} 발생 가능한 예외 설명",
" * @example",
" * // 사용 예시 코드",
" */"
]
},
"class": {
"required": true,
"template": [
"/**",
" * 클래스에 대한 간략한 설명",
" * @class",
" * @implements {인터페이스} (해당시)",
" * @extends {부모클래스} (해당시)",
" * @example",
" * // 사용 예시 코드",
" */"
]
},
"interface": {
"required": true,
"template": [
"/**",
" * 인터페이스에 대한 간략한 설명",
" * @interface",
" * @property {타입} 속성명 - 속성 설명",
" */"
]
},
"module": {
"required": true,
"template": [
"/**",
" * @module 모듈명",
" * @description 모듈에 대한 간략한 설명",
" * @author 작성자 (선택)",
" */"
]
}
},
"types": {
"typescript": {
"required": true,
"interfaces": "명시적 인터페이스 정의 및 문서화",
"genericTypes": "제네릭 타입의 명확한 문서화",
"enums": "열거형 각 멤버의 용도 설명"
}
}
},
"projectDocumentation": {
"readme": {
"required": true,
"sections": [
"프로젝트 이름 및 간략한 설명",
"설치 방법",
"사용 방법 및 예제",
"API 참조 또는 링크",
"기여 방법",
"라이선스 정보"
],
"template": [
"# 프로젝트 이름",
"",
"## 개요",
"프로젝트에 대한 간략한 설명과 주요 기능",
"",
"## 시작하기",
"### 필요 조건",
"필요한 소프트웨어 및 종속성 목록",
"",
"### 설치",
"설치 단계 설명",
"",
"## 사용 방법",
"기본 사용법 예제",
"",
"## 주요 기능",
"주요 기능 및 사용 사례 설명",
"",
"## API 참조",
"API 문서 링크 또는 간략한 설명",
"",
"## 기여 방법",
"기여 가이드라인",
"",
"## 라이선스",
"라이선스 정보"
]
},
"contributing": {
"required": true,
"sections": [
"기여 과정 개요",
"개발 환경 설정",
"코드 스타일 가이드",
"테스트 방법",
"PR 및 이슈 제출 지침"
]
},
"changeLog": {
"required": true,
"format": "시맨틱 버전 기반 변경 내역 기록",
"template": [
"# 변경 내역",
"",
"## [버전] - 날짜",
"",
"### 추가",
"- 새로운 기능",
"",
"### 변경",
"- 기존 기능 변경",
"",
"### 수정",
"- 버그 수정",
"",
"### 제거",
"- 제거된 기능"
]
},
"architecture": {
"required": true,
"sections": [
"전체 시스템 구조",
"주요 컴포넌트 및 모듈",
"데이터 흐름",
"외부 시스템 통합",
"주요 설계 결정 및 이유"
],
"visualizations": "아키텍처 다이어그램, 시퀀스 다이어그램 등 시각적 자료 포함"
}
},
"apiDocumentation": {
"restApi": {
"required": true,
"format": "OpenAPI/Swagger 형식 권장",
"perEndpoint": {
"template": [
"## 엔드포인트: `[HTTP 메서드] /경로`",
"",
"### 설명",
"API 엔드포인트에 대한 설명",
"",
"### 요청",
"#### 헤더",
"필요한 헤더 정보",
"",
"#### 파라미터",
"- `paramName` (타입): 설명",
"",
"#### 요청 본문",
"```json",
"요청 본문 예시",
"```",
"",
"### 응답",
"#### 성공 응답 (상태 코드)",
"```json",
"응답 본문 예시",
"```",
"",
"#### 오류 응답 (상태 코드)",
"```json",
"오류 응답 예시",
"```",
"",
"### 예제",
"요청 및 응답 예제"
]
},
"tools": ["Swagger UI", "ReDoc", "Postman 컬렉션"]
},
"graphqlApi": {
"required": true,
"format": "GraphQL 스키마 문서화",
"sections": [
"타입 정의",
"쿼리 및 뮤테이션",
"인자 설명",
"사용 예제"
],
"tools": ["GraphQL Playground", "Apollo Studio", "GraphiQL"]
},
"eventApi": {
"required": true,
"perEvent": {
"template": [
"## 이벤트: `이벤트명`",
"",
"### 설명",
"이벤트에 대한 설명",
"",
"### 페이로드",
"```json",
"이벤트 페이로드 예시",
"```",
"",
"### 소비자",
"이 이벤트를 소비하는 서비스 목록",
"",
"### 발생 조건",
"이벤트가 발생하는 조건 설명"
]
}
}
},
"userDocumentation": {
"userGuide": {
"required": true,
"sections": [
"소개 및 개요",
"시작하기",
"기본 기능 사용법",
"고급 기능 사용법",
"문제 해결",
"용어 설명"
],
"format": "단계별 지침, 스크린샷 포함"
},
"faq": {
"required": true,
"organization": "주제별 그룹화",
"updates": "자주 받는 질문 지속적 업데이트"
},
"tutorials": {
"required": false,
"format": "특정 작업을 위한 단계별 가이드",
"multimedia": "가능한 경우 비디오 또는 애니메이션 제공"
}
},
"documentationMaintenance": {
"reviews": {
"frequency": "정기적인 문서 검토 (분기 또는 주요 릴리스 마다)",
"checklist": [
"정확성 확인",
"최신성 확인",
"완전성 확인",
"가독성 및 명확성 확인",
"예제 작동 확인"
]
},
"versioning": {
"approach": "문서 버전 관리 (소프트웨어 버전과 연동)",
"changelog": "문서 변경 사항 기록",
"archiving": "이전 버전 문서 보관"
},
"feedback": {
"mechanism": "사용자 피드백 수집 채널 마련",
"incorporation": "피드백 기반 문서 개선 프로세스"
}
},
"documentationTools": {
"codeDocumentation": {
"recommended": ["JSDoc", "TypeDoc", "Doxygen"],
"configuration": "프로젝트에 맞는 문서 생성 도구 설정"
},
"apiDocumentation": {
"recommended": ["Swagger/OpenAPI", "Slate", "Docusaurus"],
"automation": "API 변경 시 문서 자동 업데이트 구성"
},
"generalDocumentation": {
"recommended": ["Markdown", "Docusaurus", "VuePress", "MkDocs"],
"hosting": "문서 호스팅 전략 (GitHub Pages, Netlify 등)"
},
"diagramming": {
"recommended": ["PlantUML", "Mermaid.js", "Draw.io"],
"versionControl": "다이어그램 소스 코드 버전 관리"
}
}
}
}
\ No newline at end of file
{
"name": "Git Workflow Rules",
"description": "Git 작업 흐름을 관리하기 위한 규칙",
"rules": {
"branchNaming": {
"pattern": "^(feature|bugfix|hotfix|release)/[a-z0-9-]+$",
"examples": [
"feature/user-authentication",
"bugfix/login-error",
"hotfix/security-patch"
]
},
"commitMessage": {
"format": "<type>(<scope>): <description>",
"types": ["feat", "fix", "docs", "style", "refactor", "test", "chore"],
"maxLength": 72
},
"pullRequest": {
"requireDescription": true,
"requireReviewers": 1,
"requireTests": true
},
"cicd": {
"pipelines": {
"pr": {
"triggers": "모든 풀 리퀘스트",
"stages": [
"코드 린트",
"단위 테스트",
"통합 테스트",
"빌드 검증",
"성능 프로파일링"
],
"requirements": "모든 스테이지 통과 필요"
},
"main": {
"triggers": "메인 브랜치 병합 시",
"stages": [
"전체 테스트 스위트",
"코드 품질 분석",
"보안 취약점 스캔",
"빌드 및 아티팩트 생성",
"스테이징 환경 배포"
],
"notifications": "팀 채널에 배포 알림"
},
"release": {
"triggers": "릴리스 태그 또는 릴리스 브랜치 병합",
"stages": [
"버전 번호 검증",
"릴리스 노트 생성",
"프로덕션 환경 배포",
"스모크 테스트",
"모니터링 알림 설정"
],
"approvals": "DevOps 팀 승인 필요"
}
},
"environments": {
"dev": {
"purpose": "개발 중인 기능 테스트",
"deployment": "PR별 임시 환경 또는 개발자 환경",
"access": "개발팀 내부"
},
"staging": {
"purpose": "릴리스 전 통합 테스트",
"deployment": "메인 브랜치 자동 배포",
"dataStrategy": "익명화된 프로덕션 데이터 샘플"
},
"production": {
"purpose": "실제 사용자 서비스",
"deployment": "수동 승인 후 배포",
"rollback": "즉시 롤백 메커니즘 구현"
}
},
"artifacts": {
"storage": "AWS S3, GCP Storage, Azure Blob",
"versioning": "Git SHA 또는 시맨틱 버전",
"retention": "최근 10개 빌드 보관"
},
"tools": {
"ci": ["GitHub Actions", "Jenkins", "GitLab CI", "CircleCI"],
"deployment": ["Kubernetes", "Docker", "AWS CDK", "Terraform"],
"monitoring": ["Datadog", "New Relic", "Prometheus"]
}
},
"codeReview": {
"process": {
"steps": [
"자동화된 검사 통과 확인",
"코드베이스 이해와 맥락 파악",
"코드 품질 및 설계 검토",
"기능 요구사항 충족 여부 확인",
"피드백 제공 및 토론",
"수정 후 재검토",
"승인 및 병합"
],
"timeframe": "24시간 이내 첫 응답, 48시간 이내 검토 완료",
"size": "PR당 최대 500라인 변경 권장"
},
"checklist": {
"functionality": [
"기능 요구사항 충족 여부",
"엣지 케이스 처리",
"오류 처리 및 복구",
"성능 고려사항",
"접근성 요구사항"
],
"code_quality": [
"코드 스타일 및 포맷팅",
"명명 규칙 준수",
"중복 코드 및 복잡성",
"주석 및 문서화",
"모듈화 및 재사용성"
],
"security": [
"입력 검증",
"인증 및 권한 검사",
"민감 정보 처리",
"OWASP 취약점 방지",
"의존성 보안 이슈"
],
"testing": [
"테스트 커버리지",
"테스트 케이스 품질",
"시나리오 테스트 포함",
"성능 및 부하 테스트",
"회귀 테스트"
]
},
"feedback": {
"constructive": "문제점과 함께 개선 방향 제시",
"specific": "구체적인 코드 라인 및 컨텍스트 참조",
"objective": "개인이 아닌 코드에 초점",
"prioritized": "중요도에 따라 Must-fix와 Nice-to-have 구분"
},
"tools": {
"platforms": ["GitHub PR", "GitLab MR", "Bitbucket PR"],
"automation": ["Danger JS", "CodeClimate", "SonarQube"],
"review_apps": "PR별 임시 배포 환경 제공"
}
},
"versionManagement": {
"scheme": {
"semantic": "MAJOR.MINOR.PATCH (X.Y.Z)",
"rules": [
"MAJOR: 하위 호환성을 깨는 변경",
"MINOR: 하위 호환성을 유지하는 새 기능",
"PATCH: 버그 수정 및 작은 개선"
],
"prerelease": "X.Y.Z-alpha.N, X.Y.Z-beta.N, X.Y.Z-rc.N"
},
"tagging": {
"format": "v1.2.3",
"process": "릴리스 브랜치에서 태그 생성 및 릴리스 노트 작성",
"signing": "릴리스 태그는 GPG 서명 필요"
},
"release": {
"cadence": {
"major": "연 1-2회, 주요 기능 변경 시",
"minor": "분기별 또는 주요 기능 추가 시",
"patch": "필요시 (버그 수정, 긴급 패치)"
},
"process": [
"릴리스 브랜치 생성 (release/vX.Y.Z)",
"QA 및 테스트 완료",
"릴리스 노트 및 변경 이력 작성",
"최종 버전 번호 태그 생성",
"프로덕션 배포",
"메인 브랜치에 병합"
],
"hotfix": [
"프로덕션 코드에서 hotfix 브랜치 생성",
"수정 및 테스트",
"패치 버전 증가",
"프로덕션 배포 및 태그 생성",
"메인 브랜치에 백포트"
]
},
"changelog": {
"format": "Keep a Changelog 기반 (keepachangelog.com)",
"sections": [
"Added (추가된 기능)",
"Changed (변경된 기능)",
"Deprecated (곧 제거될 기능)",
"Removed (제거된 기능)",
"Fixed (수정된 버그)",
"Security (보안 이슈 해결)"
],
"tools": ["conventional-changelog", "standard-version", "release-it"]
}
},
"issueAndPrTemplates": {
"issues": {
"types": {
"bug": {
"title": "제목은 명확하고 구체적으로 문제 설명",
"sections": [
"버그 설명",
"재현 단계",
"기대 동작",
"실제 동작",
"환경 정보",
"스크린샷 또는 로그",
"가능한 해결책"
],
"labels": ["bug", "priority-?", "status-?"]
},
"feature": {
"title": "간결하고 명확한 기능 이름",
"sections": [
"기능 개요",
"필요성 및 목적",
"상세 요구사항",
"대안 방법",
"허용 기준",
"디자인/목업"
],
"labels": ["enhancement", "priority-?", "scope-?"]
},
"technical": {
"title": "기술 부채 또는 리팩토링 제목",
"sections": [
"현재 상태",
"문제점",
"제안하는 변경사항",
"기대 효과",
"위험 요소"
],
"labels": ["technical-debt", "refactoring"]
}
},
"management": {
"status_tracking": "라벨 및 프로젝트 보드 활용",
"estimation": "포인트 또는 T-셔츠 사이즈 기반 작업량 추정",
"assignment": "깃헙 이슈 할당 또는 셀프-할당 체계",
"milestones": "릴리스 또는 스프린트 마일스톤 설정"
}
},
"pullRequests": {
"template": {
"sections": [
"관련 이슈",
"변경 내용 설명",
"테스트 방법",
"스크린샷 (UI 변경 시)",
"체크리스트"
],
"checklist": [
"코드 스타일 가이드 준수",
"테스트 코드 작성",
"문서 업데이트",
"릴리스 노트 항목 추가"
]
},
"labels": {
"size": ["size-xs", "size-s", "size-m", "size-l", "size-xl"],
"type": ["feature", "bugfix", "hotfix", "refactor", "docs"],
"status": ["ready-for-review", "in-review", "changes-requested", "approved"]
},
"automated_checks": [
"PR 크기 라벨 자동 부여",
"테스트 커버리지 확인",
"코드 스타일 검사",
"이슈 링크 확인",
"충돌 확인"
],
"merge_strategy": {
"method": "Squash and merge",
"title": "이슈 번호 및 간결한 설명",
"cleanup": "병합 후 브랜치 자동 삭제"
}
},
"automation": {
"tools": ["Probot", "GitHub Actions", "Zapier"],
"actions": [
"새 이슈에 자동 라벨 지정",
"비활성 PR 알림",
"의존성 업데이트 자동화",
"관련 문서 업데이트 확인"
]
}
}
}
}
\ No newline at end of file
{
"name": "Lint and Automation Rules",
"description": "코드 스타일 및 품질 규칙 자동화를 위한 설정 가이드",
"rules": {
"lintersConfiguration": {
"typescript": {
"eslint": {
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended"
],
"plugins": [
"@typescript-eslint",
"react",
"react-hooks",
"prettier",
"import",
"jsx-a11y"
],
"rules": {
"quotes": ["error", "single"],
"semi": ["error", "always"],
"indent": ["error", 2],
"no-console": "warn",
"no-unused-vars": "warn",
"prefer-const": "error",
"react/prop-types": "off",
"react/react-in-jsx-scope": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "warn",
"jsx-a11y/alt-text": "error",
"import/order": [
"error",
{
"groups": ["builtin", "external", "internal", "parent", "sibling", "index"],
"newlines-between": "always"
}
]
}
},
"prettier": {
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "always"
}
},
"javascript": {
"eslint": {
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended"
],
"plugins": [
"react",
"react-hooks",
"prettier",
"import",
"jsx-a11y"
],
"rules": {
"quotes": ["error", "single"],
"semi": ["error", "always"],
"indent": ["error", 2],
"no-console": "warn",
"no-unused-vars": "warn",
"prefer-const": "error"
}
}
},
"python": {
"flake8": {
"max-line-length": 88,
"extend-ignore": "E203",
"exclude": ["venv", ".venv", "env", ".env", ".git", "__pycache__"],
"per-file-ignores": {
"__init__.py": "F401",
"test_*.py": "E501"
}
},
"black": {
"line-length": 88,
"target-version": ["py38", "py39", "py310"],
"include": "\\.py$",
"exclude": "/(venv|\\.git)/",
"preview": true
},
"isort": {
"profile": "black",
"line_length": 88,
"multi_line_output": 3,
"include_trailing_comma": true,
"force_grid_wrap": 0,
"use_parentheses": true
},
"mypy": {
"python_version": "3.9",
"disallow_untyped_defs": true,
"disallow_incomplete_defs": true,
"check_untyped_defs": true,
"disallow_untyped_decorators": true,
"ignore_missing_imports": false
}
},
"css": {
"stylelint": {
"extends": ["stylelint-config-standard"],
"plugins": ["stylelint-order"],
"rules": {
"order/properties-alphabetical-order": true,
"color-hex-case": "lower",
"color-hex-length": "short",
"at-rule-no-unknown": null
}
}
}
},
"gitHooks": {
"preCommit": {
"enabled": true,
"commands": [
"lint-staged",
"npm run test:affected"
],
"configuration": {
"lintStaged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss}": [
"stylelint --fix",
"prettier --write"
],
"*.py": [
"black",
"isort",
"flake8"
],
"*.{json,md}": "prettier --write"
}
}
},
"prePush": {
"enabled": true,
"commands": [
"npm run test:all",
"npm run build"
]
},
"commitMsg": {
"enabled": true,
"tool": "commitlint",
"configuration": {
"extends": ["@commitlint/config-conventional"],
"rules": {
"header-max-length": [2, "always", 72],
"type-enum": [
2,
"always",
["feat", "fix", "docs", "style", "refactor", "test", "chore", "ci", "build", "perf"]
]
}
}
}
},
"editorIntegration": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter",
"stylelint.vscode-stylelint",
"streetsidesoftware.code-spell-checker"
],
"settings": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
}
}
},
"cursorExtensionSettings": {
"easyAutoFix": true,
"lintOnSave": true,
"inlineErrors": true,
"autoImport": true,
"codeSuggestions": true
}
},
"ciIntegration": {
"githubActions": {
"workflows": {
"lint": {
"name": "Lint",
"triggers": ["push", "pull_request"],
"jobs": [
"eslint",
"prettier",
"stylelint",
"python-lint"
]
},
"test": {
"name": "Test",
"triggers": ["push", "pull_request"],
"jobs": [
"unit-tests",
"integration-tests"
]
},
"quality": {
"name": "Code Quality",
"triggers": ["pull_request"],
"jobs": [
"sonarqube",
"code-climate"
]
}
}
},
"jenkinsIntegration": {
"pipeline": {
"stages": [
"Lint",
"Test",
"Code Quality"
],
"parallel": true
}
}
},
"automationTools": {
"dependencyManagement": {
"renovate": {
"extends": [
"config:base",
":preserveSemverRanges",
"group:allNonMajor"
],
"schedule": ["every weekend"],
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"matchCurrentVersion": "!/^0/",
"automerge": true
}
]
},
"dependabot": {
"version": 2,
"updates": [
{
"package-ecosystem": "npm",
"directory": "/",
"schedule": {
"interval": "weekly"
},
"assignees": ["team-frontend"],
"reviewers": ["lead-dev"]
},
{
"package-ecosystem": "pip",
"directory": "/",
"schedule": {
"interval": "weekly"
},
"assignees": ["team-backend"],
"reviewers": ["lead-dev"]
}
]
}
},
"issueManagement": {
"staleBot": {
"daysUntilStale": 60,
"daysUntilClose": 7,
"exemptLabels": ["pinned", "security", "enhancement"]
}
}
}
}
}
\ No newline at end of file
{
"name": "Performance Optimization Rules",
"description": "애플리케이션 성능 최적화를 위한 규칙 및 가이드라인",
"rules": {
"initialLoading": {
"metrics": {
"ttfb": {
"target": "< 200ms",
"description": "Time to First Byte - 서버 응답 시작 시간"
},
"fcp": {
"target": "< 1.8s",
"description": "First Contentful Paint - 첫 콘텐츠 렌더링 시간"
},
"lcp": {
"target": "< 2.5s",
"description": "Largest Contentful Paint - 주요 콘텐츠 렌더링 시간"
},
"tti": {
"target": "< 3.8s",
"description": "Time to Interactive - 사용자 상호작용 가능 시간"
},
"tbt": {
"target": "< 300ms",
"description": "Total Blocking Time - 메인 스레드 차단 시간"
},
"cls": {
"target": "< 0.1",
"description": "Cumulative Layout Shift - 레이아웃 변동 지표"
}
},
"strategies": {
"codeOptimization": [
"코드 분할 (Code Splitting): 경로 기반, 컴포넌트 기반",
"트리 쉐이킹 (Tree Shaking): 미사용 코드 제거",
"지연 로딩 (Lazy Loading): 필요한 시점에 모듈 로드"
],
"assetOptimization": [
"이미지 최적화: WebP/AVIF 형식 사용, 적절한 크기 조정",
"폰트 최적화: WOFF2 사용, 폰트 서브셋, preload 적용",
"자원 압축: Gzip, Brotli 압축 활성화"
],
"caching": [
"효과적인 캐시 정책 설정 (Cache-Control 헤더)",
"정적 자산 적극 캐싱",
"CDN 활용: 정적 자산 배포 및 캐싱"
],
"serverOptimization": [
"서버 응답 시간 개선: 데이터베이스 쿼리 최적화, 캐싱",
"HTTP/2 또는 HTTP/3 활용",
"필요한 경우 서버 사이드 렌더링(SSR) 또는 정적 사이트 생성(SSG) 적용"
]
}
},
"rendering": {
"general": [
"불필요한 렌더링 방지",
"적절한 키(key) 사용으로 DOM 재사용 최적화",
"가상화 적용: 긴 목록이나 테이블에 가상 스크롤 적용"
],
"react": {
"memoization": [
"React.memo, useMemo, useCallback 적절히 사용",
"렌더링 최적화를 위한 컴포넌트 분리",
"상태 관리 계층화"
],
"stateManagement": [
"지역 상태와 전역 상태 적절히 분리",
"상태 업데이트 일괄 처리",
"불변성 유지를 위한 효율적인 패턴 사용"
]
},
"vue": {
"reactivity": [
"반응형 시스템 이해 및 최적화",
"computed 속성과 watch 적절히 사용",
"v-once, v-memo 디렉티브 활용"
],
"rendering": [
"키(key) 속성 적절히 사용",
"불필요한 컴포넌트 래핑 피하기",
"큰 리스트는 가상 스크롤링 적용"
]
},
"angular": {
"changeDetection": [
"OnPush 변경 감지 전략 적용",
"NgZone 이해 및 최적화",
"trackBy 함수 사용하여 목록 렌더링 최적화"
],
"performance": [
"지연 로딩 모듈 적극 활용",
"Pure Pipes 활용",
"AOT 컴파일러 활용"
]
}
},
"memoryManagement": {
"memoryLeaks": {
"common": [
"미사용 이벤트 리스너 제거",
"타이머 및 인터벌 정리",
"DOM 참조 적절히 해제"
],
"closure": "클로저에 의한 의도치 않은 메모리 유지 방지",
"observables": "구독(subscription) 명시적 해제"
},
"dataStructures": [
"적절한 자료구조 선택",
"대용량 데이터는 필요한 부분만 로드",
"데이터 정규화 및 중복 제거"
],
"garbageCollection": [
"긴 GC 작업 방지를 위한 객체 재사용",
"객체 풀링 패턴 고려",
"최대 메모리 사용량 모니터링 및 관리"
]
},
"networkOptimization": {
"requests": {
"minimize": "HTTP 요청 최소화 (번들링, 스프라이트, 인라인)",
"prioritize": "중요 리소스 preload/prefetch",
"parallelize": "동시 요청 최적화 (HTTP/2 활용)"
},
"dataTransfer": {
"compression": "네트워크 데이터 압축 (Gzip, Brotli)",
"minification": "JS, CSS, HTML 최소화",
"binaryFormats": "적절한 경우 바이너리 형식 사용 (protobuf 등)"
},
"api": {
"payloadSize": "필요한 데이터만 요청/응답",
"pagination": "대용량 데이터 페이지네이션 구현",
"caching": "클라이언트측 캐싱 및 서버측 캐싱 활용"
}
},
"bundleSize": {
"monitoring": {
"tools": ["Webpack Bundle Analyzer", "Lighthouse", "source-map-explorer"],
"metrics": "초기 로드 번들 < 170KB (압축 후)",
"tracking": "번들 크기 변화 추적 및 회귀 방지"
},
"optimization": {
"dependencies": [
"불필요한 의존성 제거",
"경량 대안 사용 (lodash-es, date-fns 등)",
"의존성 크기 의식적 관리"
],
"codeSplitting": [
"경로 기반 코드 분할",
"컴포넌트 기반 코드 분할",
"공통 청크 최적화"
],
"dynamicImports": [
"필요 시점에 동적 임포트 사용",
"모듈 프리로딩 전략 적용",
"중요도에 따른 로딩 우선순위 설정"
]
},
"buildOptimization": {
"modes": [
"개발 모드와 프로덕션 모드 구분",
"프로덕션 빌드 최적화 활성화",
"소스맵 전략 수립 (프로덕션에서 인라인 소스맵 지양)"
],
"tools": [
"Babel/SWC 최적화 옵션 활용",
"트리쉐이킹 보장을 위한 모듈 구조 설계",
"빌드 캐싱 활용"
]
}
},
"monitoring": {
"userMetrics": {
"realUser": [
"실제 사용자 성능 메트릭 수집",
"지역별, 기기별, 네트워크별 세분화",
"핵심 성능 지표 (Core Web Vitals) 모니터링"
],
"customMetrics": [
"비즈니스 관련 성능 지표 정의",
"사용자 만족도와 성능 상관관계 분석",
"주요 사용자 경로 성능 추적"
]
},
"technicalMetrics": {
"server": [
"API 응답 시간 모니터링",
"서버 리소스 사용량 (CPU, 메모리, 디스크 I/O)",
"데이터베이스 쿼리 성능"
],
"client": [
"메모리 사용량 추적",
"프레임 레이트 & 자바스크립트 실행 시간",
"렌더링 성능 병목 식별"
]
},
"tools": {
"analytics": ["Google Analytics", "Adobe Analytics", "Matomo"],
"monitoring": ["New Relic", "Datadog", "Sentry"],
"lab": ["Lighthouse", "WebPageTest", "Chrome DevTools"]
}
},
"specificOptimizations": {
"images": {
"formats": "WebP/AVIF 우선, PNG/JPG 폴백",
"loading": "지연 로딩(lazy loading), 적절한 크기",
"responsive": "이미지 srcset 및 sizes 적절히 사용"
},
"fonts": {
"loading": "font-display: swap 또는 optional",
"formats": "WOFF2 우선, 필요 시 WOFF 폴백",
"strategies": "폰트 서브셋팅, preload 중요 폰트"
},
"animations": {
"techniques": "CSS 애니메이션 우선, JS는 필요시만",
"properties": "transform/opacity 우선 사용(합성 레이어)",
"timing": "중요한 로딩 과정에서 무거운 애니메이션 자제"
},
"dataHandling": {
"pagination": "필요한 데이터만 로드",
"caching": "클라이언트 캐싱 적극 활용",
"prefetching": "다음 사용자 작업 예측하여 데이터 미리 로드"
}
}
}
}
\ No newline at end of file
{
"name": "Project Structure Rules",
"description": "효율적인 프로젝트 구조화 및 파일 조직을 위한 규칙",
"rules": {
"directoryStructure": {
"frontend": {
"reactApp": {
"root": [
"src/: 소스 코드",
"public/: 정적 파일",
"build/ or dist/: 빌드 출력물 (gitignore)",
"node_modules/: 패키지 (gitignore)"
],
"src": [
"assets/: 이미지, 아이콘, 폰트 등",
"components/: 재사용 가능한 UI 컴포넌트",
"hooks/: 커스텀 훅",
"contexts/: React 컨텍스트",
"pages/ or views/: 페이지 컴포넌트",
"services/: API 호출, 외부 서비스 연결",
"utils/: 유틸리티 함수",
"types/: 타입 정의 (TypeScript)",
"styles/: 전역 스타일 및 테마",
"constants/: 상수 값"
],
"components": [
"atomic design 패턴 또는 기능별 구조 사용",
"각 컴포넌트는 폴더 내 index, component, styles, tests 파일로 구성",
"공통 컴포넌트와 페이지 특정 컴포넌트 구분"
]
},
"nextApp": {
"root": [
"app/: 페이지 및 라우팅 (App Router)",
"pages/: 페이지 및 라우팅 (Pages Router)",
"public/: 정적 파일",
"components/: 컴포넌트",
".next/: 빌드 출력물 (gitignore)"
],
"appDirectory": [
"layout.tsx: 레이아웃 컴포넌트",
"page.tsx: 페이지 컴포넌트",
"[param]/: 동적 경로",
"@namespace/: 병렬 라우트",
"(group)/: 라우트 그룹"
],
"separation": [
"클라이언트/서버 컴포넌트 구분",
"서버 액션 및 API 라우트 명확히 구분",
"metadata 활용"
]
},
"vueApp": {
"root": [
"src/: 소스 코드",
"public/: 정적 파일",
"dist/: 빌드 출력물 (gitignore)"
],
"src": [
"assets/: 이미지, 폰트 등",
"components/: 컴포넌트",
"views/ or pages/: 페이지 컴포넌트",
"router/: 라우트 정의",
"store/: 상태 관리 (Pinia/Vuex)",
"services/: API 및 외부 서비스",
"utils/: 유틸리티 함수",
"composables/: 조합형 함수 (Vue 3)"
]
},
"angularApp": {
"src": [
"app/: 애플리케이션 코드",
"assets/: 이미지, 폰트 등",
"environments/: 환경 설정"
],
"app": [
"core/: 핵심 서비스, 가드, 인터셉터",
"shared/: 공유 모듈, 컴포넌트, 디렉티브",
"features/: 기능별 모듈",
"layouts/: 레이아웃 컴포넌트"
],
"features": [
"각 기능은 독립적인 Angular 모듈로 구현",
"컴포넌트, 서비스, 모델 등 관련 파일 함께 보관",
"기능별 라우팅 모듈 구현"
]
}
},
"backend": {
"nodeExpress": {
"root": [
"src/: 소스 코드",
"dist/: 빌드 출력물 (TypeScript)",
"tests/: 테스트 파일",
"config/: 설정 파일"
],
"src": [
"controllers/: 라우트 핸들러",
"models/: 데이터 모델",
"routes/: 라우트 정의",
"middlewares/: 미들웨어",
"services/: 비즈니스 로직",
"utils/: 유틸리티 함수",
"types/: 타입 정의 (TypeScript)"
]
},
"nestjs": {
"src": [
"modules/: 기능별 모듈",
"shared/: 공유 모듈 및 서비스",
"config/: 설정",
"main.ts: 애플리케이션 진입점"
],
"module": [
"controllers/: 컨트롤러",
"services/: 서비스",
"dto/: 데이터 전송 객체",
"entities/: 엔티티 (데이터베이스 모델)",
"repositories/: 커스텀 저장소"
]
},
"django": {
"root": [
"apps/: 앱 모듈",
"config/: 프로젝트 설정",
"static/: 정적 파일",
"templates/: 템플릿 파일",
"media/: 사용자 업로드 파일",
"requirements/: 의존성 파일"
],
"app": [
"models.py: 데이터 모델",
"views.py: 뷰 함수/클래스",
"urls.py: URL 패턴",
"admin.py: 관리자 인터페이스",
"serializers.py: API 직렬화"
]
},
"springBoot": {
"src": [
"main/java/com/company/app/: 자바 소스",
"main/resources/: 설정 및 리소스",
"test/: 테스트 코드"
],
"javaStructure": [
"controllers/: 컨트롤러",
"services/: 서비스",
"repositories/: 저장소",
"entities/ or models/: 데이터 모델",
"dto/: 데이터 전송 객체",
"config/: 설정 클래스",
"exceptions/: 예외 처리",
"utils/: 유틸리티 클래스"
]
}
},
"fullstack": {
"monorepo": {
"root": [
"packages/: 패키지 디렉토리",
"apps/: 애플리케이션 디렉토리"
],
"packages": [
"ui/: UI 컴포넌트 라이브러리",
"config/: 공유 설정",
"utils/: 공유 유틸리티",
"types/: 공유 타입 정의",
"api/: API 클라이언트 또는 서버"
],
"tooling": [
"Lerna, Nx, Turborepo 등 모노레포 도구 활용",
"공유 빌드 설정 및 스크립트",
"워크스페이스 간 의존성 관리"
]
},
"microservices": {
"services": [
"각 마이크로서비스는 독립적인 프로젝트 구조 가짐",
"서비스 간 중복 최소화를 위한 공유 라이브러리",
"서비스 간 API 계약 정의 및 문서화"
],
"infrastructure": [
"API 게이트웨이 설정",
"서비스 디스커버리 구성",
"배포 및 오케스트레이션 설정"
]
}
}
},
"naming": {
"files": {
"general": [
"일관된 네이밍 컨벤션 사용 (kebab-case, camelCase 등)",
"파일 내용을 명확히 설명하는 이름 사용",
"축약어 사용 자제"
],
"components": {
"react": "PascalCase.tsx, 예: UserProfile.tsx",
"vue": "PascalCase.vue, 예: UserProfile.vue",
"angular": "kebab-case.component.ts, 예: user-profile.component.ts"
},
"tests": {
"pattern": "{파일명}.test.{확장자} or {파일명}.spec.{확장자}",
"examples": "user-service.test.ts, UserProfile.spec.tsx"
}
},
"directories": {
"general": [
"복수형 사용 (components/, utils/, services/)",
"features나 모듈은 단수형 가능 (auth/, user/, product/)",
"일관된 대소문자 사용 (kebab-case 또는 camelCase 권장)"
],
"hierarchies": [
"논리적 계층 구조 활용",
"너무 깊은 중첩 피하기 (최대 4-5단계)",
"관련 코드를 함께 그룹화"
]
}
},
"modularization": {
"principles": [
"단일 책임 원칙 (SRP) 준수",
"관심사 분리 (Separation of Concerns)",
"적절한 추상화 수준",
"응집도 높고 결합도 낮게 설계"
],
"techniques": {
"frontend": [
"기능별 모듈화",
"재사용 가능한 컴포넌트 설계",
"페이지/라우트 기반 코드 분할"
],
"backend": [
"도메인 주도 설계 (DDD) 원칙 적용",
"수직 슬라이스 (Vertical Slice) 아키텍처 고려",
"마이크로서비스 경계 명확히 정의"
]
},
"dependencies": {
"management": [
"명시적 의존성 선언",
"의존성 주입 패턴 활용",
"순환 의존성 방지"
],
"optimization": [
"필요한 기능만 가져오는 트리 쉐이킹 가능한 구조",
"불필요한 의존성 최소화",
"최신 패키지 관리자 기능 활용 (pnpm, Yarn Berry 등)"
]
}
},
"configuration": {
"principles": [
"환경별 설정 분리 (개발, 테스트, 프로덕션)",
"민감 정보는 환경 변수로 관리",
"기본값 제공 및 문서화"
],
"structure": {
"dotenv": ".env.{환경} 파일 활용",
"configFiles": "환경별 설정 파일 구성 (예: config.dev.js, config.prod.js)",
"validation": "설정 스키마 검증 (yup, joi, zod 등)"
},
"management": [
"구성 요소를 기능별로 모듈화",
"설정 값의 단일 진실 공급원 (SSOT) 유지",
"변경 가능성에 따른 설정 분리"
]
},
"codeOrganization": {
"imports": {
"order": [
"외부 라이브러리 임포트",
"내부 모듈 임포트 (절대 경로)",
"상대 경로 임포트",
"스타일/자산 임포트"
],
"aliasing": "절대 경로 임포트 활성화 (tsconfig.json, jsconfig.json)",
"grouping": "관련 임포트 그룹화 및 알파벳 순 정렬"
},
"codeBlocks": {
"orderOfDeclarations": [
"타입/인터페이스 선언",
"상수",
"유틸리티 함수",
"훅/상태 관리",
"컴포넌트/클래스",
"내보내기"
],
"size": "파일 크기 제한 (일반적으로 300-500줄 미만 권장)"
},
"documentationStrategy": [
"주요 모듈, 인터페이스, 함수에 JSDoc/TSDoc 주석 사용",
"코드 구조 및 아키텍처 문서화 (README.md 파일)",
"의도가 명확하지 않은 복잡한 로직에 인라인 주석 추가"
]
}
}
}
\ No newline at end of file
{
"name": "Rules Maintenance and Documentation",
"description": "코드 규칙 문서화, 교육 및 유지보수를 위한 가이드라인",
"rules": {
"documentation": {
"overview": {
"format": "웹 문서 또는 Markdown 형식",
"location": "프로젝트 루트의 docs/ 디렉토리 및 내부 Wiki",
"sections": [
"규칙 목적 및 원칙",
"규칙 범주 개요",
"적용 방법 및 예외 처리",
"자주 묻는 질문"
]
},
"ruleGuides": {
"structure": {
"header": "규칙 제목, 버전, 수정일",
"description": "규칙의 목적 및 배경",
"specification": "상세 규칙 내용",
"examples": {
"good": "모범 사례 예시 (✅)",
"bad": "안티 패턴 예시 (❌)"
},
"implementation": "적용 방법 및 도구 설정",
"exceptions": "예외 상황 및 처리 방법"
},
"format": "각 규칙 카테고리별 별도 문서 작성",
"tooling": "README 자동 생성 스크립트 제공"
},
"codeExamples": {
"repository": "샘플 코드 저장소 구성",
"structure": {
"beforeAfter": "규칙 적용 전/후 코드 비교",
"patterns": "주요 패턴별 예제 코드",
"antiPatterns": "피해야 할 패턴 예제"
},
"organization": "규칙 카테고리별 폴더 구성"
},
"visualAids": {
"diagrams": "아키텍처 및 패턴 시각화",
"flowcharts": "결정 흐름도 제공",
"cheatSheets": "주요 규칙 요약 시트 제공"
}
},
"education": {
"onboarding": {
"materials": [
"신규 입사자 규칙 가이드 문서",
"학습 경로 정의",
"주요 규칙 요약 문서"
],
"steps": [
"핵심 규칙 소개 세션",
"멘토의 코드 리뷰를 통한 피드백",
"자체 평가 문제 및 퀴즈",
"적용 연습 예제 프로젝트"
],
"timeframe": "첫 2주 이내 완료"
},
"continuousLearning": {
"sessions": {
"frequency": "월 1회",
"format": "워크샵, 발표, 코드 리뷰 세션",
"topics": [
"새로운 규칙 소개",
"기존 규칙 심화 학습",
"실제 사례 분석",
"외부 모범 사례 공유"
]
},
"resources": {
"internalWiki": "규칙 문서 및 예제 통합 관리",
"discussionForum": "질문 및 토론 공간 제공",
"slackChannel": "#coding-standards 채널 운영"
}
},
"feedbackLoop": {
"methods": [
"정기적인 규칙 활용 설문조사",
"익명 피드백 채널",
"적용 어려움 보고 프로세스"
],
"incorporation": "수집된 피드백을 규칙 개선에 반영하는 프로세스"
},
"trainingByRole": {
"juniorDevelopers": {
"focus": "기본 규칙 이해 및 적용",
"materials": "가이드 문서, 체크리스트, 연습 예제"
},
"seniorDevelopers": {
"focus": "규칙 최적화 및 예외 상황 판단",
"materials": "심화 문서, 의사결정 가이드"
},
"teamLeads": {
"focus": "규칙 준수 모니터링, 규칙 발전 계획",
"materials": "평가 도구, 임팩트 분석 방법론"
}
}
},
"maintenance": {
"reviewCycle": {
"schedule": {
"comprehensive": "6개월마다 전체 규칙 검토",
"specific": "필요 시 특정 규칙 검토",
"emergency": "중대한 문제 발생 시 즉시 검토"
},
"process": [
"현재 규칙 효과성 평가",
"팀 피드백 수집 및 분석",
"업계 트렌드 및 모범 사례 조사",
"개선 사항 식별",
"변경 제안 작성 및 검토"
],
"participants": "기술 리더, 시니어 개발자, 품질 담당자 참여"
},
"versionControl": {
"naming": "규칙 버전은 {year}.{month}.{patch} 형식으로 관리",
"changelog": "모든 변경 사항 기록 유지",
"tagging": "주요 버전은 Git 태그로 관리",
"backwardsCompatibility": "이전 버전과의 호환성 명시"
},
"updateProcess": {
"proposal": {
"template": "변경 제안서 템플릿 사용",
"fields": [
"변경 내용",
"변경 이유",
"예상 영향",
"구현 계획",
"롤백 계획"
],
"review": "기술 위원회 또는 지정된 담당자 검토"
},
"implementation": {
"steps": [
"규칙 문서 업데이트",
"도구 구성 업데이트",
"샘플 코드 업데이트",
"자동화 검사 업데이트"
],
"verification": "변경 사항 검증 및 테스트"
},
"communication": {
"announcement": "팀에 변경 사항 공지",
"channels": [
"이메일",
"팀 미팅",
"Slack 채널",
"내부 Wiki"
],
"content": [
"변경 내용 요약",
"변경 이유",
"적용 기한",
"질문/지원 연락처"
]
},
"adoption": {
"gradual": "중요한 변경은 단계적 적용",
"support": "전환 기간 동안 추가 지원 제공",
"monitoring": "적용 현황 및 이슈 모니터링"
}
},
"exceptions": {
"criteria": [
"기술적 제약",
"비즈니스 요구사항 충돌",
"마이그레이션 중인 레거시 코드",
"특정 성능 요구사항"
],
"process": {
"request": "예외 요청 양식 작성",
"approval": "기술 리더 또는 아키텍트 승인",
"documentation": "승인된 예외 기록 유지",
"review": "정기적으로 예외 상황 재검토"
},
"annotation": "코드에 예외 사유 주석 처리"
},
"metrics": {
"compliance": {
"linterCoverage": "린터 규칙 준수율",
"codeReviewFindings": "코드 리뷰 시 규칙 위반 건수",
"automatedChecks": "CI 파이프라인 검사 통과율"
},
"effectiveness": {
"bugReduction": "규칙 도입 후 버그 감소율",
"maintainabilityIndex": "코드 유지보수성 지표 변화",
"developerEfficiency": "개발자 생산성 변화"
},
"reporting": {
"frequency": "월간 및 분기별 보고",
"visualization": "트렌드 및 비교 차트 제공",
"distribution": "팀 및 경영진에게 보고"
}
}
},
"adoption": {
"initialRollout": {
"phases": [
"준비: 규칙 완성 및 도구 구성",
"파일럿: 소규모 팀 적용 및 피드백",
"전체 도입: 단계적 확대 적용",
"정착: 규칙 준수 문화 형성"
],
"timeline": "각 단계별 명확한 일정 수립",
"responsibilities": "각 단계별 담당자 지정"
},
"enforcement": {
"automated": {
"linting": "lint-staged 및 CI 파이프라인 검사",
"preCommit": "git hook을 통한 제출 전 검사",
"pullRequests": "PR 시 자동 검사 및 피드백"
},
"manual": {
"codeReviews": "규칙 준수 관점의 코드 리뷰",
"peerLearning": "팀 내 지식 공유 및 멘토링",
"regularAudits": "정기적인 코드 품질 감사"
},
"gradual": {
"warnings": "초기에는 경고만 표시",
"blocking": "안정화 후 중요 규칙 위반은 빌드 차단",
"flexibility": "특정 상황에 대한 예외 허용"
}
},
"incentives": {
"recognition": "규칙 준수 및 개선에 기여한 팀원 인정",
"metrics": "팀 성과 평가에 코드 품질 지표 포함",
"showcasing": "모범 사례 코드 공유 및 시연"
}
}
}
}
\ No newline at end of file
{
"name": "Security Rules",
"description": "보안 취약점 방지 및 안전한 코드 작성을 위한 규칙",
"rules": {
"inputValidation": {
"validateAllInputs": true,
"validationApproach": "whitelist",
"techniques": [
"데이터 타입 검증",
"범위 및 길이 제한",
"형식 검증 (정규식)",
"스키마 기반 검증"
],
"frameworks": {
"typescript": ["zod", "yup", "class-validator"],
"javascript": ["joi", "yup", "ajv"],
"python": ["pydantic", "marshmallow", "cerberus"]
},
"examples": {
"api": "모든 API 요청 파라미터는 컨트롤러 진입 전 검증",
"forms": "모든 폼 입력은 클라이언트 및 서버 양쪽에서 검증"
}
},
"dataSanitization": {
"required": true,
"contexts": [
{
"context": "HTML 출력",
"technique": "HTML 이스케이프",
"libraries": ["DOMPurify", "sanitize-html"]
},
{
"context": "SQL 쿼리",
"technique": "매개변수화된 쿼리 사용",
"libraries": ["ORM, 매개변수화 쿼리 API 활용"]
},
{
"context": "Shell 명령",
"technique": "명령 인자 이스케이프",
"libraries": ["exec 보다 execFile 사용, 쉘 지양"]
},
{
"context": "JSON 직렬화",
"technique": "안전한 직렬화 라이브러리 사용",
"libraries": ["안전한 JSON 파서 옵션 활용"]
}
]
},
"authentication": {
"passwordPolicy": {
"minLength": 10,
"requireMixedCase": true,
"requireNumbers": true,
"requireSpecialChars": true,
"maxAge": "90days",
"historyCount": 5
},
"storage": {
"hashAlgorithm": "bcrypt, argon2, scrypt",
"saltRequirements": "랜덤 생성, 최소 16바이트",
"workFactor": "bcrypt의 경우 최소 10 이상, 서버 성능에 따라 조정"
},
"sessions": {
"type": "stateless JWT 또는 서버측 세션",
"expirations": {
"access": "15-60분",
"refresh": "7-30일"
},
"cookieSettings": {
"httpOnly": true,
"secure": true,
"sameSite": "strict",
"path": "/",
"domain": "애플리케이션 도메인"
}
},
"mfa": {
"recommended": true,
"preferredMethods": ["TOTP", "FIDO2/WebAuthn", "인증 앱"]
}
},
"authorization": {
"approach": ["RBAC", "ABAC", "정책 기반"],
"implementation": {
"granularity": "기능 및 리소스 수준 권한 정의",
"validation": "모든 접근 지점에서 권한 검증",
"defaultPolicy": "명시적 허용 전까지 모든 접근 거부"
},
"considerations": [
"객체 소유권 및 다중 테넌시 고려",
"권한 상속 및 계층 구조 정의",
"권한 부여 결정의 중앙화"
]
},
"sensitiveData": {
"classification": {
"levels": [
"공개 (Public)",
"내부용 (Internal)",
"기밀 (Confidential)",
"제한 (Restricted)"
],
"examples": {
"public": "제품 카탈로그, 공개 API 문서",
"internal": "내부 전화번호부, 조직도",
"confidential": "고객 데이터, 사업 계획",
"restricted": "인증 정보, API 키, 금융 데이터"
}
},
"encryption": {
"atRest": {
"algorithm": "AES-256, ChaCha20-Poly1305",
"keyManagement": "안전한 키 저장소 사용, KMS 활용"
},
"inTransit": {
"protocol": "TLS 1.3, 최소 TLS 1.2",
"certificates": "신뢰할 수 있는 CA, 적절한 키 길이"
}
},
"secrets": {
"storage": "환경 변수 또는 안전한 비밀 관리 도구 (Vault, AWS Secrets Manager)",
"codeRepositories": "비밀을 코드에 하드코딩하지 않음",
"localDevelopment": "개발 환경 비밀은 .env.local 등으로 관리하고 버전 관리에서 제외"
}
},
"secureHeaders": {
"required": [
"Content-Security-Policy",
"X-Content-Type-Options",
"X-Frame-Options",
"Strict-Transport-Security",
"Referrer-Policy"
],
"recommendations": {
"csp": "스크립트, 스타일, 이미지 등의 소스 명시적 제한",
"hsts": "max-age=31536000; includeSubDomains; preload",
"caching": "민감한 데이터에 Cache-Control: no-store 사용"
}
},
"apiSecurity": {
"authentication": {
"methods": ["JWT", "OAuth 2.0", "API 키"],
"considerations": [
"API 키는 헤더로 전송 (Authorization: Bearer 또는 X-API-Key)",
"API 키 정기 교체 메커니즘 구현",
"다양한 클라이언트 유형에 적합한 인증 방식 제공"
]
},
"rateLimit": {
"required": true,
"implementation": "IP, 사용자, API 키 기준 요청 제한",
"responseFormat": "429 Too Many Requests, Retry-After 헤더 포함"
},
"security": [
"CORS 정책을 가능한 엄격하게 구성",
"중요 작업에 멱등성 토큰 사용",
"API 버전 관리 및 사용 중단 정책 수립"
]
},
"securityTesting": {
"automated": [
{
"type": "SAST (정적 애플리케이션 보안 테스트)",
"tools": ["SonarQube", "Checkmarx", "ESLint 보안 플러그인"],
"frequency": "모든 PR 및 코드 커밋"
},
{
"type": "DAST (동적 애플리케이션 보안 테스트)",
"tools": ["OWASP ZAP", "Burp Suite"],
"frequency": "주요 릴리스 전, 정기적으로"
},
{
"type": "SCA (소프트웨어 구성 분석)",
"tools": ["Snyk", "OWASP Dependency-Check", "npm audit"],
"frequency": "주간, 의존성 업데이트 시"
}
],
"manual": [
"보안 코드 리뷰 체크리스트 활용",
"취약점 평가 및 침투 테스트 정기 수행",
"개발자 보안 교육 프로그램 운영"
]
},
"securityResponse": {
"reporting": {
"mechanism": "보안 취약점 보고 프로세스 및 담당자 지정",
"disclosure": "responsible disclosure 정책 문서화"
},
"incidentResponse": {
"plan": "인시던트 대응 계획 수립 및 문서화",
"roles": "보안 인시던트 대응 팀 및 역할 정의",
"steps": [
"식별 및 분류",
"격리 및 억제",
"근본 원인 분석",
"복구 및 해결",
"사후 분석 및 개선"
]
}
}
}
}
\ No newline at end of file
{
"name": "Testing Rules",
"description": "테스트 코드 작성 및 실행을 위한 규칙",
"rules": {
"coverage": {
"minimum": 80,
"excludePatterns": [
"**/*.test.ts",
"**/*.spec.ts",
"**/__tests__/**"
]
},
"naming": {
"testFiles": "*.test.ts",
"testPattern": "describe('Component', () => {})"
},
"structure": {
"arrange": true,
"act": true,
"assert": true
},
"mocking": {
"preferSpyOn": true,
"mockImplementation": true
},
"testTypes": {
"unit": {
"description": "개별 함수/클래스/컴포넌트를 독립적으로 테스트",
"scope": "단일 모듈 또는 함수",
"dependencies": "모두 목/스텁 처리",
"frameworks": ["Jest", "Vitest", "Mocha", "Pytest"],
"guidelines": [
"각 테스트는 하나의 동작 또는 결과만 검증",
"외부 의존성 모두 격리",
"테스트 간 독립성 유지 (상태 공유 없음)",
"빠른 실행 시간 유지"
],
"patterns": {
"sut": "테스트 대상 모듈 명확히 식별",
"factory": "테스트 데이터/객체 생성 함수 활용",
"minimal": "테스트에 필요한 최소한의 설정만 포함"
}
},
"integration": {
"description": "여러 모듈/서비스 간 상호작용 테스트",
"scope": "모듈 간 경계, API 엔드포인트, 데이터베이스 연동",
"dependencies": "일부는 실제 구현체 사용, 외부 서비스는 목 처리",
"frameworks": ["Supertest", "TestContainers", "Spring Boot Test"],
"guidelines": [
"핵심 통합 경로 위주로 테스트",
"실제 환경과 유사한 구성 사용",
"격리된 테스트 환경 구성",
"외부 의존성 최소화"
],
"patterns": {
"testDatabase": "인메모리 DB 또는 테스트 전용 DB 인스턴스 사용",
"apiTesting": "엔드포인트 응답 형식 및 상태 코드 검증",
"dataFlow": "시스템 경계 간 데이터 흐름 검증"
}
},
"e2e": {
"description": "사용자 관점에서 전체 시스템 흐름 테스트",
"scope": "전체 애플리케이션 흐름",
"dependencies": "가능한 실제 구현체 사용",
"frameworks": ["Cypress", "Playwright", "Selenium", "Puppeteer"],
"guidelines": [
"중요 사용자 시나리오 위주로 테스트",
"테스트 안정성을 위한 대기 전략 구현",
"독립적인 테스트 데이터 관리",
"병렬 실행 가능하도록 구성"
],
"patterns": {
"pageObjects": "화면 상호작용 로직 캡슐화",
"fixtures": "테스트 데이터 외부화",
"screenshots": "실패 시 스크린샷 캡처",
"video": "테스트 실행 녹화"
}
},
"performance": {
"description": "시스템 성능 특성 검증",
"scope": "응답 시간, 처리량, 자원 사용량",
"frameworks": ["JMeter", "K6", "Gatling", "Artillery"],
"guidelines": [
"명확한 성능 지표 및 기준 정의",
"대표적인 사용자 패턴 시뮬레이션",
"다양한 부하 시나리오 테스트",
"성능 저하 추세 모니터링"
],
"metrics": [
"응답 시간 (평균, 중앙값, 95/99 백분위)",
"초당 요청 처리량",
"오류율",
"시스템 자원 사용량(CPU, 메모리, I/O)"
]
},
"security": {
"description": "보안 취약점 검출",
"scope": "인증/인가, 입력 검증, 세션 관리",
"frameworks": ["OWASP ZAP", "SonarQube", "Snyk"],
"guidelines": [
"OWASP TOP 10 취약점 대응 검증",
"인증 및 권한 부여 로직 집중 테스트",
"입력 검증 우회 테스트",
"민감 정보 노출 확인"
],
"checkTypes": [
"인증 우회 테스트",
"권한 상승 테스트",
"SQL 인젝션 테스트",
"XSS 취약점 테스트",
"CSRF 방어 테스트"
]
}
},
"testData": {
"management": {
"fixtures": {
"location": "테스트 데이터는 별도 디렉토리(/__fixtures__/)에 보관",
"format": "JSON, YAML 또는 JavaScript/TypeScript 객체",
"naming": "목적을 명확히 표현하는 이름 사용"
},
"factories": {
"purpose": "테스트 객체 생성 로직 재사용",
"implementation": "Factory 함수 또는 Builder 패턴 사용",
"examples": [
"createUser({ ...customProps })",
"new UserBuilder().withName().withRole().build()"
]
},
"mocks": {
"purpose": "외부 의존성 시뮬레이션",
"frameworks": ["Jest Mock", "Sinon", "MockK", "pytest-mock"],
"guidelines": [
"최소한의 필요 동작만 목 처리",
"재사용 가능한 목 구성",
"목의 동작 명시적 정의"
]
}
},
"bestPractices": {
"isolation": "테스트 간 데이터 독립성 보장",
"deterministic": "시간, 랜덤 값 등 비결정적 요소 목 처리",
"realistic": "실제 데이터와 유사한 테스트 데이터 구성",
"maintenance": "중앙화된 테스트 데이터 관리로 유지보수성 향상"
},
"databaseTesting": {
"approach": [
"인메모리 데이터베이스 사용",
"테스트 전용 DB 인스턴스 사용",
"테스트 후 상태 롤백"
],
"tools": ["TestContainers", "H2", "SQLite", "MongoDB Memory Server"],
"dataSeeding": "테스트 실행 전 필요 데이터 시드 삽입",
"cleanup": "각 테스트 종료 후 데이터 정리"
}
},
"automationPipeline": {
"ci": {
"triggers": [
"모든 Pull Request",
"메인 브랜치 커밋",
"릴리스 태그 생성"
],
"stages": [
"린트 및 정적 분석",
"단위 테스트",
"통합 테스트",
"E2E 테스트(주요 시나리오)",
"보안 스캔"
],
"optimizations": [
"변경된 파일 관련 테스트만 실행",
"테스트 병렬 실행",
"테스트 결과 캐싱"
]
},
"reporting": {
"formats": ["JUnit XML", "HTML 리포트", "JSON"],
"metrics": [
"테스트 성공/실패 수",
"코드 커버리지",
"테스트 실행 시간"
],
"visualization": "테스트 결과 대시보드 구성",
"notification": "실패 시 알림 전송"
},
"environments": {
"dev": "개발자 로컬 환경, 빠른 피드백 루프",
"ci": "격리된 통합 환경, 재현 가능한 결과",
"staging": "프로덕션 유사 환경, 전체 테스트 스위트 실행"
},
"flakiness": {
"detection": "불안정한 테스트 식별 및 태그 지정",
"remediation": "비결정적 요소 제거, 명시적 대기 구현",
"retry": "불안정한 테스트는 실패 시 제한된 재시도 허용"
}
},
"advancedTechniques": {
"propertyBased": {
"description": "다양한 입력 조합에 대한 속성 검증",
"frameworks": ["fast-check", "jsverify", "hypothesis"],
"applications": [
"유효성 검사 로직",
"데이터 변환 함수",
"상태 머신 동작"
],
"guidelines": [
"검증할 속성 명확히 정의",
"경계값 중심 생성기 구성",
"실패 사례 최소화 및 저장"
],
"example": {
"js": "fc.property(fc.string(), s => reverse(reverse(s)) === s)"
}
},
"snapshot": {
"description": "출력 결과의 일관성 검증",
"applications": [
"UI 컴포넌트 렌더링 결과",
"API 응답 구조",
"복잡한 객체 직렬화 결과"
],
"frameworks": ["Jest Snapshots", "Enzyme", "react-test-renderer"],
"guidelines": [
"스냅샷은 코드 리뷰 과정에서 신중히 검토",
"불필요한 세부 정보는 직렬화에서 제외",
"날짜, ID 등 가변값은 정규화",
"의도적 변경 시 스냅샷 업데이트"
],
"maintenance": "정기적인 스냅샷 검토 및 정리"
},
"mutation": {
"description": "테스트 품질 검증을 위한 코드 변형",
"frameworks": ["Stryker", "Pitest"],
"process": [
"소스 코드 연산자/값 변형",
"변형된 코드로 테스트 실행",
"테스트 실패 여부 확인"
],
"metrics": "변형 점수(높을수록 테스트 품질 우수)",
"optimization": "비용 고려하여 CI에서 제한적 실행"
},
"fuzzing": {
"description": "무작위/비정상 입력으로 견고성 테스트",
"applications": [
"파서/직렬화 함수",
"사용자 입력 처리",
"파일 처리 로직"
],
"approach": [
"유효/무효 입력 경계 집중 탐색",
"이전 오류 케이스 재활용",
"코드 커버리지 기반 입력 생성"
]
}
}
}
}
\ No newline at end of file
# Cursor IDE 가이드
![Cursor IDE](https://assets.cursor.sh/img/hero.png)
Cursor IDE는 AI를 활용한 코딩 경험을 제공하는 차세대 코드 에디터입니다. 이 가이드는 Cursor IDE의 핵심 기능, 설정 방법, 사용 팁, 규칙 및 고급 기능을 소개합니다.
## 목차
- [주요 기능](#주요-기능)
- [설정 가이드](#설정-가이드)
- [사용 팁](#사용-팁)
- [규칙 가이드](#규칙-가이드)
- [고급 기능](#고급-기능)
- [Model Context Protocol (MCP)](#model-context-protocol-mcp)
## 주요 기능
Cursor IDE는 다음과 같은 핵심 기능을 제공합니다:
- **AI 기반 코드 완성**: 단순한 코드 스니펫이 아닌 고급 자동 완성 시스템
- **페어 프로그래밍**: AI가 개발자 옆에서 함께 코딩하는 듯한 경험 제공
- **지능적 다중 줄 수정**: 여러 줄에 걸친 코드 수정 및 리팩토링 가능
- **문맥 인식**: 최근 변경사항 기록, 린터 오류 고려, 현재 작업 목표 이해
- **차이 기반 UI**: 코드 변경사항을 차이 팝업으로 시각화
### GitHub Copilot과의 차이점
Cursor Tab은 GitHub Copilot과 달리 기존 코드를 수정하고, 함수를 리팩토링하며, 버그를 수정하는 능력이 있습니다. 또한 채팅 기능과 코드 분석 도구가 통합되어 있으며, 프로젝트 구조를 시각화할 수 있습니다.
## 설정 가이드
### 기본 설정
- **테마**: 다크/라이트 모드 선택
- **폰트**: 코드 폰트 및 크기 설정
- **줄 번호**: 줄 번호 표시 여부
- **자동 들여쓰기**: 자동 들여쓰기 활성화/비활성화
### AI 관련 설정
- **AI 모델**: GPT-4o, Claude 3 Opus, Claude 3 Sonnet 등 선택
- **제안 빈도**: AI 제안 표시 빈도 조절
- **컨텍스트 크기**: AI가 참조할 코드 컨텍스트 크기 설정
- **자동 완성**: 자동 완성 기능 활성화/비활성화
### 단축키 설정
- **Tab**: AI 제안 수락
- **Esc**: AI 제안 거부
- **Ctrl/⌘ + →**: 부분 수락
- **Cmd/Ctrl+L**: 채팅
- **Cmd/Ctrl+K**: 인라인 편집
## 사용 팁
### 생산성 향상
- Tab 완성, 채팅, 인라인 편집 등 AI 기능 적극 활용
- 자주 사용하는 단축키 익히기
- 개인 작업 스타일에 맞게 설정 조정
- 대규모 프로젝트에서 전체 코드베이스 컨텍스트 활용
### 문제 해결
- AI가 제안한 코드는 항상 검토
- AI가 더 정확한 제안을 할 수 있도록 충분한 컨텍스트 제공
- 문제 발생 시 관련 설정 확인 및 조정
- 특정 문제 해결에 적합한 AI 모델로 전환
## 규칙 가이드
Cursor에는 다양한 규칙 가이드가 있습니다:
1. **코드 스타일 규칙**: 자동 포맷팅, 들여쓰기, 줄 바꿈 규칙
2. **AI 제안 규칙**: 제안 우선순위, 필터링, 제한
3. **협업 규칙**: 버전 관리, 코드 리뷰, 문서화
4. **보안 규칙**: 코드 보안, AI 사용 제한, 접근 제어
5. **성능 규칙**: 리소스 사용, 캐시 관리, 최적화 규칙
## 고급 기능
### VSCode 연동
- VSCode의 확장 프로그램 사용 가능
- Cursor Settings > General > Account에서 설정
- 기존 VSCode 워크플로우 유지 가능
### 노트패드 기능 (베타)
- `Ctrl + i` (맥: `Cmd + i`)로 접근
- 노트 생성 및 관리, AI 프롬프트와 연동
- 컨텍스트 추적, 코드 스니펫 저장, 프로젝트 문서화
### 프로젝트 분석
- 코드 의존성 분석
- 아키텍처 시각화
- 성능 병목 지점 식별
- 보안 취약점 검사
### 프라이버시 설정
- Cursor Settings -> General -> Privacy mode
- 코드 외부 유출 방지
- 민감 코드 필터링, API 키 보호
## Model Context Protocol (MCP)
### MCP란?
Model Context Protocol(MCP)은 AI 모델이 외부 데이터 소스, 도구, 환경과 표준화된 방식으로 상호작용할 수 있도록 설계된 개방형 표준 프로토콜입니다. AI 애플리케이션을 위한 USB-C 포트와 같은 역할을 합니다.
### MCP 아키텍처
- **MCP 서버**: 특정 데이터 소스나 서비스에 연결
- **MCP 클라이언트**: AI 애플리케이션 내에서 실행
- **MCP 호스트**: Cursor IDE와 같은 AI 기반 앱
- **데이터 소스 및 서비스**: 로컬 파일, 원격 API, 클라우드 서비스 등
### MCP 활용 예시
- **데이터베이스 접근**: PostgreSQL, MySQL, MongoDB 등 연동
- **코드 저장소 연동**: Git, GitHub, GitLab 서버 통합
- **웹 검색 및 브라우징**: 구글, 빙, Brave Search 등 검색 엔진 통합
- **생산성 도구 연동**: Slack, Discord, Notion 등 통합
- **로컬 시스템 도구**: 파일 시스템 접근, 터미널 명령 실행
## 라이선스 및 가격 정책
### 무료 사용자
- AI 기능 사용 제한 (일일/월별 할당량)
- 기본 모델만 사용 가능
- 프로젝트 크기 제한
### Pro 플랜
- 무제한 AI 기능 사용
- 모든 고급 AI 모델 사용 가능 (GPT-4o, Claude 3 Opus 등)
- 우선 고객 지원
### 비즈니스 플랜
- Pro 플랜의 모든 기능 포함
- 팀 관리 기능
- 엔터프라이즈급 보안 및 규정 준수
- 전용 지원
---
이 가이드는 Cursor IDE의 기본적인 사용법과 기능을 소개합니다. 더 자세한 정보는 [공식 문서](https://cursor.sh/docs)를 참조하세요.
\ No newline at end of file
# Cursor IDE 가이드
## 1. Cursor Tab 기능
### 1.1 핵심 특징
- **AI 기반 코드 완성**: 단순한 코드 스니펫이 아닌 고급 자동 완성 시스템
- **페어 프로그래밍**: AI가 개발자 옆에서 함께 코딩하는 듯한 경험 제공
- **지능적 다중 줄 수정**: 여러 줄에 걸친 코드 수정 및 리팩토링 가능
- **문맥 인식**:
- 최근 변경사항 기록
- 린터 오류 고려
- 현재 작업 목표 이해
- **차이 기반 UI**:
- 코드 변경사항을 차이 팝업으로 시각화
- 추가/삭제/변경 사항 명확히 표시
### 1.2 GitHub Copilot과의 주요 차이점
- **코드 편집 능력**:
- Copilot: 주로 현재 커서 위치에 코드 삽입
- Cursor Tab: 기존 코드 수정, 함수 리팩토링, 버그 수정 등 가능
- **통합 기능**:
- 채팅 기능 내장
- 코드 분석 도구 통합
- 프로젝트 구조 시각화
### 1.3 주요 기능
#### 기본 기능
- **탭 완성**:
- `Tab` 키로 제안 수락
- 약 1초 대기 후 AI 제안
- 패턴 기반 자동 완성
- **부분 수락**: `Ctrl/⌘ + →`로 단어별 수락
- **제안 거부**: `Esc` 키로 제안 거부
#### 고급 기능
1. **피크 뷰 통합**
- 정의로 이동
- 타입 정의 확인
- 매개변수 추가/수정
2. **커서 예측**
- 다음 논리적 편집 위치 예측
- 연속적인 탭 입력으로 관련 편집 연결
3. **다중 줄 편집**
- 여러 줄 동시 수정
- 코드 블록 완성
- 인터페이스 구현
4. **AI 채팅 통합**
- `Ctrl + L`: 채팅 패널 열기
- 코드 컨텍스트 기반 대화
- 전체 코드베이스 분석
5. **인라인 편집**
- `Ctrl + K`: 코드 편집 및 작성
- 미니 팝업으로 코드 생성/수정
- `Ctrl + Shift + Y`: 수락
- `Ctrl + N`: 거부
- `Alt + Enter`: 코드 관련 질문
### 1.4 사용 팁
- **신뢰와 검증**: AI 제안은 항상 검토 필요
- **단축키 활용**: 기본 단축키 숙지
- **컨텍스트 활용**: AI가 더 정확한 제안을 할 수 있도록 충분한 컨텍스트 제공
- **자동 가져오기**: 의존성 자동 추가
- **프라이버시 고려**: 민감한 코드는 프라이버시 모드 사용
### 1.5 가격 정책
- **무료 사용자**:
- AI 기능 사용 제한 (일일/월별 할당량)
- 기본 모델만 사용 가능
- 프로젝트 크기 제한
- **Pro 플랜**:
- 무제한 AI 기능 사용
- 모든 고급 AI 모델 사용 가능 (GPT-4o, Claude 3 Opus 등)
- 우선 고객 지원
- **비즈니스 플랜**:
- Pro 플랜의 모든 기능 포함
- 팀 관리 기능
- 엔터프라이즈급 보안 및 규정 준수
- 전용 지원
## 2. Cursor 설정 가이드
### 2.1 기본 설정
- **테마**: 다크/라이트 모드 선택
- **폰트**: 코드 폰트 및 크기 설정
- **줄 번호**: 줄 번호 표시 여부
- **자동 들여쓰기**: 자동 들여쓰기 활성화/비활성화
### 2.2 AI 관련 설정
- **AI 모델**:
- 사용할 AI 모델 선택 (GPT-4o, Claude 3 Opus, Claude 3 Sonnet 등)
- 모델별 특성 및 성능 차이 고려
- **제안 빈도**: AI 제안 표시 빈도 조절
- **컨텍스트 크기**: AI가 참조할 코드 컨텍스트 크기 설정
- **자동 완성**: 자동 완성 기능 활성화/비활성화
### 2.3 편집기 설정
- **탭 크기**: 탭 문자 크기 설정
- **공백**: 탭을 공백으로 변환 여부
- **자동 저장**: 자동 저장 간격 설정
- **미니맵**: 미니맵 표시 여부
### 2.4 단축키 설정
- **기본 단축키**:
- `Tab`: AI 제안 수락
- `Esc`: AI 제안 거부
- `Ctrl/⌘ + →`: 부분 수락
- `Cmd/Ctrl+L`: 채팅
- `Cmd/Ctrl+K`: 인라인 편집
- **커스텀 단축키**: 사용자 정의 단축키 설정
### 2.5 확장 프로그램
- **기본 확장**: 기본 제공되는 확장 프로그램
- **추가 확장**: 사용자 정의 확장 프로그램 설치
- **확장 관리**: 확장 프로그램 활성화/비활성화
## 3. Cursor 사용 팁
### 3.1 생산성 향상
- **AI 기능 활용**: Tab 완성, 채팅, 인라인 편집 등 AI 기능 적극 활용
- **단축키 숙지**: 자주 사용하는 단축키 익히기
- **커스텀 설정**: 개인 작업 스타일에 맞게 설정 조정
- **롱 컨텍스트 활용**: 대규모 프로젝트에서 전체 코드베이스 컨텍스트 활용
### 3.2 문제 해결
- **AI 제안 검토**: AI가 제안한 코드는 항상 검토
- **컨텍스트 활용**: AI가 더 정확한 제안을 할 수 있도록 충분한 컨텍스트 제공
- **설정 조정**: 문제 발생 시 관련 설정 확인 및 조정
- **모델 변경**: 특정 문제 해결에 적합한 AI 모델로 전환
### 3.3 최적화
- **리소스 관리**: 불필요한 확장 프로그램 비활성화
- **캐시 정리**: 주기적인 캐시 정리
- **업데이트**: 최신 버전 유지
- **하드웨어 요구사항 확인**: 충분한 메모리와 처리 능력 확보
## 4. Cursor 규칙 가이드
### 4.1 코드 스타일 규칙
- **자동 포맷팅**:
- 저장 시 자동 포맷팅 적용
- 언어별 기본 포맷팅 규칙 준수
- 커스텀 포맷팅 규칙 설정 가능
- **들여쓰기 규칙**:
- 탭 또는 스페이스 사용 설정
- 들여쓰기 크기 설정
- 자동 들여쓰기 정렬
- **줄 바꿈 규칙**:
- 최대 줄 길이 설정
- 자동 줄 바꿈
- 줄 끝 공백 처리
### 4.2 AI 제안 규칙
- **제안 우선순위**:
- 문맥 기반 제안 순위
- 사용자 선호도 반영
- 최근 사용 패턴 학습
- **제안 필터링**:
- 언어별 제안 필터
- 프로젝트 컨텍스트 기반 필터
- 보안 관련 제안 필터
- **제안 제한**:
- 무료 사용자 제안 할당량
- 프로 사용자 무제한 제안
- 제안 빈도 조절
### 4.3 협업 규칙
- **버전 관리**:
- Git 통합 규칙
- 커밋 메시지 형식
- 브랜치 관리 정책
- **코드 리뷰**:
- AI 기반 코드 리뷰 규칙
- 리뷰 코멘트 형식
- 승인 프로세스
- **문서화**:
- 주석 작성 규칙
- API 문서화 표준
- README 작성 가이드
### 4.4 보안 규칙
- **코드 보안**:
- 민감 정보 처리
- API 키 관리
- 환경 변수 사용
- **AI 사용 제한**:
- 민감 코드 AI 처리 제한
- 보안 관련 코드 AI 제안 제한
- 데이터 프라이버시 보호
- **접근 제어**:
- 사용자 권한 관리
- 프로젝트 접근 제한
- 기능 사용 제한
### 4.5 성능 규칙
- **리소스 사용**:
- 메모리 사용 제한
- CPU 사용량 관리
- 디스크 공간 관리
- **캐시 관리**:
- 캐시 크기 제한
- 캐시 정리 주기
- 캐시 우선순위
- **최적화 규칙**:
- 코드 최적화 가이드라인
- 빌드 최적화
- 실행 성능 모니터링
## 5. Cursor 고급 기능
### 5.1 VSCode 연동
- **확장 프로그램 호환성**: VSCode의 확장 프로그램 사용 가능
- **설정 방법**:
- Cursor Settings > General > Account에서 설정
- `Ctrl + Shift + J`로 설정 메뉴 접근
- **장점**:
- 기존 VSCode 워크플로우 유지
- 익숙한 확장 프로그램 사용
- 설정 동기화 가능
### 5.2 노트패드 기능 (베타)
- **접근 방법**: `Ctrl + i` (맥: `Cmd + i`)
- **기능**:
- 노트 생성 및 관리
- AI 프롬프트와 연동
- 컨텍스트 추적
- 코드 스니펫 저장
- 프로젝트 문서화
### 5.3 프로젝트 분석
- **빠른 분석 방법**:
1. `Ctrl + L`로 채팅 패널 열기
2. "Normal chat"에서 "Long Context Chat"으로 변경
3. "@codebase를 파악해서 내 코드의 관계와 역할을 머메이드로 시각화해줘" 입력
4. 생성된 코드를 노션이나 README.MD에 활용
- **추가 기능**:
- 코드 의존성 분석
- 아키텍처 시각화
- 성능 병목 지점 식별
- 보안 취약점 검사
### 5.4 프라이버시 설정
- **프라이버시 모드**:
- Cursor Settings -> General -> Privacy mode
- 코드 외부 유출 방지
- AI 답변 품질과의 트레이드오프 고려
- **보안 기능**:
- 민감 코드 필터링
- API 키 보호
- 환경 변수 관리
- 접근 제어 설정
### 5.5 성능 최적화
- **리소스 관리**:
- 불필요한 확장 프로그램 비활성화
- 캐시 크기 조정
- 메모리 사용량 모니터링
- **작업 효율화**:
- 자주 사용하는 명령어 단축키 설정
- 작업 공간 레이아웃 저장
- 자동 백업 설정
- **통합 도구**:
- Git 통합
- 디버깅 도구
- 테스트 프레임워크 지원
## 6. Model Context Protocol (MCP)
### 6.1 MCP란 무엇인가?
- **정의**: Model Context Protocol(MCP)은 AI 모델(예: Cursor의 AI)이 외부 데이터 소스, 도구, 환경과 표준화된 방식으로 상호작용할 수 있도록 설계된 개방형 표준 프로토콜입니다.
- **비유**: AI 애플리케이션을 위한 USB-C 포트와 같습니다. 다양한 기기를 연결하는 USB-C처럼, MCP는 AI 모델을 다양한 데이터 소스 및 도구에 연결하는 표준 방법을 제공합니다.
- **해결하는 문제**: 이전에는 AI를 데이터베이스, 파일 시스템, API 등과 연결하려면 각기 다른 맞춤형 통합 코드와 프롬프트가 필요했습니다. MCP는 이러한 파편화를 해결하고 표준화된 인터페이스를 제공하여 개발 및 유지보수를 용이하게 합니다.
### 6.2 MCP의 중요성
- **표준화**: 개별 통합 대신 공통 인터페이스를 사용하여 개발 시간 단축 및 유지보수 부담 감소.
- **생태계 성장**: 개방형 표준이므로 커뮤니티에서 다양한 MCP 서버(커넥터)를 개발 및 공유.
- **AI 잠재력 발휘**: AI가 격리된 상태에서 벗어나 실제 데이터와 도구를 활용하여 더 관련성 높은 답변을 제공하고 작업을 수행할 수 있게 함.
### 6.3 MCP 아키텍처
- **MCP 서버**: 특정 데이터 소스나 서비스(파일 시스템, 데이터베이스, Slack 등)에 연결되어 MCP 표준에 따라 데이터나 기능을 노출하는 프로그램. 특정 종류의 데이터를 가져오거나 조작하는 어댑터 역할.
- **MCP 클라이언트**: AI 애플리케이션 내에서 실행되며 MCP 서버와의 연결을 관리. 일반적으로 사용자가 직접 상호작용하지 않음.
- **MCP 호스트 (AI 애플리케이션)**: 외부 데이터나 도구를 사용하려는 AI 기반 앱 (예: Cursor IDE, Claude Desktop).
- **데이터 소스 및 서비스**: 정보나 기능이 실제로 존재하는 곳 (로컬 파일, 원격 API, 클라우드 서비스 등).
### 6.4 MCP 핵심 개념
- **리소스 (Resources)**: 서버가 AI에게 제공할 수 있는 데이터 또는 콘텐츠. (예: `file://README.md` 리소스를 요청하여 파일 내용 가져오기)
- **도구 (Tools)**: AI가 서버를 통해 호출할 수 있는 작업. (예: 데이터베이스 쿼리 실행, 메시지 전송 등)
- **프롬프트 (Prompts)**: 서버가 제공할 수 있는 재사용 가능한 프롬프트 템플릿 또는 워크플로우.
- **샘플링 (Sampling)**: 서버가 AI에게 텍스트 완성 또는 변환을 요청할 수 있는 고급 기능.
### 6.5 통신 방식
- **보안**: 민감한 데이터 접근 및 강력한 작업 수행 가능성을 고려하여 보안 제어 강조.
- **전송 방식**:
- **STDIO**: 서버가 로컬 프로세스로 실행되고 표준 입출력을 통해 통신. 로컬 개발에 적합.
- **SSE (HTTP)**: 서버가 웹 서비스로 실행되고 HTTP 엔드포인트를 통해 통신. 원격 서버 연결 등 유연성이 높음.
### 6.6 Cursor에서의 MCP 설정
- **설정 위치**: Cursor Settings > MCP
- **서버 추가**:
1. `Settings > MCP > Add Server` 클릭
2. 서버 구성 정보 입력
```json
{
"mcpServers": {
"serverName": {
"command": "실행_명령어",
"args": ["인자1", "인자2", "..."]
}
}
}
```
- **임시 실행**: 필요한 서버를 명령줄에서 일회성으로 실행 가능
- **주의**: 여러 MCP 서버 인스턴스가 충돌할 수 있으므로, 한 번에 하나의 인스턴스만 활성화하는 것이 중요합니다.
### 6.7 MCP 활용 예시
- **데이터베이스 접근**:
- PostgreSQL, MySQL, MongoDB, SQLite 등 다양한 데이터베이스 연동
- 데이터 쿼리, 스키마 분석, 쿼리 최적화 지원
- **코드 저장소 연동**:
- Git, GitHub, GitLab 서버 통합
- 코드 검색, PR 분석, 코드 통계 생성
- **웹 검색 및 브라우징**:
- 구글, 빙, Brave Search 등 검색 엔진 통합
- 웹 페이지 내용 분석 및 요약
- **생산성 도구 연동**:
- Slack, Discord, Notion, Jira, Linear 등 통합
- 데이터 검색, 업데이트, 생성 기능
- **로컬 시스템 도구**:
- 파일 시스템 접근
- 터미널 명령 실행
- 그래픽 도구 연동 (3D, 이미지 편집 등)
### 6.8 MCP 통합 팁
- **기존 서버 활용**: GitHub의 MCP 커뮤니티 저장소 확인
- **맞춤 서버 구축**: Python, TypeScript, Rust 등의 SDK 활용
- **호스팅 옵션**: 로컬, 개인 서버, 클라우드 배포 지원
- **MCP 지원 클라이언트**: Cursor IDE, Claude Desktop, Anthropic 제품군 등
- **보안 고려사항**:
- 최소 권한 원칙 적용
- 민감 정보 보호 계층 구현
- 액세스 제어 및 인증 메커니즘 활용
### 6.9 최신 MCP 동향
- **오픈소스 커뮤니티**: 활발한 MCP 서버 및 도구 개발
- **기업 채택**: 더 많은 기업이 자체 도구에 MCP 지원 추가
- **표준화 노력**: 프로토콜 사양 개선 및 표준화 진행
- **확장 생태계**: 점점 더 다양한 AI 도구 및 모델과의 호환성 증가
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment