프로젝트 기획 및 설계
온라인 북스토어의 사용자·문제·MVP를 정의하고 기술 스택, 화면·API 경계, 도서·주문 데이터 모델을 설계합니다.
이 장에서는 앞선 챕터에서 학습한 Next.js 핵심 개념과 고급 주제를 종합해, 실제 웹 애플리케이션을 기획하고 설계하는 과정을 다룹니다.
이론 정리를 넘어 프로젝트 시작 방식, 구조화 방법, 기술 스택 선택, 기능 구현 순서를 실전 기준으로 안내합니다.
이번 절에서는 프로젝트 기획 및 설계에 초점을 맞춰 아이디어 구체화, 요구사항 정의, 기술 스택 선정, 아키텍처 설계, 데이터 모델링까지의 흐름을 정리합니다.
프로젝트 아이디어 구체화 및 목표 설정
프로젝트 시작 단계에서는 아이디어와 목표를 명확히 해야 합니다.
어떤 종류의 애플리케이션을 만들지, 누가 사용할지, 어떤 문제를 해결할지 먼저 정리합니다.
아이디어 도출 및 선정
- 관심 분야 탐색: 자신이 관심 있거나 잘 아는 분야에서 아이디어를 찾습니다. (예: 독서 기록 앱, 재료 관리 앱, 스터디 그룹 매칭 서비스, 간단한 이커머스 스토어)
- 문제점 인식: 일상생활이나 업무에서 불편함을 느꼈던 점, 개선이 필요하다고 생각하는 점을 찾아봅니다.
- 기존 서비스 분석: 유사한 기존 서비스가 있다면, 그들의 장단점을 분석하고 차별화될 수 있는 요소를 모색합니다.
- 실현 가능성 고려: 주어진 시간과 기술 역량 내에서 구현 가능한 아이디어를 선정합니다. 너무 거창한 아이디어보다는 작고 핵심적인 기능부터 시작하는 것이 좋습니다.
예시 프로젝트 아이디어: 간단한 온라인 북스토어 (Online Bookstore)
- 문제 정의: 사용자들이 쉽게 책을 검색하고, 상세 정보를 확인하며, 장바구니에 담아 주문할 수 있는 간단한 플랫폼이 필요하다.
- 대상 사용자: 책 구매에 관심 있는 일반 사용자.
- 핵심 가치: 사용자 친화적인 인터페이스, 빠른 검색, 간편한 구매 프로세스.
프로젝트 목표 설정 (SMART 원칙)
선정된 아이디어를 바탕으로 구체적인 목표를 설정합니다.
SMART 원칙(Specific, Measurable, Achievable, Relevant, Time-bound)을 적용하면 좋습니다.
- S (Specific): 사용자가 책을 검색하고, 상세 페이지를 보고, 장바구니에 담아 가상으로 주문할 수 있는 웹 애플리케이션 개발.
- M (Measurable): 최소 50권의 책 데이터 구축, 검색 기능 응답 시간 1초 이내, 장바구니 및 주문 프로세스 구현.
- A (Achievable): Next.js와 기본적인 웹 기술 스택(MongoDB/PostgreSQL, Route Handlers/Server Actions)만으로 구현 가능.
- R (Relevant): Next.js 학습 내용을 총체적으로 적용하며, 실제 서비스 개발 경험 습득에 기여.
- T (Time-bound): 4주 이내에 핵심 기능 개발 및 배포 완료.
요구사항 정의 및 기능 목록 작성
프로젝트 기획 및 설계에서는 요구사항, 데이터 모델, 화면 범위, 기술 선택 기준을 정리합니다.
온라인 북스토어 예시는 기능 목록을 늘리기 전에 무엇을 해결하고 어떤 산출물로 확인할지 먼저 고정한다.
| 기획 질문 | 북스토어 답 | 설계 산출물 | A 기준 |
|---|---|---|---|
| 어떤 불편을 줄이나 | 책 검색, 상세 확인, 장바구니 주문을 한 흐름으로 묶는다 | 문제 정의와 핵심 가치 | 기능보다 사용자 행동이 먼저 보임 |
| 누가 쓰나 | 책 구매 의도가 있는 일반 사용자 | 대상 사용자와 주요 시나리오 | 관리자 기능은 확장으로 분리 |
| 무엇을 먼저 만들까 | 로그인, 목록, 검색, 상세, 장바구니, 가상 주문 | MVP 범위 | 인증된 사용자별 구매 흐름이 이어지고 결제·리뷰·추천은 뒤로 밀림 |
| 어떤 제약이 있나 | 4주, 최소 50권 데이터, 1초 이내 검색 | 성공 지표와 일정 | 측정 가능한 완료 조건 존재 |
프로젝트의 목표를 달성하기 위해 필요한 기능들을 구체적으로 정의합니다.
사용자 관점에서 어떤 기능을 제공해야 하는지 상세하게 나열합니다.
핵심 기능 (MVP)
최소 기능 제품(MVP - Minimum Viable Product)은 프로젝트의 핵심 가치를 전달할 수 있는 최소한의 기능 집합입니다.
MVP를 먼저 개발하여 빠르게 피드백을 받고 점진적으로 기능을 확장합니다.
- 사용자 인증: 장바구니와 주문을 사용자별로 분리하기 위한 로그인, 로그아웃, 서버 세션 확인.
- 도서 목록 조회: 모든 도서 목록을 페이지네이션과 함께 표시.
- 도서 검색: 도서 제목, 저자 등으로 검색.
- 도서 상세 정보: 특정 도서의 상세 정보(제목, 저자, 설명, 가격, 이미지 등) 표시.
- 장바구니 기능: 도서 추가, 수량 변경, 도서 삭제.
- 주문 기능 (가상): 장바구니의 도서를 가상으로 주문 (결제 시스템 연동은 MVP에서 제외).
추가 기능 (향후 확장 고려)
MVP 이후 확장할 수 있는 기능들을 미리 구상해 봅니다.
- 사용자 리뷰 및 평점 시스템.
- 위시리스트 기능.
- 추천 도서 기능 (개인화).
- 관리자 페이지 (도서 추가/수정/삭제, 주문 관리).
- 실제 결제 시스템 연동 (Stripe, Toss Payments 등).
- 국제화 (i18n) 지원.
- 푸시 알림.
다음 다이어그램은 온라인 북스토어의 MVP와 향후 확장 기능을 분리해, 처음 구현할 사용자 흐름이 어디서 끝나는지 보여줍니다.
장바구니와 주문의 소유권이 필요하므로 인증은 선택 기능이 아니다. 리뷰나 결제 같은 부가 기능만 성공 흐름 뒤에 붙인다.
- 로그인
Auth.js 세션을 만들고 보호 경계를 통과한다.
- 탐색
목록과 검색으로 원하는 책을 좁힌다.
- 상세
격, 설명, 재고를 확인한다.
- 장바구니
세션 userId 기준으로 수량 변경과 삭제를 처리한다.
- 가상 주문
소유권을 다시 검증하고 주문 기록을 만든다.
| 분류 | 포함 기능 | 판정 기준 |
|---|---|---|
| MVP | 로그인, 목록, 검색, 상세, 사용자별 장바구니, 가상 주문 | 인증된 사용자가 자신의 장바구니로 주문까지 완료 가능 |
| 인증 확장 | 다중 공급자, 계정 설정, 권한 관리 | 기본 Auth.js 로그인과 서버 세션 경계를 만든 뒤 추가 |
| 확장 | 리뷰, 추천, 관리자, 실제 결제, i18n, 알림 | 핵심 구매 흐름을 검증한 뒤 추가 |
기술 스택 선정
Next.js를 기반으로 하지만, 백엔드, 데이터베이스, 스타일링, 배포 등 전반적인 기술 스택을 결정합니다.
프론트엔드 (Next.js 기반)
- 프레임워크: Next.js (React 기반)
- 렌더링: 정적 렌더링(정적인 정보 페이지), 동적 렌더링(검색 결과, 사용자별 장바구니), 클라이언트 컴포넌트(장바구니, 주문, 검색 입력)를 적절히 활용.
- 데이터 페칭:
fetchAPI, SWR 또는 React Query.
- 타입스크립트: 안정성과 개발 생산성 향상을 위해 TypeScript 사용.
- 스타일링:
- CSS Modules: 컴포넌트별 스코프 CSS.
- Tailwind CSS: 유틸리티 우선 CSS 프레임워크 (빠른 UI 개발).
- Styled-components / Emotion (선택 사항): 컴포넌트 기반 스타일링. (이 프로젝트에서는 Tailwind CSS를 주력으로 사용)
- 폼 관리: React Hook Form (폼 유효성 검사 및 상태 관리).
백엔드 및 API
- API 구현 방식: App Router 기준의 Route Handlers 또는 Server Actions.
- 간단한 애플리케이션이므로 별도의 백엔드 서버 없이 Next.js 서버 기능을 활용.
- 인증: Auth.js(소셜 로그인 및 세션 관리). 장바구니와 주문 Server Action은 인증된 사용자 ID를 기준으로 동작.
- 데이터베이스: NoSQL 또는 RDB
- MongoDB (NoSQL): 유연한 스키마, 빠른 개발 (Mongoose ODM).
- PostgreSQL (RDB): 관계형 데이터, 안정성 (Prisma ORM 또는 raw SQL).
- (예시 프로젝트에서는 MongoDB와 Mongoose를 선택)
배포
- 호스팅: Vercel (Next.js에 최적화된 배포 플랫폼).
- 데이터베이스 호스팅: MongoDB Atlas (클라우드 MongoDB 서비스).
아키텍처 설계
애플리케이션의 전체적인 구조와 데이터 흐름을 시각화합니다.
시스템 아키텍처 다이어그램
Next.js 프로젝트 설계에서 중요한 것은 브라우저, Vercel Edge, 앱 런타임, 서버 로직, 데이터베이스의 책임을 섞지 않는 것이다.
- Browser
목록, 검색, 장바구니 화면을 요청하고 사용자 상호작용을 만든다.
- Vercel Edge
정적 자산, CDN 캐시, ISR 결과를 먼저 반환한다.
- Next.js App
라우팅, 렌더링, 캐싱 정책, 클라이언트/서버 컴포넌트를 조정한다.
- Auth.js + Server
auth()로 로그인 경계를 세우고 문자열 userId로 장바구니·주문 권한을 검증한다.
- MongoDB Atlas
도서, 장바구니, 주문 데이터를 저장한다.
| 요청 종류 | 먼저 확인할 계층 | DB 접근 여부 | 설계 포인트 |
|---|---|---|---|
| 홈, 정적 정보 | Vercel Edge / CDN | 대부분 없음 | 캐시 가능성을 먼저 본다 |
| 도서 검색 | Next.js App + 서버 로직 | 있음 | 쿼리 파라미터와 인덱스 기준을 맞춘다 |
| 장바구니/주문 | Auth.js + Server Action | 인증 후 있음 | auth() 실패는 /login으로 보내고 userId 소유권을 서버에서 검증한다 |
- User Browser: 사용자가 웹 애플리케이션에 접근하는 클라이언트.
- Vercel CDN / Edge: 사용자의 요청을 가까운 네트워크 계층에서 받아 정적 자산, CDN 캐시, ISR 캐시 등으로 응답 가능한지 먼저 확인. 캐시로 해결되지 않거나 사용자별 처리가 필요한 요청만 앱 런타임으로 전달.
- Next.js App on Vercel: Next.js 애플리케이션의 React 컴포넌트, 정적/동적 렌더링, 캐싱 정책을 담당.
- Vercel Functions: Route Handlers 또는 Server Actions로 구현된 서버 로직. 주문 생성, 데이터 검증처럼 서버 권한이 필요한 요청을 처리.
- MongoDB Atlas: 클라우드 기반 MongoDB 데이터베이스. 도서 정보, 장바구니 데이터, 주문 정보 등을 저장.
폴더/파일 구조 설계
App Router 기반으로 프로젝트 구조를 설계합니다.
데이터 모델링
애플리케이션이 다룰 데이터의 구조를 정의합니다.
NoSQL (MongoDB)을 기준으로 예시를 들어보겠습니다.
주요 엔티티 식별
- Book: 도서 정보.
- User: Auth.js 공급자와 세션이 관리하는 사용자 식별 정보. 이 MVP는 별도
User모델을 만들지 않습니다. - CartItem: 장바구니에 담긴 도서 항목.
- Order: 주문 정보.
다음 다이어그램은 주요 엔티티가 화면 기능이 아니라 저장 책임 기준으로 어떻게 나뉘는지 정리합니다.
Book, Auth.js userId, CartItem, Order는 기능 이름이 아니라 데이터 소유권과 변경 범위를 제한하는 경계다.
- Book
도서 목록과 상세 화면의 기준 데이터. 키: isbn 또는 _id
- Auth.js userId
세션의 문자열 ID가 장바구니와 주문의 소유자를 결정. MVP: 인증 필수
- CartItem
사용자가 선택한 책과 수량을 임시 보관. 참조: userId, bookId
- Order
구매 시점의 가격과 수량을 확정 기록. 스냅샷: priceAtPurchase
| 관계 | 저장 방식 | 이유 | 실수 신호 |
|---|---|---|---|
| Auth.js -> CartItem | CartItem.userId에 문자열 ID 저장 | 사용자별 장바구니와 수정 권한 조회 | 임의 userId를 입력값에서 신뢰 |
| Book -> CartItem | CartItem.bookId 참조 | 책 정보 변경과 수량 변경 분리 | 책 제목과 가격을 장바구니마다 복사 |
| Book -> Order.items | bookId와 priceAtPurchase 함께 저장 | 주문 후 가격 변경을 이력과 분리 | 주문 총액을 매번 현재 가격으로 재계산 |
스키마 정의 (MongoDB/Mongoose 예시)
각 스키마는 폴더 구조에서 정한 models 파일에 하나씩 분리합니다.
다음 Book 모델은 그대로 복사할 수 있는 예시이며, CartItem과 Order 모델은 다음 절에서 같은 방식으로 구현합니다.
import mongoose, { Schema, type Model } from 'mongoose';
// Book 스키마 정의
export interface IBook {
_id: mongoose.Types.ObjectId;
title: string;
author: string;
description: string;
price: number;
imageUrl: string;
isbn: string;
publishedDate: Date;
genre: string[];
stock: number;
}
const BookSchema = new Schema<IBook>({
title: { type: String, required: true },
author: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
imageUrl: { type: String, required: true },
isbn: { type: String, required: true, unique: true },
publishedDate: { type: Date, default: Date.now },
genre: [{ type: String }],
stock: { type: Number, default: 0 },
}, { timestamps: true });
const Book = (mongoose.models.Book as Model<IBook> | undefined)
?? mongoose.model<IBook>('Book', BookSchema);
export default Book;아래 다이어그램은 Mongoose 스키마를 필드 나열이 아니라 검증, 참조, 인덱스 의도까지 포함한 설계 점검표로 다시 압축합니다.
MongoDB는 유연하지만 프로젝트 설계 단계에서는 어떤 값이 필수이고 어떤 조회가 자주 일어나는지 명확히 적어야 한다.
| 모델 | 핵심 필드 | 검증/인덱스 | 설계 이유 |
|---|---|---|---|
| Book | title, author, price, isbn, stock | isbn unique, 검색 필드 index | 목록/검색/상세의 기준 데이터 |
| CartItem | userId(string), bookId, quantity, addedAt | quantity min 1, userId+bookId unique | Auth.js ID로 소유권을 고정하고 같은 책의 중복 행을 막음 |
| Order | userId(string), items, totalPrice, status | status enum, userId/orderDate index | 사용자별 주문과 구매 시점의 가격·상태를 이력으로 보존 |
| DB 연결 | MONGODB_URI, cached connection | env 누락 시 즉시 오류 | 서버리스 환경에서 연결 재사용과 실패 원인을 분리 |
프로젝트 기획 및 설계 단계는 실제 개발의 기초를 다지는 가장 중요한 과정입니다.
이 단계에서 충분한 시간을 투자하여 명확한 목표, 구체적인 기능, 적절한 기술 스택, 그리고 견고한 아키텍처를 정의한다면, 이후 개발 과정의 효율성과 프로젝트의 성공 가능성을 크게 높일 수 있습니다.
다음 절에서는 이 설계를 바탕으로 실제 프로젝트 환경을 설정하고 개발을 시작하는 방법을 다루겠습니다.
아래 다이어그램은 개발을 시작하기 전에 목표, 기능, 아키텍처, 데이터 모델이 서로 맞물리는지 확인하는 완료 기준입니다.
설계가 끝났다는 뜻은 문서가 길어졌다는 뜻이 아니라, 구현 순서와 실패 기준을 팀원이 같은 말로 설명할 수 있다는 뜻이다.
| 확정할 것 | 좋은 산출물 | 개발 중 흔한 실패 | 수정 방향 |
|---|---|---|---|
| 프로젝트 목표 | SMART 지표와 4주 범위 | 기능 추가가 계속 늘어남 | MVP 밖 기능을 backlog로 이동 |
| 기능 목록 | 로그인부터 주문까지 이어지는 MVP | 인증 없이 userId를 입력값으로 받음 | auth()-탐색-장바구니-주문 경계 유지 |
| 아키텍처 | 브라우저, Edge, App, API, DB 책임 분리 | 클라이언트에서 DB 권한 노출 | 서버 로직으로 검증 이동 |
| 데이터 모델 | 문자열 userId, Book, CartItem, Order 관계와 인덱스 | 소유권 또는 주문 가격 이력 소실 | Auth.js ID와 priceAtPurchase 스냅샷 저장 |
아래 다이어그램은 MVP 기능, 기술 스택, 백엔드 API, 배포 흐름을 프로젝트 설계 관점에서 묶고, 요구사항 정의, 데이터 모델링, 화면 구조, 배포 제약 순서로 최종 점검합니다.
최종 설계 요약은 구현 체크리스트가 아니라, 앞에서 내린 결정들이 서로 충돌하지 않는지 보는 압축 지도다.
- 요구사항
그인한 사용자의 책 탐색과 주문 흐름을 보호한다.
- 데이터 모델
Book은 기준 데이터, CartItem은 임시 선택, Order는 확정 이력이다.
- 화면/API
목록, 검색, 상세, 장바구니, 주문 API가 MVP 경로를 만든다.
- 배포 제약
Vercel은 앱 런타임, MongoDB Atlas는 데이터 저장소를 맡는다.
| 설계 묶음 | 확인 질문 | A 기준 |
|---|---|---|
| MVP | 로그인 경계부터 자신의 주문 완료까지 이어지는가 | Auth.js 세션과 핵심 경로가 한 번에 설명됨 |
| 기술 스택 | Next.js, MongoDB, Vercel의 책임이 분리됐나 | 클라이언트/서버/DB 경계가 명확함 |
| 데이터 | 가격, 수량, 주문 상태가 이력으로 남나 | 변경 가능한 값과 확정 값이 분리됨 |
| 리스크 | 검색 성능, DB 연결, env 누락을 점검했나 | 실패 신호와 대응 위치가 문서화됨 |