엘리스 AI트랙 7기 1차 프로젝트: 포트폴리오 공유 웹 서비스 <백투더퓨처>

2023/04/24~2023/05/06

개발자 연습생으로서 첫 번째 프로젝트가 끝났다. 프로젝트 시작 직전엔 취업 준비를 병행한답시고 시간을 100% 투자하지 못했어서 강의 진도를 따라가는 것에 급급한 상태였다. 게다가 바로 직전 주말에는 회사 필기와 기사 실기 시험을 봤는데, 일요일 첫 미팅을 마칠 때까지 ‘나만 진도 못 따라잡아서 민폐가 되면 어떡하지…’ 라는 생각만 들었다.

집중할 수 있는 마음가짐을 갖기 위해서 프로젝트와 이후의 엘리스 과정에 신경을 완전히 쏟아야겠다고 다짐했다. 일요일 시험을 보고 나오면서 집에 전화를 걸어 수료 전까지는 1순위 회사들을 제외한 곳들은 지원하지 않고 개발 공부에 집중하겠다고 얘기했다. 지키고 있는진 모르겠다.

AI 트랙을 시작하기 전에는, 만약 개발자가 된다면 데이터와 관련된 일을 하는 개발자가 되고 싶다고 막연히 생각했기 때문에 프로젝트를 할 때는 백엔드를 하는 게 좋을 것 같았다. 한편으로는 어떤 포지션을 하든 눈앞에 닥치면 해낼 수 있을 거라는 근거 없는 자신감에 나는 희망 직무 설문조사에서 ‘무관’ 이라는 무책임한 선택을 하고 만다. 그리고 회의 도중 프론트엔드를 맡게 되는데……. (밑에서 계속)

우리의 귀여운 깃그래프 - 마지막날까지 어떻게 보는지 몰랐는데 지금 보니까 좀 알겠당

우리의 귀여운 깃그래프 - 마지막날까지 어떻게 보는지 몰랐는데 지금 보니까 좀 알겠당

우리 팀원들은 개발이 처음이거나, 개발 프로젝트를 처음 진행해 보거나, 각자의 포지션으로 프로젝트 경험은 처음인 사람들로 모였다. 다른 팀에 비하면 지식적으로 특출난 사람은 없었지만, 결과적으로 우리는 2주 동안 수많은 시행착오를 거치며 대화를 통해 최선을 방향을 설정할 수 있었다.

학교에서 이런 장기적인 팀프로젝트를 진행한 적은 거의 없지만, 몇 안 되는 경험을 통해 느낀 점이 있다. 가지고 있는 지식 수준이 많이 차이나면 오히려 진행 상황을 쫓아가야 하는 사람이 생기고, 이 차이를 보정하기 위해 또 시간을 할애해야 하기 때문에 힘들었던 기억이 있다. 물론 내가 쫓아가야 하는 사람이었음.. -.ㅠ

인턴 팀 프로젝트를 통해 배운 명확한 의사소통법, 어려울 땐 도움 요청하기, 방향성 설정, 모두의 의견을 수용하고 각자가 가진 장점을 배우기… 같은 것들을 이번 프로젝트를 진행하면서 활용할 수 있었다.

프로젝트 기간에는 거의 매일 엘리스랩에서 개발을 했는데, 지윤님과 문제가 생기면 서로 도우면서 바로 해결할 수 있어 정말 편했다. 나는 성격이 급해서 질문에 대한 피드백을 기다리는 것이 어려운 사람이다…. 첫날에는 스켈레톤 코드를 살펴보며 컴포넌트를 파일들이 어떤 구조를 가지고 있는지, 각 파일과 코드가 하는 기능을 알아내기 위해 시간을 보냈다. 그러다 지치면 홈페이지의 레이아웃/디자인에 대한 얘기를 하면서 바로 싸이월드 콘셉트를 확정했다.

