수리 공작소

[Digital hana 路] 5일간 진행한 개인 프로젝트 후기 본문

카테고리 없음

[Digital hana 路] 5일간 진행한 개인 프로젝트 후기

suleee 2026. 2. 17. 23:13

안녕하세요, 디지털하나로 8기 수강 중인 주인장입니다.

지난 1월 진행했던 개인 프로젝트에 대한 정리 및 회고를 해보려고 합니다!

 

프로젝트 정보

주제: 나만의 기술 블로그 만들기
기간: 1월 2일 ~ 6일 (총 5일)
인원: 1인 프로젝트

 

추후에 이를 리팩토링해서 개인 기술 블로그까지 발전시켜봐라 하는 취지로 주제가 정해졌다고 합니다. 

저도 한번 해볼까 합니다! 나중에 정말로 완성하게 된다면 이 블로그를 옮기게 되겠죠???

정말 기대가 됩니다. 정말!

 

요구사항

우선 해당 과제의 주요 요구사항은 아래와 같았습니다.

 

기능적 요구사항

  • 블로그 가입 및 로그인 (일반 회원, 관리자 회원)
  • 작성일/수정일 기반으로 잔디밭 구현 (깃헙 잔디밭과 같이)
  • 일반 회원 : 글 검색 (제목 + 내용), 좋아요, 댓글 작성/수정/삭제/답글, 작성일/수정일 모두 표시
  • 관리자: 회원 관리(목록/검색), 글관리(등록/수정/삭제), 댓글관리(작성/수정/삭제)
    *삭제시 '삭제된 댓글입니다' 표시

비기능적 요구사항

  • Next.js 16.1버전 이상 (react-compiler 사용)
  • TailwindCSS 사용 (Shadcn/ui 장려)
  • Biome 필수 적용
  • Storybook에 컴포넌트 등록
  • 빌드 기준 Lighthouse 요소 90점 이상 맞추기
  • 데이터베이스 
    • mysql8 docker-compose
    • prisma ORM 사용
    • 불용어 테이블 사용 (2글자 이상의 단어)
    • sql dump 파일 제출

이 정도가 되겠습니다!

 

개발 과정

 

디자인

디자인을 어떻게 했을까요?

처음에는 피그마 메이크를 열심히 돌렸어요...

하지만 결국 시간에 쫓겨서 디자인은 신경쓰지 않기로 했습니다.

 

그래서 별거 없어요!

다크 모드 & 라이트 모드

 

게시글 내부 (오로지 글만 작성 가능) & 관리자 페이지

 

하핫.. 대충 이렇게 생겼는데요,,, 허허 네.

 

erd 설계

 

위와 같이 설계되어있습니다! 

 

몇가지 특이(?)한 부분들은

 

1. Comment 테이블의 자기참조 구조

댓글의 대댓글 구조를 구현하기 위해 

parentComment를 가지고 있는 자기참조 구조로 설계하였습니다.

 

2. StopWord 테이블 (불용어 테이블)

게시글 검색시에 의미있는 단어로 걸리지 않도록 불용어 테이블을 만들었습니다.

단순 필터링용 단어들이 미리 저장되기 때문에 (서비스에서 추가 및 삭제하는 api없음)

키 없이 설계했습니다.

 

페이지 구조

/
├─ (Root)
│  ├─ page.tsx              → 홈
│  ├─ layout.tsx
│  └─ globals.css
│
├─ /admin
│  ├─ layout.tsx
│  ├─ page.tsx              → 관리자 메인
│  └─ /posts
│      ├─ /new
│      │   └─ page.tsx      → 게시글 작성
│      │
│      └─ /[postId]
│          └─ /edit
│              └─ page.tsx  → 게시글 수정
│
├─ /posts
│  └─ /[postId]
│      └─ page.tsx          → 게시글 상세
│
├─ /folders
│  └─ /[folderId]
│      └─ page.tsx          → 폴더별 게시글 목록  
│
├─ /mypage
│  └─ page.tsx              → 마이페이지
│
├─ /sign
│  ├─ layout.tsx
│  ├─ page.tsx              → 로그인
│  │
│  ├─ /register
│  │   └─ page.tsx          → 회원가입
│  │
│  ├─ /error
│  │   └─ page.tsx
│  │
│  └─ @viewer               → 회원가입 모달
│      ├─ default.tsx
│      └─ (.)register
│
├─ /components               → 컴포넌트 폴더
└─ /lib                      → action, prisma generated, util 등등

 

