목차
프로젝트 기술 스택
백엔드
- Java 11
- Spring Boot
- Spring Data JPA
- QueryDSL
- Rest Docs
- MySQL
- Jacoco
- AWS EC2, RDS, S3, CodeDeploy
- Gradle
프론트엔드
- TypeScript
- React
- Next.js
- Vercel
- Context API
- StoryBook
협업툴
- Jira
- Notion
- Slack
- Git&GitHub
💘 협업 준비
코드 스타일 합의 (Eslint, Prettier)
ESlint 규칙 파헤치기
module.exports = { printWidth: 80, // 코드 라인 길이 tabWidth: 2, // 탭 간격, 스페이스 설정 시 2칸 띄어쓰기 singleQuote: true, // '' 작은 따옴표 사용 trailingComma: 'all', // , 자동으로 붙이기 semi: false, // ; 사용 안 함 useTabs: false, // tab키 사용. false 추천 == space 대체 arrowParens: 'always', // (x) => x, x => x로 전자처럼 괄호 유지 endOfLine: 'auto', // EOL 자동 삽입 bracketSpacing: true, // 대괄호 {} 사이 공백 jsxBracketSameLine: true, // JSX 요소 > 줄바꿈 }
{ "env": { "browser": true, "node": true }, "root": true, "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint", "prettier"], "extends": [ "plugin:@typescript-eslint/recommended", "prettier", "plugin:prettier/recommended" ], "parserOptions": { "project": "./tsconfig.json" }, "rules": { "@typescript-eslint/space-before-function-paren": "off", "no-var": "error", // var 변수를 사용하지 않는다. "object-curly-spacing": ["error", "always", { "objectsInObjects": false }], // 시작 괄호 바로 다음과 끝 괄호 바로 이전에 공백이 있으면 안 된다. "key-spacing": ["error", { "beforeColon": false }], // 키워드, 연산자와 다른 코드 사이에 공백이 있어야 한다. "newline-before-return": "error", // return문 바로 위는 한 칸 비워 놓는다. "eqeqeq": ["error", "always"], // 삼중 등호 연산자인 ===, !==만 사용한다. "prefer-template": "error", // 변수 등을 조합해서 문자열을 생성하는 경우 템플릿 문자열을 이용한다. "implicit-arrow-linebreak": ["error", "beside"], // 암시적 반환을 사용할 경우 함수 본문 전에 개행을 하지 않는다. "arrow-parens": ["error", "as-needed"], // 화살표 함수의 파라미터가 하나이면 괄호를 생략한다. "prefer-arrow-callback": "error", // 함수 표현식 대신 화살표 함수를 사용한다. "lines-between-class-members": ["error", "always"], // 메서드 문법 사용 시 메서드 사이에 개행을 추가한다. "object-shorthand": ["error", "always"], // 객체의 메서드 표현 시 축약 메소드 표기를 사용한다. "no-self-assign": ["error", { "props": true }] // 자기 참조 할당은 하지 않는다. } }
네이밍 컨벤션
- Component 는 Pascal Case (ex. Divider)
- 변수명의 경우 Camel Case (ex. useForm)
- 함수명의 경우 동사+목적어 (ex. useForm, displayHeader)
.
으로 세 번 이상 depth 로 진입해서 접근하는 경우는 별도의 변수 선언하여 사용
- 상수 변수는 대문자로 명명 (ex. ROOT_URL, API_KEY)
컴포넌트 컨벤션
- 스타일드 컴포넌트 로직은 중요 로직 아래, 하위에 위치시킬 것.
- 각 기능별 주석을 달아 이해를 도울 것.
프로젝트 관리 - 지라
Branch 관리
- Git flow 방식
main
-develop
-issue_based_branch
- main, develop, feature, release, Hotfix 총 5개의 브렌치사용
- 지라 이슈 넘버를 브렌치 네이밍으로 활용 + 컴포넌트 이름은 파스칼 케이스로 ⇒ Ex. feat/GD-XX/Avatar

Commit 메시지 관리
feat : 새로운 기능 추가
fix : 버그 수정
docs : 문서 수정
style : 코드 포맷팅, 세미콜론 누락, 코드 변경이 없는 경우, 디자인 변경시
refactor : 코드 리펙토링
test : 테스트 코드, 리펙토링 테스트 코드 추가
build : 빌드 관련 파일 수정에 대한 커밋
chore : 자잘한 수정, 파일 삭제
add : 파일 추가
PR 관리
- PR 제목에는 지라의 이슈 넘버를 기입함 Ex. [GD-73] [커밋 메시지 Feat, Style] : ESlint 규칙 추가
- .github 폴더를 이용한 템플릿화
- PR 템플릿
- 머지되었을 경우 지라와 연동하여 이슈 Close

코드 리뷰
- 매일 스크럼 마무리 후, 1시간 가량의 각 개인 간 코드리뷰 시간을 가짐
- PR등록 후, 최소 24시간 이내 Aprove 할 것 (LGTM)
- 엣지 케이스, 개선 사항 제안은 자유
💠 UI 흐름도
📄 UI 기능 명세서
작성 방법
구현해야하는 기능(동작 또는 데이터에 따른 변동)요소에 대해 상세하게 설명해주세요.
- 1) 무엇을 2) 어떻게 작동해야하는지 적어주세요
- 기능이 작동하지 않았을 때 에러처리 어떻게 해야할지(에러 메세지 등) 빨간색으로 적어주세요.
- 페이지 이동은 노란색으로 적어주세요.
- 컴포넌트 명칭은 [컴포넌트] 로 작성해주세요
페이지 목록
- 로그인 페이지
- 메인 페이지
- 마이페이지
- 등록한 이벤트 디테일 페이지
- 받은 선물함 디테일 페이지
- 선물 등록 페이지
- step별로 5개의 컴포넌트로 구성
- 선착순 선물 받기 페이지
- 랜덤 선물 받기 페이지
Default
- 로그인, 메인 페이지 제외하고 로그인 기반으로 접속하게끔 체크
로그인 페이지