인터넷에 있는 html, css 코드를 참고해서 지윤 님이 전체적인 디자인을 입히고, 기존 CSS 와 충돌하는 부분과 화면이 무너지는 것들은 뜯어보면서 수정하고 화면 구성도 변경해 보다 잘 안 되면 코치님의 도움을 받아 디테일을 맞춰 가며 싸이월드의 구색을 갖췄다.


백투더퓨처 - Description

시유 님의 README.md 를 참고했습니다….

기획 의도

포트폴리오 공유와 함께 개인의 포트폴리오 = 개인 공간이라는 것을 착안하여 추억의 공간 ‘싸이월드’ 콘셉트를 인용하여 개인의 포트폴리오 관리와 개발자들 간의 온라인 커뮤니티를 형성하고자 함

component 구성

Untitled

******************기존 스켈레톤 components******************

  • User: 회원가입, 로그인 등 사용자 정보 관리
  • Award: 수상 이력
  • Certificate: 자격증
  • Education: 교육사항
  • Project: 프로젝트

********추가한 components********

  • Career: 경력사항
  • Skill: 사용 기술
  • GuestBook: 방명록

주요 사용 기술

Front

  • JavaScript
  • Bootstrap
  • React

Back

  • Node.js
  • Express.js
  • Mongo DB
  • POSTMAN

팀원

Front

Back


페이지 구성과 기능

기본적으로 네 가지 페이지가 있고, 데스크탑이 아닌 기기(스마트폰, 태블릿 등)를 사용할 때도 화면 크기에 상관없이 편리하게 볼 수 있도록 반응형 웹사이트 또한 구현했다.

  1. Login
    1. Login
    2. Register
  2. Home
    1. 유저 프로필
    2. GuestBook을 제외한 모든 컴포넌트
  3. GuestBook
    1. 유저 프로필
    2. 미니홈피 주인/타인이 미니홈피 주인에게 남긴 방명록
  4. Network
    1. 본인을 포함한 모든 유저들의 유저 프로필 및 미니홈피로 연결되는 링크

2주간 저의 고군분투기를 소개합니다. 페이지를 하나씩 살펴보면서 기억을 더듬어 보겠습니다. 물론 프론트엔드 위주의 리뷰가 될 것 같습니다….

ღ Login

******주요 기능 - 하이라이트는 추후 추가한 기능******

→ 로그인/회원가입 시 이메일, 비밀번호 validation (이메일 형식, 비밀번호 최소 글자)

→ 로그인 화면에서 이메일 비밀번호를 입력하면 배경색 변경

**************사이트 초기 화면 - 로그인 화면**************

Untitled

주소를 입력하면 /login페이지로 라우팅된다.

Untitled

컨트롤에 뭔가 입력하면 배경색이 변한다.

**************회원가입 화면**************

Untitled


ღ Home

******주요 기능 - 하이라이트는 추후 추가한 기능******

→ 개인 포트폴리오 열람

→ 경력, 학력, 수상이력, 자격증, 프로젝트, 사용기술 컴포넌트 수정/삭제

Untitled

로그인하면 가장 먼저 볼 수 있는 나의 포트폴리오 화면이다.

콘텐츠가 많아지거나 데스크탑 해상도가 작은 경우 미니홈피 영역이 잘리는 때가 있어 수정했던 기억이 난다. 페이지 전체 영역과 미니홈피 영역 모두에 스크롤을 적용했다.

Untitled

❶ UserCard

→ 프로필 사진, 유저 이름, 이메일, 인사말 등 개인 정보

→ github, blog 링크

인사말 아래에는 깃허브와 티스토리 아이콘이 있다. 편집 화면에서 깃허브/티스토리 링크를 입력해 두면 저 아이콘을 눌렀을 때 그 사람의 블로그와 깃허브로 이동할 수 있다.

편집 화면

Untitled

→ 프로필 사진 추가

입력하지 않으면 우리가 알고 있는 싸이월드 기본 이미지가 나타난다.

위부터 순서대로