크게 홈, 관리자, 게시글, 게시글 목록, 회원가입으로 페이지를 나누었어요.

 

구현 후기

 

평가를 받고 제가 놓친 부분들을 확인할 수 있었어요.

(물론 기능 빼먹은것도 많지만... 아예 생각지 못했던 부분들이요!)

그래서 아래는 아쉬운 점을 정리해보았습니다.

 

1. 게시글 검색 full text index 미사용

 

저는 게시글 검색을 그냥... 노가다로 했습니다...

DB에서 미리 모든 게시글을 가져와서

사용자가 입력한 검색어에 맞게 filtering을 해줬는데요,

 

알고보니 이렇게 하면 성능에 치명적인 방법이고

제목, 내용과 같은 텍스트 검색을 할 때에는 full text index를 사용해야합니다!

 

예를 들어 위 ERD의 Post 테이블에서 검색에 사용되는 속성인 title과 contents에

ALTER TABLE Post
ADD FULLTEXT(title, content);

 

이런식으로 인덱스를 걸어줘야 합니다.

그럼 DB에서 텍스트를 단어 단위로 잘라서 인덱스로 관리해줍니다.

 

검색을 할 때에도 제가 사용한 방식 혹은 문자열에 포함되는지를 찾는 LIKE 문이 아닌,

MATCH … AGAINST 구문을 사용하면 된다고 해요!

 

2. Cache Component 사용하지 않음

 

Next 16버전부터 Cache Component가 도입되었습니다. 

Cache Component가 가지는 의의가 대단하다고 하는데요, 사실 제가 Next js가 처음이라

아직 막 와닿지는 않아요,,,,

그렇지만 확실한건 이를 개발하고 있는 Vercel의 의도는 

 

  • 기본은 서버에서 실행하고
  • 버튼, 상태, 클릭 같은 것만 클라이언트로 보내게 만든 것

즉, 데이터 처리와 렌더링은 서버에서 최대한 처리하고, 사용자 인터랙션에 필요한 부분만 클라이언트로 전달하여

더 빠른 웹사이트를 만드는 것입니다.

 

제가 이 cache component를 사용하지 않은 이유는 나온지 얼마되지 않아서 아직 기업에서 상용화가 많이 안 되었다고 하더라구요? 처음으로 사용해보는거니까 일단 현재 가장 많이 사용하는 방식을 써보고 싶었습니다.

그리고 사실... hydration error가 계속 나버려서 바꿀 생각을 못했어요. 솔직히. 미안합니다?

 

 

3. 날짜 렌더링 시 Hydration Error

 

hydration error란 간단히 말해서 서버에서 렌더링한 결과와 클라이언트에서 렌더링한 결과가 다를 때 나는 에러입니다.

게시글 수정일과 생성일을 띄울 때 사용하는 toLocaleDateString을 사용하는데, 서버는 UTC를 기준으로 렌더링을 하고 

클라이언트(브라우저)는 컴퓨터의 시스템 설정 시간을 기준으로 하다 보니 시간대가 맞지 않는 경우가 생깁니다.

이를 방지하기 위해선

 

1. 서버 컴포넌트에서 모든 날짜를 계산하고 이를 String으로 클라이언트에 전달하거나

2. 서버 컴포넌트 & 클라이언트 컴포넌트에서 사용할 때 timezone을 명시하거나

3. 아예 날짜 계산을 클라이언트 컴포넌트에서만 하거나

 

이렇게가 있는데요, 전 첫번째 방법을 사용했습니다.


만약에 내가...? 리팩토링을 한다면?

 

기능적으로는

  • 가장 우선은 버벅이는 기능들을 수정하고 싶어요...
  • 게시글에 사진도 넣을 수 있게 하고 싶어요!
  • 디자인 이쁘게 바꾸고 싶어요.
  • 외부 API 사용해서 뭔가 하고 싶어요 (Spotify api 써서 노래 표시라던가)

기술적으로는 위의 아쉬운 부분 고치고 코드를 더 멋지게 짜고 싶습니다!

 

 

제가 참 했으면 좋겠네요! 화이팅~~