Lsiron

AIR PANG(ts, express, mysql)- 1(기초 및 기획) 본문

개발일지/AIR PANG

AIR PANG(ts, express, mysql)- 1(기초 및 기획)

Lsiron 2024. 8. 14. 09:24

엘리스 부트캠프에서 환경 데이터에 기반한 웹 사이트를 만들기 위해 3주 기간의 2차 프로젝트가 시작되었다.

 

백엔드는 총 2명, 프론트는 총 4명으로 팀원은 총 6명이다.

 

나는 백엔드 포지션을 담당했다.

 

1차 프로젝트 때 해야할 것이 정해져있고 기준 또한 잡혀져있던 것과 달리 2차 프로젝트는 말 그대로 환경 데이터에 기반한 자율주제 였기 때문에 기획이 상당히 많은 포션을 차지했다.

 

첫 1주간의 여정은 아래와 같다.

  1. 포지션 분리 및 역할 분리
  2. 팀원 간 규칙정립 (커밋 컨벤션 등)
  3. 프로젝트 아이디어를 위한 브레인스토밍
  4. 기획서 작성
  5. 데이터의 구조화 (ERD 작성 등)
  6. MVP에 따른 각 포지션 별 역할 분담
  7. 와이어 프레임 작성
  8. 구조화된 데이터와 와이어프레임에 기반하여 API 명세서 작성
  9. 디렉토리 구조화
  10. git lab에 프로젝트 생성

 

기획서

Project Name : 공기 팡!

실시간 대기질 정보를 시각적으로 제공하고, 사용자의 친환경 챌린지 참여를 통해 지역 대기 질 개선에 기여하는 웹서비스입니다.

프로젝트 구성 안내

1. 프로젝트 소개

 

본 프로젝트에서는 대기질 분석을 위한 다양한 데이터셋과 웹 개발 도구 및 기술을 활용하였습니다.

 

사용 데이터셋

  • 대기 오염물질 농도 데이터: PM2.5, PM10, NO2, CO 등 주요 대기 오염물질의 농도 정보를 포함합니다. 이 데이터는 공공기관의 오픈 API를 통해 실시간으로 수집되며, 지역별 대기질 현황을 반영합니다.
  • 대기 질 지수(AQI) 데이터: 대기 질 지수는 대기 오염 상태를 종합적으로 평가하는 지표로, 사용자에게 직관적으로 대기질을 이해할 수 있도록 돕습니다.
  • 과거 대기 질 데이터: 특정 지역의 2023년 연간 및 월별 대기 질 변화 추이를 분석하기 위해 과거 데이터를 사용합니다.

도구 및 기술

  • 프론트엔드: React, Bootstrap React를 활용하여 사용자 친화적인 UI를 구현하였습니다.
  • 백엔드: Node.js와 Express를 사용하여 RESTful API를 구축하였으며, 데이터베이스는 MySQL을 사용하여 대기질 데이터를 효율적으로 저장하고 관리합니다. 그리고 TypeScript를 사용하여 백엔드 코드의 안정성과 유지보수성을 높였습니다.
  • 데이터 시각화: Chart.js를 통해 대기질 데이터를 시각적으로 표현하여 사용자가 쉽게 이해할 수 있도록 하였습니다.
  • 상태 관리: Recoil을 사용하여 애플리케이션 상태를 효율적으로 관리하고, 사용자 인터페이스의 반응성을 높였습니다.

웹서비스 소개

공기 팡은 사용자에게 실시간 대기질 정보를 제공하며, 지역별 대기 오염 수준을 시각적으로 비교할 수 있는 기능을 갖추고 있습니다. 사용자는 자신의 거주 지역의 대기질을 직관적으로 확인하고, 대기질 개선을 위한 개인의 친환경 활동에 참여할 수 있는 챌린지에 안내받게 됩니다.

또한, 과거 대기 질 데이터와의 비교를 통해 대기질 변화에 대한 인사이트를 얻을 수 있으며, 이를 바탕으로 사용자가 보다 나은 환경을 위한 행동을 유도하는 플랫폼으로 발전할 것을 목표로 하고 있습니다.

2. 프로젝트 목표

데이터를 통해 탐색하려는 문제

데이터 분석을 통해 각 지역의 대기 오염물질 농도 현황을 파악하고자 합니다. 대기 오염 지수(AQI) 등급과 점수로 비교하여, 해당 지역의 대기질이 과거에 비해 개선되고 있는지 악화되고 있는지를 확인하고자 합니다. 이를 통해 지역별 대기 오염 수준의 변화 추이를 분석하고, 효과적인 대기 질 개선 방안을 모색할 수 있을 것으로 기대됩니다.

 