→ 유저 이름, github, blog, 인사말

→ 미니홈피 이름, 배경/박스/메뉴 색상 customizing

  • technical comment user DB에 새로운 변수를 만들어 저장하고, 페이지를 렌더링할 때마다 저장된 hexaCode를 가지고 CSS에 반영했다. 이것 또한 작성하지 않으면 싸이월드 기본 색상으로 나타난다. 수정 후 변경된 색상을 바로 반영하려면 useEffect를 써야 했다. 설정하지 않으면 매번 새로고침을 통해 페이지를 다시 렌더링해야 했다. 배경 색상 같은 경우, body 컴포넌트에 직접 적용해야 해서 박스 색상, 메뉴 색상과 달라 조금 어려웠다. 하지만 이것은 프론트엔드 개발자의 기본 지식…!

→ 메뉴 글자색 자동 변경

Untitled

백엔드 코치님께서 오피스아워 때 제안한 기능인데, 바로 적용할 수 있어 기뻤다. 이 현상을 발견할 수 있게 해 준 나의 친구 ㅎㅈ이에게 감사합니다.

  • technical comment 적용하면서 함수를 살펴보니 저장된 메뉴 색상 hexaCode를 받아와서 흰 글자를 적용할지, 까만 글자를 적용할지 리턴하는 방식이다.

❷ 파도타기

네트워크: 네트워크 페이지로 이동

유저 이름 (미니홈피 이름): 다른 사람의 미니홈피로 이동

Untitled

디자인을 싸이월드로 결정하고 나서 가장 구현하고 싶었던 건데, 막판에 시간이 남아 할 수 있었다!! 2주 내내 노래를 불렀는데 귀에 딱지 앉았을 지윤 님께 감사….

  • technical comment 네트워크 페이지 같은 경우는 기존에 구현되어 있었고, 다른 사람의 미니홈피로 이동하는 것은 network 페이지에서 users 를 활용해 usercard를 렌더링하는 방식에서 아이디어를 얻었다. 가장 먼저, map 함수로 토글에 user 이름을 렌더링 하고, user 이름을 가지고 같은 객체의 homeName을 가지고 추가한 후에, db에 저장된 유저의 고유 id를 받아 연결되는 코드를 구현했다. 페이지를 빠르게 이동할 경우에 렌더링 하는 데 시간이 걸리는 탓에 가끔 오류가 나기도 했는데, 이것은 코치님과 함께 ? 구문을 써서 해결했다. 에러 처리의 중요성을 깨달았던 기능이었다.

❸ 컴포넌트 추가

→ 이름, 기간 등 추가

→ 필수로 들어가야 하는 필드와 기간 validation

→ 추가/편집/삭제/확인/취소 버튼, 카드 디자인 수정

→ 날짜 선택 시 React DatePicker 활용

컴포넌트 추가 화면

Untitled

추가, 편집 기능은 제공된 코드에 있었고, 화면 레이아웃과 validation에 집중했다. 유효한 값이 들어오는지 확인하고 맞지 않다면 백엔드에 Api 요청을 넣지 않고 요청 함수 자체를 끝내는 방식으로 구현했다. 이는 수정하는 과정에서도 동일하게 적용된다.

Untitled

필수값을 입력하지 않았을 때

Untitled

시작 날짜가 종료 날짜보다 늦을 때

Untitled

종료 날짜를 입력하지 않았을 때

Untitled

미래 날짜를 입력했을 때

  • technical comment 캡처를 하다 보니 날짜 validation만 보여 주고 있는데, DB 상에서 required = True 인 값들은 모두 validation 처리를 해서 Api 요청 전 확인을 했다. 프론트엔드에서 함수를 짤 때, 조건에 맞지 않는 값이 있다면 백엔드에 요청을 아예 보내지 않는 방식으로 만들어서 백엔드 팀원분들이 에러가 나오지 않아 당황했던 일이 있었다. ㅋㅋㅋㅋ 그리고, 날짜를 선택할 때 DatePicker를 사용했는데 특정 일자를 선택하면 하루 일찍 나오는 현상이 발생해서 검색해보니 DatePicker가 반환하는 날짜값의 기준시가 한국 시간이 아니라는 해답을 얻었다…. convertTime 이라는 함수를 만들어서 한국 시간으로 바꾸는 코드도 넣었다.

