08 / 28 ~ 09 / 04 기간 동안 진행했던 devnote 프로젝트를 마무리 지었다.
시연영상
구현기능
- 회원관리
- 로그인 : 유효성 검사로 입력 양식 검증, supabase에 저장된 사용자의 정보와 일치하면 로그인처리
- 회원가입 : 유효성 검사로 입력 양식 검증, supabase에 입력받은 정보를 저장
- 정보 수정 : 사용자의 기본키값인 id로 로그인 한 사용자의 정보를 입력받은 값으로 수정
- 로그아웃 : 사용자가 로그아웃하면 Supabase는 새로 고침 토큰을 취소하고 클라이언트 측에서 JWT를 삭제
- Context API로 user를 전역 상태 관리
- 게시판
- 작성 : 썸네일 이미지, 제목, 내용, 기술스택, 진행 기간 등 정보를 입력받아 DB에 저장
- 수정 : 게시글에서도 작성한 사용자의 id를 가지고 있기 때문에 사용자의 id를 비교해서 작성자만 수정하고 싶은 값 입력하고 수정가능
- 삭제 : 해당 게시글의 id로 게시글을 식별하고 DB에서 삭제
- Context API로 posts를 전역 상태 관리
- 메인(home)
- DB에 저장된 모든 게시물을 불러와서 화면에 뿌리고 게시글 하나하나를 card로 보여줌
- header와 footer가 존재하고 header는 navBar의 용도로 로그인, 회원가입이나 마이페이지로 간단하게 이동 가능
- 게시글 상세
- 해당 게시글의 id로 한개의 게시글을 가져와 DB에 저장된 column들을 레이아웃과 UI에 맞게 화면에 뿌려줌
- 이미지 클릭 시 이미지 Enlarge(크게보기) 기능
- 댓글 등록, 삭제 기능 (작성자만 삭제 가능, 공백만 입력하지 못하게 유효성 검사)
- 작성자만 게시글 삭제, 수정 버튼이 보이고 클릭 시 이동
- 마이 페이지
- 상단에 사용자의 정보를 보여주는 UI가 위치하고 아래로는 본인이 작성한 게시글을 월별로 필터링해서 보여줌
트러블슈팅(troubleshooting)
사용자 권한에 따라 보일 기능 / 보이지않는 기능 구분
- 문제: 기능 구현이 어려웠고, supabase 관련 이슈로 사용자 정보를 받아올 수 없는(null) 상황이 있었는데 null에서 id 등의 정보를 가져오려 하니 오류가 발생함
- 해결: user 정보(id 등)를 확인하기 전 user의 존재 여부를 먼저 확인
const isAuthor = user && post.author_id === user.id;
return (
{ isAuthor ? <작성자일 때만 보여야하는 요소/> : null }
)
사용자 정보 관리
- 문제: 기본적으로 제공되는 유저 정보 외에 다른 내용(프로필 이미지 등)을 추가하고 싶은데, 테이블을 따로 생성하려니 비밀번호가 그대로 노출돼서 고민
- 해결: 새로운 사용자가 추가될 때(회원가입) 테이블과 연결하는 함수 사용하여 처리
create policy "public profiles are viewed by everyone." on profile
for select using(true);
create policy "Users can insert their own profile." on profile
for insert with check(auth.uid()=id);
create function public.handle_new_user()
returns trigger as $$
begin
insert into public.profile (id, email, name, nickname, avatar_url)
values (new.id, new.email, new.raw_user_meta_data->>'name', new.raw_user_meta_data->>'nickname', new.raw_user_meta_data->>'avatar_url');
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
supabase storage 이미지 중복저장
- 문제: 수정 기능에서 사용자가 어떤 입력을 수정하는지 고려하지 않고 모든 내용을 update하면서 storage에 이미지가 중복저장됨
- 해결: 수정 기능의 경우 작성 완료 버튼을 눌렀을 때 기존 값과 비교해 변경된 값만 객체에 넣어 update 하는 방식으로 변경 → 썸네일을 수정하지 않은 경우 storage 업데이트로 url을 받아오는 과정을 거치지 않아 중복저장이 해결되고 큰 이미지의 post를 수정하는 경우 비교적 시간이 단축됨
if (prevColumns.title !== newColumns.title) updateColumns.title = newColumns.title;
if (prevColumns.tech_stack !== newColumns.tech_stack) updateColumns.tech_stack = newColumns.tech_stack.split(' ');
if (prevColumns.content !== newColumns.content) updateColumns.content = newColumns.content;
if (prevColumns.project_start_date !== newColumns.project_start_date)
updateColumns.project_start_date = newColumns.project_start_date;
if (prevColumns.project_end_date !== newColumns.project_end_date)
updateColumns.project_end_date = newColumns.project_end_date;
if (prevColumns.thumbnail !== newColumns.thumbnail)
updateColumns.thumbnail_url = await getImageURL(newColumns.thumbnail, 'thumbnails');
const { error: tableError } = await supabase.from('DEV_POSTS').update(updateColumns).eq('post_id', id).select();
소감
좋았던 점
1. 프로젝트 기간 중 매일매일 데일리 스크럼을 진행해서 팀원들의 기분이나 전날에 한 일, 오늘 할 일, 공유할 이슈 등을 이야기했던 점이 좋았다.
2. github PR 템플릿을 만들어서 사용했던 점
3. commit 규칙을 정해서 어떤 commit인지 쉽게 알아볼 수 있었던 점
4. 팀원간의 소통이 원활하여 이슈 공유가 잘 되었고, 서로 어려운 부분이 있을 때, 물어보고 알려주며 진행했던 점
어려웠던 점
- supabase에서 기본 제공하는 auth.users테이블에 추가가 있을 때, 직접 생성한 테이블인 public.porfile에도 추가가 될 수 있게 함수와 트리거를 설정하는 부분이 어려웠다.
- 페이지나 컴포넌트가 많아져서 폴더 구조를 효율성 있게 짜야한다는 점이 어려웠다.
- 사용자 인증 상태에 따라 접근을 제한하는 라우팅 기법이 어려웠다.
- 장애가 발생 했을 때, 해당 API 요청의 반환값을 확인하거나 에러 코드를 해석하고 디버깅하는 작업이 어려웠다.
아쉬운 점
- DB 테이블에서 관계나 제약 조건을 설정하는 등 테이블 구축이 미숙했던 점이 아쉽다.
- memoization이나 useEffect 등 성능 개선을 위한 작업을 하지 못한 점이 아쉽다.
- 무한스크롤이나 페이지네이션 기능을 구현하지 못한 점이 아쉽다.
느낀점
상태 관리의 중요성:
게시판 기능에서는 게시글 목록, 사용자, 댓글 등 다양한 상태를 관리했다.
이 과정에서 리액트의 useState, useEffect와 같은 훅이 큰 도움이 되었고, Redux와 같은 상태 관리 라이브러리의 필요성도 느꼈다.
비동기 데이터 처리:
서버와의 통신이 필요한 CRUD 작업을 처리하면서, 비동기 처리의 중요성을 깨달았다.
UI/UX 고려:
사용자 경험을 향상시키기 위해 게시글 작성 후 자동으로 목록에 반영되거나, 로딩 스피너를 활용해 사용자에게 명확한 피드백을 제공하는 등 UI/UX 측면에서도 많은 고민이 필요했다.
테스트의 중요성:
작성된 코드가 의도한 대로 동작하는지, 다수의 input을 제어하고 확인하기 위해 console 등 여러 방법으로 테스트가 필요한 부분이 많았고, 이로 인해 테스트의 중요성을 깨달았다.
github : https://github.com/jjjangsh/dev-note
'팀프로젝트' 카테고리의 다른 글
food compass 프로젝트 - 최종 (7) | 2024.09.23 |
---|---|
food compass 프로젝트 트러블 슈팅 (0) | 2024.09.20 |
devnote 프로젝트 - 3 (0) | 2024.09.03 |
devnote 프로젝트 - 2 (0) | 2024.08.30 |
devnote 프로젝트 - 1 (4) | 2024.08.29 |