번호 | 기능명세서 |
1 | [로고] Large로고 |
2 | [Text] |
3 | [버튼] 구글 소셜 로그인
- 버튼 클릭 시, API연동 되어 로그인 진행
- API 최초 로그인 성공 시, DB에 사용자 정보 저장
- 로그인 성공시 메인 페이지 이동 |
메인 페이지

번호 | 기능명세서 |
1 | [로고] Small로고
- 클릭 시 메인 페이지 이동 |
2 | [Avatar] 사용자 구글 프로필 이미지 표시
- 클릭 시 마이 페이지 이동 |
3 | [Text] 서비스 소개 |
4 | [Button] 이벤트 생성
- 클릭 시 이벤트 등록 페이지 이동 |
5 | 동영상 애니메이션 효과 넣기 |
마이 페이지 - 받은 선물함


번호 | 기능 명세서 |
1 | 유저 정보
- 이미지, 이름, 이메일 |
2 | 받은 선물함, 나의 이벤트 탭에 따라 다른 컴포넌트 |
3 | 받은 선물 목록 필터
- 전체 / 사용한 선물 / 미사용 선물 중 하나만 선택할 수 있다. |
4 | 받은 선물 목록 List
- 받은 선물 (이미지, 텍스트, 만든 유저 정보)
- 받은 선물이 텍스트일 경우 지정된 커버 이미지 + 텍스트
- 클릭 시 해당 이벤트 디테일 페이지 이동 |
5 | 사용 완료 표시 여부
- 디테일 페이지에서 사용 완료 체크 가능 |
6 | 나의 이벤트 목록 필터
- 전체 / 진행중인 이벤트 / 종료된 이벤트 중 하나만 선택할 수 있다. |
7 | 나의 이벤트 List
- 커버이미지와 이벤트 제목을 카드형태로 보여준다.
- 클릭 시 해당 이벤트 디테일 페이지 이동 |
8 | 이벤트 진행 여부 표시
- 진행중 / 종료
- 선물이 소진 되었을 시 이벤트 종료
- 종료 시간이 지났을 때, 이벤트 종료 |
마이 페이지 - 받은 선물함 디테일

번호 | 기능 명세서 |
1 | [버튼]
- 클릭 시 이전 페이지 (마이 페이지의 받은 선물 목록 탭으로 이동) |
2 | 받은 선물 제목 |
3 | 받은 선물 사용 여부 체크
- 미사용시 비활성 색상
- 사용시 활성 색상 |
4 | 선물 받은 날짜 및 시간 |
5 | 이벤트 생성자 이름 표시 |
6 | 받은 선물
- 이미지일 경우 원본
- 텍스트일 경우 이벤트 커버이미지와 텍스트를 편지 형태로 보여줌 |
7 | 이미지 저장 기능(다운로드) |
마이 페이지 - 등록한 이벤트 디테일



번호 | 기능 명세서 |
1 | [버튼]
- 클릭 시 이전 페이지 (마이 페이지의 등록한 이벤트 목록 탭으로 이동) |
2 | 이벤트 커버이미지 |
3 | [버튼]
- 이벤트 삭제
- 클릭 시 이벤트 삭제 여부 확인 |
4 | 이벤트 제목 |
5 | [버튼] 클릭 시, 클립보드에 이벤트 링크가 복사 |
6 | 설정한 이벤트 오픈 시간, 종료 시간 표시 |
7 | [버튼] 클릭 시, 당첨자 목록 Modal 띄우기 |
8 | 현재 시간 기준으로 오픈, 종료까지 카운트 다운 표시 |
9 | 아이템 카테고리 별 당첨자 정보(이름, 이메일) 표시
- 커버 이미지 색상은 랜덤 |
이벤트 등록 페이지