❹ 컴포넌트 편집/삭제

→ 기존에 작성된 컴포넌트 내용 편집

→ 삭제 기능 구현

→ 삭제 버튼 클릭 시 ‘정말로 삭제하시겠습니까?’ modal 팝업

Career Card

Untitled

**********편집 폼**********

Untitled

편집 버튼을 누르면 수정창이 나오는데, 추가할 때와는 다르게 기존에 입력된 값을 볼 수 있다.

******************삭제 confirm******************

Untitled

React의 Modal component를 활용했다. alert 창으로도 할 수 있겠지? 여기서 확인 버튼을 눌러야 Api 요청이 들어간다.

우리가 처음으로 구현한 추가 기능으로, 만들었을 때 팀원들과 굉장히 좋아했던 기억이 난다.

  • technical comment 여기에서도 삭제 버튼을 눌렀을 때, 삭제하고 싶은 카드 하나만 삭제되는 게 아니라 카드 전체가 삭제되어서 당황했다. 새로고침을 해서 페이지를 새로 렌더링해야 남은 카드들을 볼 수 있었다. 이것도 React의 useEffect를 활용하면 해결되는 일이었다!

❺ Navigator

→ 각 버튼 클릭 시 해당 컴포넌트로 스크롤 이동

Untitled

우리가 다른 레퍼런스를 보며 가장 구현하고 싶어 했던 기능이다. 포트폴리오에 담은 내용이 많아지면, 페이지를 분리하거나 원하는 곳으로 편하게 이동하는 수단이 필요했다.

  • technical comment 이 기능을 구현하면서 지윤 님이 엄청 고생했다!! 처음에는 방명록 페이지에 가면 홈을 누른 후에 경력, 학력 같은 컴포넌트로 이동할 수 있게 만들었다. 홈 이외에 다른 컴포넌트의 navigator는 disabled 상태로 남겼다. 코치님의 도움을 받아 언제 어디서든 원하는 컴포넌트로 이동할 수 있도록 코드를 수정했다.

ღ GuestBook

주요 기능

→ 방명록 작성, 삭제

삭제는 작성자, 미니홈피 주인만 가능

→ 방명록 작성자의 이름을 누르면 작성자의 홈페이지로 이동

******************나의 방명록******************

Untitled

미니룸, 일촌평과 더불어 싸이월드의 정체성이라고 할 수 있는 방명록을 구현했다.

