· case-study · 2 min read

작가·구독자·관리자를 위한 웹소설 플랫폼 풀스택 개발 사례

작가가 글을 쓰고, 구독자가 읽고, 관리자가 통계를 확인하는 구조를 한 코드베이스로 설계한 웹소설 플랫폼 풀스택 개발 과정.

작가·구독자·관리자를 위한 웹소설 플랫폼 풀스택 개발 사례

한 문장 요약

작가가 글을 쓰고, 구독자가 읽고, 관리자가 전체 통계를 보는 — 세 종류의 사용자가 각자의 화면을 갖는 웹소설 플랫폼을 풀스택으로 만들었습니다. 기획부터 디자인, 백엔드, 인프라까지 한 팀에서 진행한 프로젝트입니다.

3D도 AI도 들어가지 않은 “평범한 웹 플랫폼”이지만, 평범한 플랫폼일수록 기본기가 더 중요하다는 걸 다시 확인한 프로젝트였습니다.

세 종류의 사용자를 위한 화면 구성

플랫폼 구축에서 먼저 정해야 할 것은 누가 쓰는가입니다. 이 프로젝트는 처음부터 사용자가 셋이었습니다.

  • 작가 — 소설을 쓰고, 회차를 발행하고, 자기 작품을 관리
  • 구독자 — 로그인 없이도 공개 작품을 읽을 수 있고, 가입하면 즐겨찾기
  • 관리자 — 전체 회원·소설을 관리하고, 통계 대시보드로 플랫폼 상태를 확인

이 셋이 서로 다른 페이지·권한·UX를 가지므로, 사실상 세 개의 앱을 하나의 코드베이스에서 만드는 작업이었습니다.

소설과 회차 데이터 구조

웹소설은 단순한 블로그가 아닙니다. 소설 한 편 안에 회차가 수십-수백 개 있고, 회차마다 발행 상태가 다르며, 일부는 무료, 일부는 유료가 될 수 있어야 합니다. 우리는 이렇게 모델링했습니다.

User ──────────────┐
                   │
Novel              │
 ├─ id             │
 ├─ authorId ──────┘
 ├─ title
 ├─ genre
 ├─ status (draft/public/private)
 └─ Episodes []
      ├─ id
      ├─ order
      ├─ title
      ├─ content (rich text)
      ├─ status (draft/published)
      └─ publishedAt

회차의 order 가 핵심입니다. 작가는 종종 회차 순서를 바꿉니다 — “중간에 5화를 끼워 넣고 싶습니다”. 이런 요구를 처리하려면 order가 단순한 정수가 아니라 소수점이 가능한 숫자 여야 했습니다.

4화와 5화 사이에 새 회차를 넣을 때 모든 회차의 order를 다시 매기면 DB 부하가 커집니다. 새 회차의 order를 4.5로 잡고, 충분히 누적되면 그때 한꺼번에 정수로 정규화 — 이게 정석입니다.

비로그인 읽기와 캐싱 전략

이 플랫폼의 핵심 결정 중 하나는 공개 회차는 비로그인 상태에서도 읽힌다였습니다. 이 한 줄이 백엔드 캐싱 전략을 완전히 바꿨습니다.

  • 공개 회차는 CDN 레벨에서 캐싱 — 로그인 사용자도, 비로그인 사용자도 같은 캐시 히트
  • 회차 본문에 “좋아요 수” 같은 동적 데이터를 안 박는다 → 별도 API로 비동기 로드
  • 캐시 무효화는 회차 수정·발행 시점에만 — 작가가 수정하면 그 회차 URL만 invalidate

결과적으로 트래픽의 90% 이상이 CDN에서 처리됩니다. 서버는 작가의 편집과 구독자의 “좋아요 / 댓글” 같은 인터랙션만 처리하면 됩니다.

별도 앱으로 분리한 관리자 대시보드

처음에는 관리자 화면도 같은 React 앱 안에 라우트로 두려고 했습니다. 하지만 곧 분리하는 편이 낫다는 결론이 났습니다.

  • 관리자 페이지가 무거워질수록 일반 구독자가 받는 번들도 커진다
  • 권한 분리가 코드 분리보다 약하다 (실수가 한 번이면 사고)
  • 관리자 UX 가 통계·차트 중심이라 라이브러리도 다르다

그래서 관리자 페이지는 같은 백엔드를 공유하되 별도 React 앱 + 별도 도메인으로 분리했습니다. 이 결정 덕분에 일반 페이지의 번들이 30% 이상 가벼워졌습니다.