데이터 분석 결과로 도출되는 인사이트와 웹서비스의 해결과제

데이터 분석을 통해 도출된 대기오염 지수(AQI)와 실시간 대기질 정보를 활용하여, 사용자에게 지역별 대기질 현황을 시각적으로 제공하고 친환경 챌린지 참여를 통한 대기 정화 기능을 구현함으로써, 사용자의 환경 의식 제고와 실질적인 대기 개선 효과를 달성할 수 있습니다.

 

프로젝트 아이디어 동기

최근 대기 오염이 심각해지면서 국민들의 환경 보호에 대한 관심이 높아지고 있습니다. 이에 따라 우리는 데이터 분석을 통해 지역별 대기질 현황을 파악하고, 이를 사용자에게 시각적으로 제공하고자 합니다. 또한 사용자가 친환경 챌린지에 참여하여 대기 정화에 기여할 수 있도록 하는 기능을 구현함으로써, 환경 보호에 대한 사용자의 인식을 높이고 실질적인 대기 개선 효과를 달성하고자 합니다. 이를 통해 우리는 사용자들이 자신이 살고 있는 지역의 대기질을 실시간으로 확인하고, 자발적인 참여를 통해 지역 사회의 환경 보호에 기여할 수 있도록 지원하고자 합니다.

 

문제를 해결하기 위한 특정 질문

  1. 실시간 대기질 상태는 2023년 연 평균 대기질 상태와 비교하여 어떤 경향을 보이는가? : 실시간 대기질 데이터를 연 평균 대기질 데이터와 비교하여, 현재 대기질 상태가 평균적인 상태보다 더 나쁜지, 아니면 더 좋은지를 평가한다.
  2. 지역별 종합 AQI 등급과 점수는 어떻게 분포하는가? : 각 지역의 2023년 평균 대기오염 물질 데이터를 기반으로 종합 AQI 등급을 산출한 뒤 시각적으로 표현하여, 유저들이 쉽게 이해할 수 있도록 한다. 또한, 지역별 2023년 종합 AQI와 실시간 대기오염 물질 데이터를 기반으로 산출한 AQI를 비교하여, AQI가 동일할 시, 50점을 base score로 실시간 AQI가 더 높으면 점수를 낮게주고, 더 낮으면 점수를 높게주는 방식으로 점수를 계산하였다. 이를 통해 대기질이 상대적으로 좋은 지역과 나쁜 지역을 비교할 수 있다.
  3. 유저의 친환경 챌린지가 지역 대기질 개선에 미치는 영향은 무엇인가? : 유저들이 참여하는 친환경 챌린지 활동이  환경 보호에 더 큰 동기를 가지게 되는지를 분석한다.
  4. 대기오염물질의 농도와 유저 활동 데이터를 기반으로 지역 대기질 개선 방안을 어떻게 제시할 수 있는가? : 데이터 분석을 통해 특정 오염물질의 농도가 높은 지역을 식별하고, 유저들에게 효과적인 환경 보호 활동을 제안하여, 실질적인 대기질 개선 방안을 모색한다.

3. 프로젝트 기능 설명

웹서비스의 유용성, 편의성 및 시각화의 실용성에 대한 설명

사용자가 실시간으로 자신의 거주 지역 대기질 현황을 직관적으로 확인할 수 있도록 시각화된 데이터를 제공합니다. 이를 통해 사용자는 지역별 대기 오염 수준을 쉽게 파악하고, 자신의 일상생활에 미치는 영향을 이해할 수 있습니다. 또한 사용자가 친환경 챌린지에 참여하여 대기 정화 활동에 직접 동참할 수 있도록 하여, 환경 보호에 대한 관심과 참여를 높일 수 있습니다.

주요 기능 (주된 활용성) 및 서브 기능

  • 실시간 대기질 정보 제공: 사용자의 지역 정보를 기반으로 해당 지역의 대기 오염 지수(AQI) 및 오염물질 농도 데이터 제공
  • 지역별 대기질 비교 기능: 사용자가 관심 있는 지역의 대기질을 비교 분석할 수 있는 기능 제공
  • 친환경 챌린지 참여 기능: 사용자가 대기 정화 활동에 참여할 수 있는 챌린지 기능 제공

프로젝트만의 차별점, 기대 효과

