Skip to content

TEAM-CLUSTAR/CLUSTAR-CLIENT

Repository files navigation

logo

흩어진 메모를 빛나는 결과물로


표지 클러스타 소개뷰1 소개뷰2 소개뷰3 소개뷰4 소개

CLUSTAR FE Developers


조혜린

백지연

최윤하

임서준

기술 Stack

카테고리 기술 스택
UI Library React
Server State Management TanStack Query
Language TypeScript
Build Tool Vite
Styling Vanilla Extract
Version Control Git GitHub
Cooperation Notion Discord Figma Swagger
Formatting ESLint Prettier Lefthook
Design System Storybook
Repository Management Monorepo
Build System Turborepo
Package Manager Pnpm
Test Code Vitest
Error Monitoring Sentry
CI/CD Vercel GitHub Actions

Git 컨벤션

♟️ GITHUB 전략

브랜치 전략: git flow 기반 + develop 운영

GitHub Flow: 브랜치/규칙이 단순해서 온보딩이 빠르고, 기능 단위로 PR을 올리는 흐름 명확

브랜치 역할

  • main: 배포 가능 브랜치
  • develop: 기능 브랜치들이 모이는 통합 브랜치

🌳 브랜치 컨벤션

기능명 규칙: 케밥 케이스(kebab-case)

  • init/feature-name/#issue-number: 초기 세팅, 환경 구성, 템플릿/룰 셋업 등
  • feat/feature-name/#issue-number: 신규 기능 개발
  • fix/feature-name/#issue-number: 버그 수정
  • refactor/feature-name/#issue-number: 리팩터링(동작 변경 최소화, 구조 개선 중심)
  • Docs/feature-name/#issue-number: 문서 작업 (README, 주석, 가이드, 문서 구조 정리 등)
  • Perf/feature-name/#issue-number: 성능 개선 (렌더링 최적화, 불필요한 연산 제거, 메모리/속도 개선 등)

➡️ merge가 끝난 브랜치는 반드시 삭제 (squash merge)


📝 PR 컨벤션

PR 단위: 하나의 PR에는 최대한 하나의 기능만 포함

PR 제목: PR 제목은 Type(모노레포 영역) 로 시작하고, Type은 앞 글자 대문자로 통일

  • Feat(client): 로그인 기능 추가
  • Feat(cds): Button 컴포넌트 구현
  • Init(client): router 설정
  • Init(project): PR/Issue 템플릿 세팅
  • Fix(client): 메모 저장 시 중복 호출 수정
  • Refactor(client): API 에러 처리 구조 개선

🖊️ 커밋 컨벤션
  • init: 커밋 메시지
  • feat: 커밋 메시지
  • fix: 커밋 메시지
  • chore: 커밋 메시지
  • refactor: 커밋 메시지
  • docs: 커밋 메시지
  • perf: 커밋 메시지
  • test: 커밋 메시지

📡 Issue 컨벤션

Issue 제목은 작업 성격을 바로 알 수 있도록 prefix 추가

  • [Init] 프로젝트 초기 세팅
  • [Feat] Tab 컴포넌트 구현
  • [Fix] 색상 수정
  • [Refactor] API 모듈 구조 개선

💌 코드리뷰 규칙

merge 조건

  • PR은 최소 2명 이상의 Approve가 있어야 merge 가능
  • 직접 push로 합치는 방식은 지양,, 반드시 PR을 통해 merge

리뷰 타임

  • PR이 올라오면 가능한 빨리 리뷰
  • 몰아서 한 번에가 아니라, 올라오는 즉시 분산 리뷰가 원칙

리뷰 기준

  • 리뷰 코멘트는 최대한 둥글게 작성
  • 근거있는 주장
  • 가능한 경우 레퍼런스(문서/가이드/팀 규칙)를 함께 첨부

리뷰에서 중요하게 보는 포인트 예시

  • 아키텍처/폴더 구조 일관성
  • 예외 처리/에러 핸들링
  • 성능에 영향 줄 수 있는 부분(불필요 렌더링, 무거운 연산 등)
  • 타입 안정성(TypeScript), API 계약 준수
  • 접근성/UX 고려(로딩/에러 상태 등)
  • 네이밍/가독성(우리 팀이 중요하게 보는 기준)


