콘텐츠로 이동

실전 프로젝트 — 기획과 설계

이 장의 목표

지금까지 배운 것들을 하나로 엮어 실제 프로젝트를 만드는 과정을 경험합니다.

3장: SDD  (무엇을 만들 것인가)
4장: SRS  (어떤 기능이 필요한가)
5장: DB 설계 (데이터를 어떻게 구조화할까)
...
이제: 처음부터 끝까지 한 번 더, 실제로 만들어 봅니다

이 장에서 만들 서비스: 링크 북마크 앱

핵심 기능:
- 링크(URL)를 저장하고 관리한다
- 태그로 분류할 수 있다
- 검색할 수 있다
- 여러 사용자가 독립적으로 사용할 수 있다

1단계: 서비스 정의

누가 사용하는가? (사용자)

주 사용자: 나중에 읽으려고 링크를 저장하는 사람
사용 맥락: 브라우저에서 흥미로운 글/영상/도구를 발견했을 때

어떤 문제를 해결하는가?

문제:  "나중에 읽어야지" 하고 저장한 링크를 다시 찾기 어렵다
해결:  제목, 태그, 검색으로 쉽게 찾을 수 있게 관리한다

핵심 기능 (MVP)

MVP(Minimum Viable Product) — 가장 핵심적인 기능만 먼저 만든다.

MVP에 포함:
  ✅ 회원가입 / 로그인
  ✅ 링크 추가 (URL, 제목, 메모)
  ✅ 링크 목록 조회
  ✅ 링크 삭제

MVP 이후:
  ⬜ 태그 기능
  ⬜ 검색
  ⬜ 즐겨찾기
  ⬜ 링크 미리보기 (og:title 자동 수집)

2단계: 요구사항 정의 (SRS)

기능 요구사항

FR-01: 사용자는 이메일과 비밀번호로 회원가입할 수 있다.
FR-02: 이미 사용 중인 이메일로 가입을 시도하면 오류를 반환한다.
FR-03: 로그인 성공 시 JWT 토큰을 반환한다.

FR-04: 로그인한 사용자는 링크를 추가할 수 있다.
FR-05: 링크 추가 시 URL은 필수, 제목과 메모는 선택이다.
FR-06: URL 형식이 올바르지 않으면 오류를 반환한다.

FR-07: 사용자는 자신의 링크 목록을 조회할 수 있다.
FR-08: 다른 사용자의 링크는 조회할 수 없다.

FR-09: 사용자는 자신의 링크를 삭제할 수 있다.
FR-10: 다른 사용자의 링크는 삭제할 수 없다. (403)

비기능 요구사항

NFR-01: 목록 조회 응답 시간 200ms 이하
NFR-02: 비밀번호는 bcrypt로 해싱하여 저장
NFR-03: 모든 API는 HTTPS로만 접근 가능 (운영 환경)
NFR-04: 인증 없이 접근 시 401 반환

3단계: API 설계

엔드포인트 목록

메서드 URL 설명 인증
POST /auth/signup 회원가입 불필요
POST /auth/login 로그인 불필요
GET /bookmarks 내 링크 목록 필요
POST /bookmarks 링크 추가 필요
GET /bookmarks/{id} 링크 단건 조회 필요
PATCH /bookmarks/{id} 링크 수정 필요
DELETE /bookmarks/{id} 링크 삭제 필요

요청/응답 형식

POST /bookmarks
Request:
{
  "url": "https://example.com/article",
  "title": "흥미로운 글",  (선택)
  "memo": "나중에 정독할 것"  (선택)
}

Response 201:
{
  "id": 7,
  "url": "https://example.com/article",
  "title": "흥미로운 글",
  "memo": "나중에 정독할 것",
  "created_at": "2026-05-23T10:00:00"
}

4단계: 데이터베이스 설계

ER 다이어그램

users
  id          INTEGER PK
  email       TEXT UNIQUE NOT NULL
  password    TEXT NOT NULL
  name        TEXT NOT NULL
  created_at  TEXT DEFAULT (datetime('now'))

bookmarks
  id          INTEGER PK
  user_id     INTEGER FK → users.id
  url         TEXT NOT NULL
  title       TEXT
  memo        TEXT
  created_at  TEXT DEFAULT (datetime('now'))

관계

users (1) ──────────── (N) bookmarks
한 사용자는 여러 북마크를 가질 수 있다
북마크는 반드시 한 사용자에게 속한다

DDL

CREATE TABLE users (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    email      TEXT    UNIQUE NOT NULL,
    password   TEXT    NOT NULL,
    name       TEXT    NOT NULL,
    created_at TEXT    DEFAULT (datetime('now'))
);