실시간 대기질 데이터와 시각화 기능을 통해 사용자의 환경 의식을 향상시키고, 실제 대기 개선 활동에 적극적으로 참여할 수 있도록 지원하는 데 있습니다. 이는 단순히 대기질 정보를 제공하는 기존 서비스와는 차별화되며, 사용자의 능동적인 참여를 이끌어내어 지역 사회의 환경 보호에 기여할 것으로 기대됩니다.

4. 프로젝트 팀원 역할 분담

프론트엔드 & 데이터 담당

< 기획 단계 >

큰 주제에서 문제 해결 아이디어 도출, 데이터 수집, 와이어프레임 작성
주요목표: 데이터 시각화 / 유저 인터페이스 논의 및 시각화


사용자에게 제공할 가치와 기능: 대기질 정보를 통해 질병 예방 및 환경 개선을 위한 참여 유도


주요기능: 
지역별 대기질 정보 시각화 / 관심지역 검색 및 설정
환경챌린지 참여 / 생성

< 개발 단계 >

와이어프레임을 기반으로 구현, 데이터 처리 및 시각화 담당, UI 디자인 완성
· 와이어프레임

목표: 사용자의 인터페이스와 사용자 경험(UX)을 직관적으로 설계하여 쉽게 정보를 제공

와이어프레임 도구: Figma

와이어프레임 구성

메인 페이지: 간략한 관심지역 대기질 정보 위젯, 소셜 로그인

로그인 후 메인 페이지: 지역별 선택, 최신 대기질 정보 요약

환경 챌린지 페이지: 챌린지 리스트
- 챌린지 생성 페이지
- 할일 추가 모달

마이페이지: 관심지역 검색 및 추가, 챌린지 진행상황 (최대 3개 디스플레이) 



 

백엔드 & 데이터 담당

< 기획 단계 >

문제 정의: 지역별 대기오염물질 데이터를 분석하여 각 지역의 대기 질을 등급화하고, 실시간 대기오염물질과 연간 대기오염물질 데이터를 통합 AQI로 환산해 비교하는 문제를 해결하고자 함. 이 프로젝트는 사용자들에게 환경에 대한 인식을 높이고, 친환경 행동을 장려하기 위해 설계함.

데이터 수집 및 분석: 지역별 월간 그리고 연간 대기오염물질 데이터 수집, 데이터의 정합성 및 신뢰성 검토, 데이터 분석을 통해 초기 통계 및 트렌드를 파악함.

목표 설정: 사용자들이 친환경 행동을 통해 점수를 높이는 시스템 구축, 이를 통해 대기 질 개선에 대한 인식 제고.

< 개발 단계 >

웹 서버 구축: 사용자들이 백엔드에 데이터를 저장할 수 있는 기능 구현.

데이터베이스 구축: MySQL 관계형 데이터베이스를 사용하여 대기오염물질 데이터 저장. 사용자 행동 데이터를 기록하고 관리할 수 있는 테이블 구조 설계.

API 활용: 외부 대기오염 데이터 API와 통신하여 실시간 데이터 수집. 이를 통해 실시간 AQI 계산 및 업데이트.

데이터 분석 및 시각화: 지역 별 대기 질 등급화 및 통합 AQI 시각화.

< 수정 단계 >

피드백 반영: 코치님 피드백을 기반으로 데이터 분석 및 시각화 방식 수정. 데이터 처리 방식 개선 및 시각화 그래프의 가독성 향상.

기능 개선: UI 및 UX 개선. 친환경 챌린지 참여도를 높이기 위한 인터랙티브 요소 추가.

성능 최적화: 데이터베이스 쿼리 최적화, API 응답 속도 개선

 

ERD

MVP

  • 로그인과 회원가입 관련한 auth MVP
  • 사용자 관련한 user MVP
  • 지역 및 지역 대기질 정보 관련한 geo MVP
  • 유저 환경챌린지 관련한 challenge MVP

와이어프레임

 

API 명세서

MVP Method EndPoint request body response body Description exception handling
  GET / None {
"locations": {
"id": 1,
"address_a_name": "서울",
"address_b_name": "강남구"
},
"Realtime_Air_Quality": {
"aqi": 56,
"co": 0.6,
"no2": 0.009,
"o3": 0.047,
"pm10": 22,
"pm25": 13,
"so2": 0.003,
}
}
구글 또는 네이버 로그인 선택 제공,
대표적으로 서울 강남구 기후데이터 제공
 