Code 컨벤션

🧩 컴포넌트

네이밍

  • 리액트 컴포넌트만 PascalCase를 사용
    • ex: Header, MemoCard, AiSummaryPanel)
  • 그 외 유틸/함수/변수는 camelCase

export 규칙

  • 컴포넌트는 기본적으로 default export를 사용
  • 모듈 집합(index.ts)에서는 named export로 re-export

JSX 작성 규칙

  • 의미 없는 div 남발을 지양하고, 가능한 시맨틱 태그를 사용
    • 예: section, header, main, nav, article, aside, footer
  • 최상단 래퍼가 의미가 없다면 Fragment(<>...</>)를 사용
  • children이 불필요한 컴포넌트는 Self closing
    • 예: <EmptyState />

이벤트 핸들러 규칙

  • 이벤트 핸들러 함수는 반드시 handle prefix를 사용
    • 예: handleSubmit, handleResetClick

📂 폴더명

규칙

  • 폴더명은 kebab-case + 소문자 시작
    • 예: user-profile, memo-list, error-boundary
  • 가능한 경우 복수형(s) 사용
    • 예: models, libs, styles, configs

⛓️ 타입

네이밍 규칙

  • 타입/인터페이스 이름은 PascalCase를 사용
  • 기본적으로 type보다 interface를 우선 사용

Props 네이밍

  • Props 타입은 반드시 Props 접미사
    • 예: CardProps, HeaderProps

type을 사용하는 경우

  • 유니언 타입, 튜플, 리터럴 타입이 꼭 필요한 경우
    • 예: type ButtonVariant = 'primary' | 'secondary'

타입 파일 구성

  • 컴포넌트와 관련된 타입은 가능한 같은 폴더 내부에 co-locate
    • 규모가 커지면 types.ts로 분리

🌎 함수

함수 네이밍(동사 + 명사)

  • 함수는 무엇을 하는지가 이름만으로 드러나야 한다
  • 의미별 prefix를 통일
    • get: 값을 가져와 반환(조회)
    • create: 새 값을 생성
    • check: 조건을 검사
    • convert: 형태를 변환
    • add / minus: 더하거나 빼기
    • filter: 필터링 결과를 반환
  • boolean 반환 유틸은 is으로 시작
    • 예: isEmailValid, isSubmit

함수 선언 방식

  • 화살표 함수(arrow function)를 우선 사용해요.
    • 컴포넌트 내부/유틸 함수 스타일을 통일하기 위함이에요.

key 사용 규칙

  • key에 랜덤 값을 넣지 않는다
  • 리스트가 동적이면 반드시 고유 id를 key로 사용
  • 정적 리스트(순서/개수 변화 없음)에서는 index 허용

🪢 메소드

배열/객체 처리

  • 배열 복사는 스프레드 연산자 사용
    • 예: const copy = [...original]
  • 반복은 가능하면 map, forEach, filter, reduce를 사용
    • 단순 루프라도 “결과물이 무엇인지” 드러나는 메소드 우선

구조 분해 할당

  • props/객체는 가능한 구조 분해로 받아서 사용

🎨 스타일

네이밍 규칙

  • 특정 요소를 감싸는 래퍼가 필요하다면 container로 통일
    • 예: pageContainer, buttonContainer
  • 스타일 이름은 반드시 의미를 드러내기
    • 예: titleSection, emptyStateContainer, textContainer

CSS 속성 작성 순서

  • 가능한 범위에서 바깥 → 안쪽 흐름으로 작성
    • display → position → size → spacing → border/background → typography → etc

📓 스토리북

작성 목적

  • Storybook은 보여주기뿐 아니라 컴포넌트 사용법 문서화가 목적
  • Story에 Props 설명(특히 interface 기반)을 포함

규칙

  • title은 폴더 구조를 반영
    • 예: Common/Box, Components/Button
  • componentSubtitle로 컴포넌트 한 줄 설명
  • docs.description.component에 다음 내용 포함
    • 컴포넌트 역할
    • 핵심 Props 설명
    • 동작 조건(예: 특정 prop일 때 버튼 노출 등)
  • 대표 케이스를 Story로 분리
    • Default, WithButtonLabel, Disabled, ErrorState 등