수정과 발행의 분리

작가들이 가장 자주 요청한 기능은 의외였습니다.

“수정 중인 내용이 실수로 발행되면 안 됩니다.”

처음에는 글 = 콘텐츠 한 덩어리로 모델링했는데, 이러면 작가가 글을 쓰는 중에도 구독자가 보고 있는 상태가 됩니다. 그래서 한 회차당 draftpublished 두 개의 콘텐츠 슬롯을 두기로 했습니다.

Episode
 ├─ draftContent
 ├─ publishedContent
 ├─ status
 └─ publishAt (예약 발행 가능)

작가는 항상 draftContent를 편집하고, “발행” 버튼을 눌러야 publishedContent로 복사됩니다. 단순한 변경이지만 작가들의 안심도가 크게 올라갔습니다.

모바일이 90%인 환경의 반응형

웹소설은 사용자의 90% 이상이 모바일입니다. 이 가정이 디자인 방향을 바꿉니다.

  • 본문 폰트는 16-18px 기본 — 작아 보여도 모바일에선 충분합니다
  • 줄 간격 1.7-1.8배 — 한 시간 읽어도 눈이 안 아픈 수준
  • 다크 모드 우선 설계 — 야간 독서가 압도적으로 많음
  • 스와이프 제스처로 회차 이동 — 다음/이전 버튼은 보조

이런 작은 디테일이 누적되면 체류 시간이 30% 이상 차이 납니다. 우리는 처음에 이걸 “부수적 디테일”로 봤다가, 베타 테스트 후 “핵심 기능”으로 재분류했습니다.

프로젝트에서 얻은 것

평범한 웹 플랫폼의 어려움

3D나 AI 같은 화려한 요소가 없으면 모든 평가가 속도·안정성·작은 UX 디테일에 집중됩니다. 숨을 곳이 없습니다. 이런 프로젝트가 오히려 엔지니어링 실력을 더 분명하게 드러냅니다.

데이터 모델만큼 중요한 캐싱 전략

“공개 콘텐츠는 CDN, 동적 데이터는 별도 API” — 이 한 줄짜리 룰이 인프라 비용을 다섯 배 줄입니다. 처음부터 이걸 의식하고 모델링하면 나중에 후회가 적습니다.

관리자 페이지 분리

같은 React 앱에 두지 않는 편이 좋습니다. 권한 분리, 번들 크기, 라이브러리 차이 — 세 가지 모두 분리가 더 안전합니다.

자주 받는 질문

비슷한 콘텐츠 플랫폼을 만드는 데 얼마나 걸리나요? 역할별 화면이 셋이라면 보통 12-16주 정도가 일반적입니다. 결제·구독 모듈이 들어가면 +4주.

작가용 에디터는 어떻게 구현했나요? ProseMirror 기반의 리치 텍스트 에디터를 썼습니다. 자동 저장(2초 단위), 이미지 인라인 업로드, 다른 회차 링크 자동 생성 — 작가의 글쓰기 흐름을 끊지 않는 게 가장 중요했습니다.

확장성은 어디까지 보장하나요? 구독자 100만, 회차 100만 단위까지는 PostgreSQL + 적절한 인덱스로 충분합니다. 그 이상은 회차 본문을 별도 storage로 분리하는 식으로 확장합니다.

관리자 통계는 어떻게 보여주나요? 일별 신규 회원, 활성 작가, 인기 장르, 회차별 유입 등 15개 정도의 카드형 KPI와 시계열 차트로 구성했습니다. 모든 통계는 야간 배치로 사전 계산해 즉시 응답.


콘텐츠 플랫폼 — 웹소설, 강의, 뉴스레터, 블로그 등 — 을 처음부터 만들 계획이 있으시면 프로젝트 문의 로 사용자 역할 종류와 예상 규모를 알려주세요. 보통 첫 통화에서 데이터 모델과 캐싱 전략의 큰 그림을 같이 그려드립니다.

Hammergrid Lab은 React·Node.js 풀스택 웹 플랫폼과 3D·AI 도구를 만드는 크리에이티브 개발 스튜디오입니다.

관련 서비스

3d웹, 3dweb, 3d 컨피규레이터, 3D 제품 컨피규레이터, 3D 제품 뷰어, WebGPU, Three.js

English version: Building a Web Novel Platform from Scratch — One Codebase, Three Audiences

← 인사이트로

프로젝트 문의