Auth GET /google None None 사용자가 구글 로그인 페이지로 Redirect (구글을 통한 소셜로그인) 성공 시 200 Ok 실패시 400 Bad Request 또는 500 Internal Server Error
Auth GET /google/callback None(쿼리 파라미터로 code와 state가 포함) None 서버는 인증 코드를 사용하여 토큰을 요청하고, 성공 시 메인 페이지로 Redirect 성공 시 200 Ok 실패시 400 Bad Request 또는 500 Internal Server Error
Auth GET /refresh-token None   리프레시 토큰을 이용한 엑세스 토큰 갱신 성공시 accessToken 발급, 실패시 401 Unauthorized 또는 403 Forbidden 에러
User GET /my None {
"User_Locations": [
{
"id":1,
"location_id": 119,
},
{
"id":2,
"location_id": 74,
}
],
"Challeng_Status": [
{
"id": 1,
"challenge_id": 10
"title": "분리수거 하기",
"description": "플라스틱 분리수거 시 라벨지 제거 하기",
"status": "진행중"
"start_date": "2023-07-01",
"end_date": "2023-07-07",
},
{
"id": 2,
"challenge_id": 11
"title": "자전거 타기",
"description": "출,퇴근 시 자전거 타기",
"status": "진행중"
"start_date": "2023-07-05",
"end_date": "2023-07-10",
}
]
}
사용자 정보 조회(유저의 마이페이지 정보와 참여중인 환경 챌린지 목록 조회), 관심지역 페이지 조회
유저의 마이페이지 조회시, 현재 로그인 된 사용자의 id와 name은 세션에서 가져와서 사용
성공 시 200 Ok 실패시 500 Internal Server Error
User POST /my/logout None   로그아웃 성공 시 200 Ok 실패시 500 Internal Server Error
User DELETE /my None   회원 탈퇴- deleted_at 업데이트
유저의 마이페이지 조회시, 현재 로그인 된 사용자의 id와 name은 세션에서 가져와서 사용
성공 시 200 Ok 실패시 401 Unauthorized 또는 500 Internal Server Error
User GET /my/locations Request Parameters:
userId: 유저의 id
{
"locations": [
{
"id":1,
"address_a_name": "강원",
"address_b_name": "강릉시"
},
{
"id":2,
"address_a_name": "강원",
"address_b_name": "고성군"
}
]
}
사용자 관심지역 페이지 조회
유저의 마이페이지 조회시, 현재 로그인 된 유저의 id를 파라미터에서 가져와서 사용
성공 시 유저 관심지역 반환 실패시 500 Internal Server Error
User POST /my/locations Request Parameters:
userId: 유저의 id,
{
"locations": [
{
"id":1
},
{
"id":2
}
]
}
  사용자 관심지역 추가
유저의 마이페이지 조회시, 현재 로그인 된 유저의 id를 파라미터에서 가져와서 사용
성공 시 201 Created 실패시 400 Bad Request 또는 500 Internal Server Error
User PUT /my/locations Request Parameters:
userId: 유저의 id,
{
"locations": [
{
"id":1
},
{
"id":2
}
]
}
  사용자 관심지역 삭제
유저의 마이페이지 조회시, 현재 로그인 된 유저의 id를 파라미터에서 가져와서 사용
성공 시 204 Not Contents 실패시 400 Bad Request 또는 500 Internal Server Error
User DELETE /my/locations/:id Request Parameters:
userId: 유저의 id,
{
"locations": [
{
"id":1
},
{
"id":2
}
]
}
  사용자 관심지역 삭제
유저의 마이페이지 조회시, 현재 로그인 된 유저의 id를 파라미터에서 가져와서 사용
성공 시 204 Not Contents 실패시 400 Bad Request 또는 500 Internal Server Error
Geo GET /locations req.query.location [
{
"location": "강원",
"averageAQI":48
},
{
"location": "경기"
"averageAQI":59
},
// ... 다른 메인 지역들
]

특정 주요 지역의 메인 지역 목록 가져오기
(각 메인 지역 평균 AQI 에 따른 색깔과 등급 표시)
성공 시 200 Ok 실패시 500 Internal Server Error
Geo GET /locations/sub req.query.location [
{
"location": "강남구",
"annualMaxAQI": 64,
"realtimeMaxAQI": 46,
},
{
"location": "강동구",
"annualMaxAQI": 61,
"realtimeMaxAQI": 61,
},
{
"location": "강북구",
"annualMaxAQI": 61,
"realtimeMaxAQI": 43,
}
// ... 다른 세부 지역들
]