🧪 테스트 코드

테스트 목표

  • 테스트는 깨지면 치명적인 흐름을 보호하는 게 목적

우선순위

  • 유틸 함수 / 변환 로직
    • 입력 → 출력이 명확해서 테스트 효율이 높다
  • 비즈니스 핵심 플로우
    • 예: 메모 생성/저장/요약 결과 저장 같은 핵심 기능
  • 컴포넌트 테스트
    • 상호작용이 중요한 UI (버튼 클릭, 폼 제출, 조건부 렌더링)

규칙

  • 테스트 파일은 보통 *.test.ts(x)
    • 예: it('submits form when valid', ...)

⭐️ 그라운드 룰

모르는 건 꼭 물어보기

  • 고민하지 말고 바로 물어보기
  • 질문은 능력 부족이 아니라, 성장 의지
  • 디스코드/노션/카톡 어떤 채널이든 편하게 질문하기

지식 공유하기

  • 공유 예시
    • 이 에러 이렇게 해결했어요 → 노션 정리
    • 이 구조가 더 좋더라 → 회의 때 공유
    • 이 글 도움 됐어요 → 링크 공유

문서화를 잘 하기

  • 구조를 바꿨다면 → 왜 바꿨는지 기록
  • 규칙을 정했다면 → README/노션에 남기기
  • 트러블슈팅을 했다면 → 해결 과정 정리

우리 팀의 핵심 가치

  • 질문하는 용기
  • 공유하는 문화
  • 문서화하는 습관
  • 코딩 이후까지 책임지는 태도
  • 리뷰를 존중하는 자세
  • 도전을 두려워하지 않는 마음


폴더 구조

└── src/
    ├── app/
    │   ├── main.tsx
    │   └── App.tsx
    ├── pages/
    │   ├── home/               // 페이지 단위 도메인 폴더
    │   │   ├── apis/           // 도메인 관련 API
    │   │   ├── components/     // 도메인 관련 컴포넌트
    │   │   ├── utils/          // 도메인 관련 유틸 함수
    │   │   ├── hooks/          // 도메인 관련 훅
    │   │   └── home-page.tsx  // 도메인 UI
    │   ├── ai-results/
    │   ├── login/
    │   ├── memo/
    │   ├── landing/
    │   └── ...
    ├── router/                  // 라우팅 설정
    │   ├── path.ts
    │   ├── lazy.ts
    │   ├── router.ts
    │   └── ...
    └── shared/                  // 공통으로 사용되는 것들을 모아놓은 폴더
        ├── api/                 // 공통 API 설정
        │   ├── interceptor/     // Axios 인터셉터
        │   ├── instance.ts
        │   └── status.ts
        ├── components/         // 공통 컴포넌트
        │   ├── header/
        │   ├── sidebar/
        │   └── ...
        ├── configs/            // 앱 전역 설정
        ├── constants/          // 공통 상수
        ├── hooks/              // 공통 커스텀 훅
        ├── utils/              // 공통 유틸 함수
        ├── libs/               // 공통 라이브러리 래퍼/설정(외부 라이브러리 초기화 등)
        └── types/             // 공통 타입 정의

└── packages/                  // 모노레포 워크스페이스: 앱과 공통 패키지를 분리해 재사용/버전관리
    ├── cds-ui/                // Clustar 디자인 시스템
    │   └── src/
    |       ├── components
    |       ├── styles
    |       ├── token
    │       └── ...
    ├── cds-icons/             // 아이콘 패키지(React 컴포넌트화된 SVG 등)
    ├── eslint-config/         // 공통 ESLint 설정 패키지
    └── typescript-config/     // 공통 TS config 패키지
└── pnpm-workspace.yaml        // 카탈로그 설정 파일

keunnnnnlobstar


조혜린

백지연

최윤하

임서준

About

⭐️ 흩어진 메모를 빛나는 결과물로, CLUSTAR

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages