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

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 고려(로딩/에러 상태 등)
  • 네이밍/가독성(우리 팀이 중요하게 보는 기준)

코딩 컨벤션

🧩 컴포넌트

네이밍

  • 리액트 컴포넌트만 PascalCase를 사용해요.

    • 예: Header, MemoCard, AiSummaryPanel
  • 그 외 유틸/함수/변수는 camelCase를 사용해요.


export 규칙

  • 컴포넌트는 기본적으로 default export를 사용해요.

  • import 경로가 단순해지고, “이 파일의 대표 컴포넌트”가 명확해져요.

  • 단, 모듈 집합(index.ts)에서는 named export로 re-export해요.

  • 팀에서 import 스타일을 통일하기 위함이에요.

JSX 작성 규칙

  • 의미 없는 div 남발을 지양하고, 가능한 시맨틱 태그를 사용해요.

    • 예: section, header, main, nav, article, aside, footer
  • 최상단 래퍼가 의미가 없다면 Fragment(<>...</>)를 사용해요.

  • children이 불필요한 컴포넌트는 Self closing을 사용해요.

    • 예: <EmptyState />

이벤트 핸들러 규칙

  • 이벤트 핸들러 함수는 반드시 handle prefix를 사용해요.

    • 예: handleSubmit, handleResetClick
  • 이벤트 핸들러가 아닌 일반 함수에는 handle을 사용하지 않아요.

    • “이 함수는 이벤트 핸들러다”라는 의미를 유지하기 위함이에요.
📂 폴더명

규칙

  • 폴더명은 kebab-case + 소문자 시작을 사용해요.

    • 예: user-profile, memo-list, error-boundary
  • 가능한 경우 복수형(s)을 사용해요. - 예: models, libs, styles, configs

⛓️ 타입

네이밍 규칙

  • 타입/인터페이스 이름은 PascalCase를 사용해요.

  • 기본적으로 type보다 interface를 우선 사용해요.

    • 객체 형태 확장(merge/extends)과 협업 시 확장성 때문에 더 유리해요.

Props 네이밍

  • Props 타입은 반드시 Props 접미사를 붙여요.
    • 예: CardProps, HeaderProps

type을 사용하는 경우

  • 다음 상황에서는 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', ...)
💪 export 규칙 (named rule)

원칙

  • 컴포넌트 파일은 default export를 기본으로 해요.

    • 예: ui/button.tsx → export default Button
  • 외부로 공개하는 진입점은 index.ts에서 named export로 통일해요.

    • import가 예측 가능해지고, 모듈 경계를 명확히 할 수 있어요.
⭐️ 그라운드 룰

모르는 건 꼭 물어보기

모르는 걸 숨기는 것보다, 물어보는 게 훨씬 더 팀에 도움이 돼요.

  • 고민하지 말고 바로 물어봐요.

  • 질문은 능력 부족이 아니라, 성장 의지예요.

  • 디스코드/노션/카톡 어떤 채널이든 편하게 질문해요.

  • 이미 아는 사람은 최대한 친절하게 설명해줘요.

지식 공유하기

  • 공유 예시
    • “이 에러 이렇게 해결했어요” → 노션 정리

    • “이 구조가 더 좋더라” → 회의 때 공유

    • “이 글 도움 됐어요” → 링크 공유

문서화를 잘 하기

  • 구조를 바꿨다면 → 왜 바꿨는지 기록

  • 규칙을 정했다면 → README/노션에 남기기

  • 트러블슈팅을 했다면 → 해결 과정 정리


  • 우리가 문서화하는 이유
    • 나중에 “이거 왜 이렇게 했지?” 안 해도 돼요.

    • 새로운 팀원이 들어와도 빠르게 적응할 수 있어요.

    • 리뷰어가 맥락을 이해해서 코드리뷰가 쉬워져요.

챌린징을 두려워하지 말기

우리는 ‘안전한 선택’보다 ‘성장하는 선택’을 더 가치 있게 봐요.

  • 새로운 기술 도입

  • 구조 개선

  • 성능 최적화

  • 리팩터링 제안

물론 근거 없는 주장이나 아무런 근거 없이 기술을 도입하려고 하면 안돼요. 대신 대신 이렇게 하면 이런 장점이 있어요, 이런 단점은 있을 수 있어요처럼 생각 정리해서 제안하면 돼요.

서로 존중하기

우리는 코드보다 사람이 먼저인 팀이에요.

  • 말투 둥글게 하기
  • 비판이 아니라, 개선을 목표로 말하기

우리 팀의 핵심 가치

  • 질문하는 용기

  • 공유하는 문화

  • 문서화하는 습관

  • 코딩 이후까지 책임지는 태도

  • 리뷰를 존중하는 자세

  • 도전을 두려워하지 않는 마음

폴더 구조

FSD 폴더 구조

└── src/
    ├── app/                    // app 레이어: 앱의 엔트리/조립/전역 설정
    │   ├── main.tsx
    │   └── App.tsx
    ├── pages/                  // pages 레이어: 라우트 단위 화면(진입점)
    │   ├── home/               // pages 내부에서도 ui/model/api를 나눠 화면
    │   │   ├── ui
    │   │   │  └── memo-page.tsx
    │   │   └── index.ts
    │   ├── ai-results/
    │   ├── login/
    │   ├── memo/
    │   └── landing/
    ├── widgets/                // widgets 레이어: 여러 페이지에서 재사용되는 큰 UI 블록
    │   ├── header/
    │   ├── sidebar/
    │   │   ├── api/
    │   │   ├── ui/
    │   │   ├── model/
    │   │   └── ...
    │   └── ...
    ├── features/                // features 레이어: 유저 행동/기능 단위(로그인, 메모 생성, 요약 생성 등)
    ├── entities/                // entities 레이어: 도메인 모델(메모, 사용자, AI결과물 등)
    └── shared/                  // shared 레이어: 전 레이어에서 쓰는 범용 공통(순수/재사용)
        ├── api/
        │   ├── instance.ts
        │   └── configs/         // API 공통 설정(전역)
        │           ├── end-point.ts
        │           └── status.ts
        ├── configs/
        │   └── app-config.ts
        ├── libs/               // 공통 라이브러리 래퍼/설정(외부 라이브러리 초기화 등)
        │   ├── query-client.ts // TanStack Query QueryClient 설정(전역 공통)
        │   └── sentry-init.ts  // Sentry init
        ├── router/             // 라우팅
        │   ├── routes/
        │   ├── path.ts
        │   ├── router.ts
        │   └── ...
└── packages/                  // 모노레포 워크스페이스: 앱과 공통 패키지를 분리해 재사용/버전관리
    ├── cds-ui/
    │   └── 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

No packages published

Contributors 5

Languages