번호 | 기능 명세서 |
1 | Material-UI Stepper 사용
단계에 따른 설정 값 등록 |
2 | 이벤트 제목 입력
- 필수 입력 폼
- 최대 15자 글자수 제한 |
3 | 참여인원수 입력
- 필수 입력 폼
- 최소 1 이상 입력해야 함 |
4 | 이벤트 커버 이미지 선택
- 내가 만든 이벤트에서 활용
- 선물 당첨자의 받은 선물에서 편지지로 활용(텍스트일 경우)
- 필수 입력 폼
- 1개만 선택 가능 |
5 | [Button] 클릭시 다음 단계 진행
- 2,3,4번의 입력폼은 로컬 스토리지에 저장 후 다음 단계로 넘어감 |

번호 | 기능 명세서 |
1 | 이벤트 오픈/종료 날짜 및 시간 설정
- 종료 시간이 오픈 시간보다 빠르지 않게 예외처리
- 오픈 시간이 현재 시간보다 빠르지 않게 예외처리 |
2 | [Button] BACK 클릭 시 이전 입력 폼으로 이동
- 로컬스토리지에 저장된 데이터 기반으로 이전 폼 보여줌 |
3 | [Button] NEXT 버튼 클릭시 다음 폼으로 이동
- 오픈시간, 종료시간 로컬스토리지 저장 후 다음 단계로 넘어감 |

번호 | 기능 명세서 |
1 | 랜덤 이벤트, 선착순 이벤트 설정
- 필수 입력 폼 |
2 | BACK, NEXT 기능 명세서는
위의 2,3번 기능 명세와 동일 |


번호 | 기능 명세서 |
1 | 등록한 선물의 총 수량 표시 |
2 | 선물 추가하기 클릭 시, 선물 추가 Modal 띄우기 |
3 | 커버 이미지는 Local에서 저장한 Image를 랜덤으로 보여주게 설정 단순 UI시각화 목적 |
4 | 삭제 버튼 클릭 시, 삭제 확인 여부 Alert 띄우기 |
5 | 꽝 수량 표시
- 처음에 입력한 참여자 수 - 등록한 선물 = 꽝 수량 |
6 | 작성한 이벤트 Form 서버에 전송
- 서버에 업로드 성공 시 로컬스토리지 삭제 |
선물 추가 Modal

번호 | 기능 명세서 |
7 | Modal창 닫기 |
8 | 선물 카테고리 제목 입력 |
9 | 이미지 추가 |
10 | 메세지 추가 (링크, 편지, 쿠폰 번호) |
11 | +버튼 클릭 시, 작성한 폼 하위에 텍스트 미리보기 형태로 추가 |
12 | 메세지 List 표시 |
13 | 일정 수 넘어가면 말줄임 처리
더보기 기능을 통해 전체 내용 확인 가능 |
14 | 완료 버튼 클릭 시, 위 페이지 3번에 List 추가 |

번호 | 기능 명세서 |
1 | [Text] |
2 | 링크 주소
- 클릭시 해당 URL로 이동(a링크) |
3 | [버튼] 클릭 시, 클립보드에 이벤트 링크가 복사 |
선착순 선물 받기 페이지

번호 | 기능 명세서 |
1 | 이벤트 작성자 이름 표시 |
2 | 현재 시간 기준으로 이벤트 시작 시간까지 카운트 다운 표시 |
3 | 이벤트에 포함 된 선물 List를 화면에 뿌려줌
- 커버 이미지는 Local에서 저장한 Image를 랜덤으로 보여주게 설정 단순 UI시각화 목적 |
4 | [Button] 자신이 원하는 Item을 GET버튼 클릭으로 받아 올 수 있게 설정
- 클릭 시, 서버에 해당 Item을 클릭했다는 정보를 보내줌
- 수량이 없다면 다른 버튼 클릭 가능
- 수량이 남아 있으면 받았다는 Alert알람 표시 → 마이페이지 저장
- 서버에서 이벤트 참여자 목록과 현재 접속한 유저 정보를 비교해서 참여 여부 판단 |
랜덤 선물 받기 페이지

번호 | 기능 명세서 |
1 | 이벤트 작성자 이름 표시 |
2 | 현재 시간 기준으로 이벤트 시작 시간까지 카운트 다운 표시 |
3 | 랜덤 박스 클릭 시, 랜덤으로 선물 당첨
- 당첨이 된 경우 Alert알람 표시
- 한 번 참여 완료 시 해당 페이지 접근을 막거나 버튼 GET버튼 비활성화
- 서버에서 이벤트 참여자 목록과 현재 접속한 유저 정보를 비교해서 참여 여부 판단 |