특정 주요 지역의 세부 지역 목록 가져오기
(각 세부 지역 등급에 따른 색깔과 점수 표시)

query parameter 방식 사용
http://localhost:3000/location?location=서울
성공 시 200 Ok 실패시 400 Bad Request 또는 500 Internal Server Error
Geo GET /locations/detail req.query.location
req.query.subLocation
{
"locations": {
"id":1,
"address_a_name": "강원",
"address_b_name": "강릉시"
},
"Realtime_Air_Quality": {
"pm10": 25,
"pm25": 18,
"o3": 0.05,
"no2": 0.03,
"co": 0.6,
"so2": 0.004,
"aqi": 85
},
"monthly_aqi": [
{"month": "1월", "aqi": 85},
{"month": "2월", "aqi": 78},
{"month": "3월", "aqi": 90},
{"month": "4월", "aqi": 95},
{"month": "5월", "aqi": 70},
{"month": "6월", "aqi": 60},
{"month": "7월", "aqi": 55},
{"month": "8월", "aqi": 65},
{"month": "9월", "aqi": 80},
{"month": "10월", "aqi": 85},
{"month": "11월", "aqi": 90},
{"month": "12월", "aqi": 95}
]
}
세부지역의 월별 통합 AQI지수 변화 추이 그래프, 세부지역의 오늘의 대기질 및 등급, 점수 정보

query parameter 방식 사용
http://localhost:3000/location/detail?location=서울&subLocation=강남구
성공 시 200 Ok 실패시 400 Bad Request 또는 500 Internal Server Error
Challenge GET /challenges None {
"challenges": [
{
"id": 1,
"title": "친환경 생활 실천",
"description": "일주일 동안 플라스틱 사용 줄이기",
"goal": 5,
"progress": 2
"start_date": "2023-07-01",
"end_date": "2023-07-07",
"user_id": 4,
"user_name": "김재영"
},
{
"id": 2,
"title": "지구를 위한 작은 변화",
"description": "우리의 일상에서 쉽게 실천할 수 있는 작은 변화로 지구를 보호하는 챌린지입니다. 매일 하나씩 친환경 행동을 실천해보겠습니다 ㅎㅎ",
"goal": 5,
"progress": 0
"start_date": "2023-08-01",
"end_date": "2023-08-07",
"user_id": 1,
"user_name": "이승철"
}
]
}
모든 환경챌린지 목록 가져오기
검색어가 제공되면 해당 검색어에 맞는 챌린지 목록을 반환.

Query String으로 검색결과 받기.
/challenges?search=친환경
을 통해 '친환경'에 해당하는 챌린지 목록을 가져옴

챌린지 만들기 버튼있음

유저 아이디 통해서 유저 이름 가져오기
성공 시 200 Ok 실패시 500 Internal Server Error
Challenge GET /challenges/:id url Parameters
id: 해당 챌린지 id
{
"challenge": {
"id": 1,
"title": "친환경 생활 실천",
"description": "일주일 동안 플라스틱 사용 줄이기",
"goal": 2,
"progress": 1,
"start_date": "2023-07-01",
"end_date": "2023-07-07"
},
"tasks": [
{
"id": 1,
"challenge_id": 1,
"description": "텀블러 사용하기",
"is_completed": false
},
{
"id": 2,
"challenge_id": 1,
"description": "재사용 가능한 가방 사용하기",
"is_completed": true
}
],
"userId": 1
}
선택한 환경챌린지 상세 가져오기

챌린지 수정하기, 삭제하기 버튼있음

투두 리스트 가져오기

투두 리스트 수정하기, 삭제하기 버튼있음
성공 시 200 Ok 실패시 500 Internal Server Error
Challenge POST /challenges {
"title": "자전거 타기",
"description": "일주일 동안 자전거로 출퇴근하기",
"start_date": "2023-07-10",
"end_date": "2023-07-16",
"tasks": [
{
"description": "자전거 정비하기"
},
{
"description": "자전거 안전 장비 착용하기"
}
]
}
  새로운 환경챌린지 추가하기 성공 시 201 Created 실패시 400 Bad Request 또는 500 Internal Server Error
Challenge PATCH /challenges/:id url Parameters
id: 해당 챌린지 id,
{
"title": "자전거 타기 수정",
"description": "수정된 내용",
"start_date": "2023-07-10",
"end_date": "2023-07-17"
}
  특정 환경챌린지 수정하기 성공 시 204 Not Contents 실패시 400 Bad Request 또는 500 Internal Server Error