CREATE TABLE bookmarks (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id    INTEGER NOT NULL REFERENCES users(id),
    url        TEXT    NOT NULL,
    title      TEXT,
    memo       TEXT,
    created_at TEXT    DEFAULT (datetime('now'))
);

CREATE INDEX idx_bookmarks_user_id ON bookmarks(user_id);

5단계: 파일 구조 설계

bookmark-app/
├── backend/
│   ├── main.py          ← FastAPI 앱, 라우터
│   ├── database.py      ← DB 연결, 초기화
│   ├── auth.py          ← 인증 유틸리티
│   ├── requirements.txt
│   ├── Dockerfile
│   └── .env.example     ← 환경 변수 예시 (실제 값 없이)
│
├── frontend/
│   ├── index.html       ← 메인 화면 (목록)
│   ├── login.html       ← 로그인/회원가입
│   ├── style.css
│   └── app.js
│
└── docker-compose.yml

6단계: 개발 순서 계획

1단계: 백엔드 기반 구축
  □ database.py: 테이블 생성
  □ auth.py: 해싱, JWT 유틸리티
  □ main.py: FastAPI 앱 초기화

2단계: 인증 API
  □ POST /auth/signup
  □ POST /auth/login
  □ get_current_user 의존성

3단계: 북마크 CRUD API
  □ GET /bookmarks
  □ POST /bookmarks
  □ GET /bookmarks/{id}
  □ PATCH /bookmarks/{id}
  □ DELETE /bookmarks/{id}

4단계: 테스트
  □ auth 테스트
  □ CRUD 테스트
  □ 인증 필요 엔드포인트 테스트

5단계: 프론트엔드
  □ 로그인/회원가입 페이지
  □ 북마크 목록 페이지
  □ 추가/삭제 기능

6단계: 배포
  □ Dockerfile 작성
  □ 환경 변수 설정
  □ Railway 배포

7단계: 스프린트 계획

큰 작업을 짧은 주기(스프린트)로 나눕니다.

스프린트 1 (1일차): 백엔드 뼈대 + 인증 API
  → 목표: Postman/docs로 회원가입, 로그인 성공

스프린트 2 (2일차): 북마크 CRUD API + 테스트
  → 목표: 모든 API 테스트 통과

스프린트 3 (3일차): 프론트엔드
  → 목표: 브라우저에서 전체 흐름 동작

스프린트 4 (4일차): 배포
  → 목표: 실제 URL로 서비스 접근 가능

8단계: 화면 설계 (와이어프레임)

[로그인 페이지]
┌─────────────────────────────┐
│        Bookmark App         │
│                             │
│  이메일  [____________]     │
│  비밀번호 [____________]    │
│                             │
│  [    로그인    ]           │
│  아직 계정이 없으신가요? 가입│
└─────────────────────────────┘

[메인 페이지 — 북마크 목록]
┌─────────────────────────────┐
│ Bookmark App    [로그아웃]  │
├─────────────────────────────┤
│ URL  [___________________]  │
│ 제목 [___________________]  │
│ 메모 [___________________]  │
│              [  추가  ]     │
├─────────────────────────────┤
│ 흥미로운 글                 │
│ https://example.com  [삭제] │
│ ─────────────────────────── │
│ FastAPI 공식 문서           │
│ https://fastapi.tiangolo... │
└─────────────────────────────┘

실습 미션

미션 1: 요구사항 작성

자신만의 서비스를 정의하고 (Todo, 메모장, 일기장, 운동 기록 등):
1. 핵심 사용자와 해결하는 문제를 한 문장으로 쓰세요.
2. MVP 기능 목록을 5개 이내로 정리하세요.
3. MVP 이후 추가할 기능을 별도로 나열하세요.

미션 2: API 설계

정의한 서비스의 API를 설계하세요:
- 엔드포인트 목록 (메서드, URL, 설명, 인증 여부)
- 주요 요청/응답 JSON 형식 2개 이상

미션 3: DB 설계

필요한 테이블을 설계하고:
1. ER 다이어그램(텍스트 형식)을 그리세요.
2. CREATE TABLE SQL을 작성하세요.
3. 필요한 인덱스를 추가하세요.

미션 4: 개발 순서 계획

전체 개발을 단계로 나누고,
각 단계의 완료 기준("언제 이 단계가 끝났다고 볼 수 있는가")을 명시하세요.

핵심 요약

단계 내용
서비스 정의 누가, 어떤 문제를, 어떻게 해결하는가
MVP 핵심 기능만 먼저 — 나머지는 나중에
요구사항 기능(FR)과 비기능(NFR)으로 구분
API 설계 엔드포인트, 요청/응답 형식
DB 설계 테이블, 관계, 인덱스
개발 순서 의존관계에 따라 순서 정하기

만들기 전에 설계하고,
설계하기 전에 "무엇을 왜 만드는가"를 명확히 하세요.