방명록은 로그인한 사람이라면 누구든지 작성할 수 있고, 내 블로그에서는 방명록은 모든 글을 삭제할 수 있다. 삭제 권한을 작성자와 포트폴리오 주인에게 주었다.

  • technical comment
    • DB 및 페이지 생성 receiverId, authorId, content, timeStamp 를 담은 배열을 만들었다. createdAt과 updatedAt 두 종류의 타임 스탬프를 만들어서 마지막으로 수정한 날짜까지 보여 주려고 했으나, 우리는 수정은 구현하지 않고 삭제만 구현했기 때문에 createdAt만 활용했다.
    • guestBookCard 작성자의 프로필 사진, 이름과 작성 일시, 삭제 버튼을 넣었다. 방명록을 작성할 때 DB에 authorName도 저장해 뒀기 때문에 작성자의 작성 당시 이름이 보여서 이름을 바꿔도 이전의 이름으로 보인다. 다만, 사진은 authorId로 그 작성자의 user 객체에 접근하여 이미지를 가져오는 것으로 변경되면 방명록에 보이는 그림도 함께 바뀐다. 내 기억에 싸이월드는 이전의 미니미가 그대로 남았던 것 같은데, 만약 원한다면 user의 picture도 함께 서버에 저장하면 유지될 것 같다! 작성자의 이름을 누르면 그 사람의 미니홈피로 이동한다. authorId를 활용해서 라우팅 했다.
    • 삭제 버튼 기존에 본인의 포트폴리오를 편집하는 것과 다르게, 쓴 사람/받는 사람 두 가지 권한이 주어지므로, Api 요청도 두 경우로 나눠서 진행했다. Api 명세서에 따르면, 요청 url이 마지막 부분에만 다르게 나타나서 author 권한일 경우, receiver 권한일 경우를 나눠서 구현했다. Untitled 지윤 님이 isEditable 과 같은 isAuthor 를 만들어 줘서 이를 활용해서 Api 요청 링크를 만들었다. isEditable은 본인의 포트폴리오를 수정할 수 있는 권한이기에 receiver 권한이며, isAuthor는 접속한 user.id === authorId 인 경우 Truthy를 리턴한다. 또한, 모든 삭제 버튼에는 정말 삭제하시겠습니까? Modal이 나온다.
    • guestBooks 렌더링 → 기존 경력, 학력 같은 컴포넌트를 렌더링할 때 porfolioOwner.id를 가지고 그 사람의 이력들을 렌더링 했는데, 여기서는 미니홈피 주인id === receiverId 인 content를 렌더링 하면, 받는 사람이 미니홈피 주인인 방명록들을 가져올 수 있다.

******************방명록 쓰기******************

Untitled

Untitled

확인 버튼을 누르면 Api.post 요청이 들어간다. 여기서 author, receiver와 더불어 내용, 작성 시간 등이 DB에 저장된다.

****************남의 방명록****************

Untitled

내가 쓴 글에만 삭제 버튼이 나온다. isAuthor || isEditable 인 경우에만 삭제 버튼이 보이도록 구현했다.

ღ Network

주요 기능

→ 사용자 프로필 카드 모아보기

→ 타 사용자의 깃헙, 블로그, 포트폴리오로 이동

Untitled

파도타기의 네트워크 버튼을 누르면 네트워크 화면으로 이동할 수 있다. 이 화면도 싸이월드틱하게 만들 수 있다면 좋았겠지만… 두뇌 풀가동 및 시간 부족 이슈로 인해 반응형과 스크롤 구현 정도로 가독성을 챙겼다.

Untitled

테스트 계정 왕창 만들었음. 근데 누가 썼을까? 가짜 데이터로 경력과 학력사항 등등 넣기가 제일 재미있었다.


백투더퓨처 Tech Summary

********기본 MVP에서 추가한 기능********

  • 방명록 기능: 개인 페이지에서 누구나 글을 작성할 수 있는 공간, 삭제 기능 추가
  • 내비게이터로 원하는 포트폴리오 요소로 이동할 수 있는 스크롤
  • 파도타기 기능: 네트워크 페이지로 이동과 사용자 이름 클릭 시 그 사람의 포트폴리오로 이동

개선한 기능

  • 포트폴리오에 경력, 사용 기술 섹션 추가
  • 포트폴리오 이력 삭제 기능 추가
  • 유효하지 않은 정보에 대한 validation 프론트&백엔드에서 모두 구현
  • 웹 화면 구성과 디자인 변경, 사용자 친화적 기능 개선
  • 유저가 화면 색상을 선택할 수 있도록 배경, 박스, 메뉴 색상 customizing
  • 메뉴탭 색상 변경 시 자동 색대비 기능
  • 미니홈피 이름 추가

  • 개인 프로필 사진 추가
  • 사용자의 github, blog 추가, 아이쾬 클릭 시 이동