Challenge DELETE /challenges/:id url Parameters
id: 해당 챌린지 id
  특정 환경챌린지 삭제하기 성공 시 204 Not Contents 실패시 400 Bad Request 또는 500 Internal Server Error
Challenge POST /tasks {
"challenge_id": 2,
"description": "자전거 정비하기"
}
  새로운 할 일 추가하기 성공 시 201 Created 실패시 400 Bad Request 또는 500 Internal Server Error
Challenge PATCH /tasks/:id url Parameters
id: 해당 챌린지 id,
{
"description": "수정된 내용"
}
  특정 할 일 수정하기 성공 시 204 Not Contents 실패시 400 Bad Request 또는 500 Internal Server Error
Challenge DELETE /tasks/:id url Parameters
id: 해당 챌린지 id
  특정 할 일 삭제하기 성공 시 204 Not Contents 실패시 400 Bad Request 또는 500 Internal Server Error

기능명세 참조표

디렉토리 구조

data_project/
├── back                              # 백엔드 프로젝트 루트 디렉토리
│   ├── logs                          # 로그 파일들이 위치하는 디렉토리
│   ├── node_modules                  # 의존성 모듈들이 위치하는 디렉토리
│   └── src                           # 소스 파일들이 위치하는 디렉토리
│       ├── config                    # 환경설정 관련 파일들이 위치하는 디렉토리
│       ├── controllers               # 컨트롤러 파일들이 위치하는 디렉토리
│       ├── dto                       # 데이터 전송 객체들이 위치하는 디렉토리
│       ├── middlewares               # 미들웨어 파일들이 위치하는 디렉토리
│       ├── repositories              # 데이터 저장소 파일들이 위치하는 디렉토리
│       ├── routes                    # 라우트 정의 파일들이 위치하는 디렉토리
│       ├── services                  # 서비스 파일들이 위치하는 디렉토리
│       ├── types                     # 타입 정의 파일들이 위치하는 디렉토리
│       ├── utils                     # 유틸리티 함수들이 위치하는 디렉토리
│       ├── app.ts                    # 애플리케이션 진입점 파일
│       └── index.ts                  # 서버 시작 파일
│   ├── .env                          # 환경변수 설정 파일
│   ├── .env.production               # 프로덕션 환경변수 설정 파일
│   ├── .gitignore                    # Git에서 무시할 파일을 지정하는 파일
│   ├── nodemon.json                  # Nodemon 설정 파일
│   ├── package-lock.json             # 정확한 버전의 패키지를 설치하기 위한 파일
│   ├── package.json                  # 프로젝트 메타데이터 및 의존성 목록
│   └── tsconfig.json                 # TypeScript 설정 파일
│
├── front                             # 프론트엔드 프로젝트 루트 디렉토리
│   ├── node_modules                  # 의존성 모듈들이 위치하는 디렉토리
│   ├── public                        # 정적 파일들이 위치하는 디렉토리
│   └── src                           # 소스 파일들이 위치하는 디렉토리
│       ├── assets                    # 이미지, 폰트 등 자산 파일들이 위치하는 디렉토리
│       ├── components                # 리액트 컴포넌트들이 위치하는 디렉토리
│       ├── context                   # 컨텍스트 관련 파일들이 위치하는 디렉토리
│       ├── data                      # 데이터 관련 파일들이 위치하는 디렉토리
│       ├── pages                     # 페이지 관련 파일들이 위치하는 디렉토리
│       ├── services                  # API 서비스 파일들이 위치하는 디렉토리
│       ├── styles                    # 스타일 파일들이 위치하는 디렉토리
│       ├── utils                     # 유틸리티 함수들이 위치하는 디렉토리
│       ├── App.jsx                   # 메인 리액트 컴포넌트 파일
│       ├── App.test.jsx              # 리액트 컴포넌트 테스트 파일
│       └── index.jsx                 # 애플리케이션 진입점 파일
│   ├── .env                          # 환경변수 설정 파일
│   ├── .env.production               # 프로덕션 환경변수 설정 파일
│   ├── .gitignore                    # Git에서 무시할 파일을 지정하는 파일
│   ├── config-overrides.js           # CRA(create-react-app) 구성 설정 파일
│   ├── package-lock.json             # 정확한 버전의 패키지를 설치하기 위한 파일
│   ├── package.json                  # 프로젝트 메타데이터 및 의존성 목록
│   └── server.js                     # 서버 설정 파일

 

마지막으로, git lab에 프로젝트를 생성했다.

 

그럼 한번 제작을 시작해보자.