더 추가하고 싶은 기능

  • 네트워크 페이지 디자인 개선
  • github, blog 링크는 계정만 입력하고, 클릭 시 페이지 이동
  • 사용자 좋아요(치얼업) 기능
  • 사용자 간 쪽지 보내기
  • 방명록/네트워크 페이지 페이지네이션
  • 방명록 비밀글 기능
  • 방명록 댓글 남기기
  • 방명록 수정 기능

Personal Review

디테일하게 기획하기

기본 기능을 구현하는 게 우선이었어서 처음에는 뭘 해야 할지 감이 안 왔다…. 지체 없이 진행하기 위한 필수 조건인 것 같다. 데이터 validation, router, db 구성까지 프론트 혼자서 아무리 해도 결과물을 확인할 수 없다…. 백엔드 없는 프론트는 껍데기뿐인 코딩 팥 없는 붕어빵 민초 없는 배스킨라빈스이다….

개발을 진행하면서 디테일한 것들을 맞춰 가다 보니 대화를 수시로 할 수 있었던 점은 좋았다. 백엔드 시유 님의 시원시원한 의사 결정과 채영 님의 꼼꼼함, 지윤 님의 집념이 나에게 큰 동기 부여가 되었다. 무엇보다 다들 힘든 내색 하나 하지 않고 해야 할 일을 뚝딱 해내는 모습이 존경스러웠다.

명확한 의사소통의 중요성

어떤 과제든 팀원들과 작업할 때마다 느끼는 점이다. 이런 프로젝트를 진행하며 작업 속도나 이해도는 개인마다 다를 수밖에 없다. 다만, 프로젝트를 원활히 진행하기 위해서는 명확한 의사 표현이 필요하다. 각자가 해야 할 일을 분명하게 나누고, 어려움이 있다면 최대한 빠르게, 그리고 적극적으로 도움을 요청해야 원하는 바를 효율적으로 이뤄낼 수 있다.

**************************개발자로서 나…**************************

프로젝트를 진행하며 앞으로 개발자가 된다면 어떨지 많이 생각했다. 막연하게 할 수 있을까? 생각했던 것들을 하나씩 만들어 가면서 흥미도 느꼈고, 생각했던 것보다 나와 잘 맞을지도 모른다는 생각을 했다. 더불어 시행착오를 많이 거치다 보니 체력적으로 힘들기도 했고, 개발 특성상 매일 하려는 목표를 정해 둬도 고쳐야 할 것들이 무한증식 하다 보니 절대적으로 잠이 부족했다. 앞으로 남은 두 개의 프로젝트를 진행할 때, 또 개발자로 취직하게 된다면 체력적으로 부친다는 것을 느끼면 과감하게 잠을 자러 가야 할 결단력도 필요해 보인다.

프로젝트 회고를 하며 내가 전기 기술자로 취업하게 되더라도 친구들이 허락만 해 준다면 함께 프로젝트를 진행하고 싶다는 생각도 잠깐 들었다.

오피스 아워를 진행하면서, 그리고 최종 발표에서 코치님들께 이런저런 칭찬을 많이 들었다. 이렇게까지 퍼포먼스를 할 수 있었던 것은 팀원들 덕분이라 생각한다! 나 혼자 했다면 이틀 후 그냥 놓아 버렸을지도 모른다…. 꼼꼼하게 디자인, 반응성을 수정하는 우리를 보며 백엔드 코치님은 변태 같다… 고 해 주셨고 프론트 코치님은 유독 도전적인 팀이라 질문이 많아 가르치는 맛이 난다고 해 주셨다. ㅎㅎ 코치님들 없이 했다면 도전하지도 못했을 것들이 많은 것 같다. 새로운 것을 추가하려고 할 때, 우리가 생각한 구현 방식이 맞는 방향인지 피드백을 구한 후, 그것을 실현시켜 다음 오피스 아워에서 보여드리는 건 진짜 기분 짜릿했다. ㅎㅎ

다음 프로젝트는 데이터 분석으로 진행한다. 그때까지 알고리즘 문제 열심히 풀어야지….

Untitled

킹받은 지윤님으로 마무리


License & Reference