Sign In

plan.md

Firebase Todo App - 코드 설계도 및 프롬프트 엔지니어링 가이드

작성일: 2025년 10월 18일
프로젝트: todo-app
목적: 처음부터 끝까지 오류 없이 Todo 앱을 구축하기 위한 완전한 가이드

📋 목차

1. 프로젝트 아키텍처 개요

1.1 기술 스택

Frontend Framework: React 19.1.1 + TypeScript 5.9.3 Build Tool: Vite 7.1.7 Routing: React Router DOM 7.9.4 Backend: Firebase (Authentication + Firestore) Internationalization: i18next + react-i18next Styling: Bootstrap 5 (via CDN) + CSS State Management: React Context API (Theme)

1.2 프로젝트 구조

todo-app/ ├── public/ # 정적 파일 │ └── vite.svg ├── src/ │ ├── components/ # React 컴포넌트 │ │ ├── AddTodoForm.tsx # Todo 추가 폼 │ │ ├── TodoItem.tsx # Todo 단일 아이템 │ │ └── TodoList.tsx # Todo 목록 컨테이너 │ ├── context/ # React Context │ │ └── ThemeContext.tsx # 다크모드 테마 관리 │ ├── firebase/ # Firebase 설정 및 서비스 │ │ ├── config.ts # Firebase 초기화 │ │ └── services.ts # Firestore CRUD 함수 │ ├── hooks/ # Custom React Hooks │ │ ├── useAuth.ts # 인증 상태 관리 │ │ └── useTodos.ts # Todo 목록 관리 │ ├── locales/ # 다국어 번역 파일 │ │ ├── en/translation.json # 영어 │ │ ├── ko/translation.json # 한국어 │ │ └── ja/translation.json # 일본어 │ ├── pages/ # 페이지 컴포넌트 │ │ ├── HomePage.tsx # 메인 페이지 (Todo 관리) │ │ └── LoginPage.tsx # 로그인/회원가입 페이지 │ ├── App.tsx # 앱 라우팅 │ ├── main.tsx # 앱 진입점 │ ├── i18n.ts # i18next 설정 │ ├── App.css # 앱 스타일 │ └── index.css # 전역 스타일 ├── firestore.rules # Firestore 보안 규칙 ├── firestore.indexes.json # Firestore 인덱스 ├── firebase.json # Firebase 설정 ├── .firebaserc # Firebase 프로젝트 ID ├── package.json # 의존성 관리 ├── tsconfig.json # TypeScript 설정 └── vite.config.ts # Vite 설정

1.3 주요 의존성

{ "dependencies": { "firebase": "^12.4.0", "i18next": "^25.6.0", "i18next-browser-languagedetector": "^8.2.0", "react": "^19.1.1", "react-dom": "^19.1.1", "react-i18next": "^16.1.0", "react-router-dom": "^7.9.4" }, "devDependencies": { "@types/node": "^24.6.0", "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "^5.0.4", "firebase-tools": "^14.20.0", "typescript": "~5.9.3", "vite": "^7.1.7" } }

2. 컴포넌트 계층 구조

App (라우팅) ├── LoginPage (비인증) │ └── 로그인/회원가입 폼 └── HomePage (인증 후) ├── Header │ ├── 제목 │ ├── 언어 선택기 │ ├── 테마 토글 버튼 │ └── 로그아웃 버튼 ├── AddTodoForm │ ├── 텍스트 입력 │ └── 추가 버튼 └── TodoList └── TodoItem[] (반복) ├── 체크박스 ├── 텍스트 └── 삭제 버튼

3. 데이터 플로우

┌─────────────────────────────────────────────────────────────┐ │ Firebase Cloud │ │ ┌────────────────┐ ┌─────────────────┐ │ │ │ Authentication │ │ Firestore DB │ │ │ │ (Auth SDK) │ │ (todos 컬렉션) │ │ │ └────────────────┘ └─────────────────┘ │ └──────────┬──────────────────────────────┬──────────────────┘ │ │ │ onAuthStateChanged │ onSnapshot (실시간) │ │ ┌──────────▼──────────────────────────────▼──────────────────┐ │ Frontend (React) │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ main.tsx (전역 AbortError 차단 시스템) │ │ │ └───────────────────────────────────────────────────────┘ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ App.tsx (React Router) │ │ │ │ ├─ useAuth() → user, loading │ │ │ │ └─ Route 분기 (인증/비인증) │ │ │ └───────────────────────────────────────────────────────┘ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ HomePage │ │ │ │ ├─ useTodos() → todos[], loading │ │ │ │ ├─ ThemeContext → theme, toggleTheme │ │ │ │ ├─ i18next → t(), i18n │ │ │ │ └─ Components: AddTodoForm, TodoList │ │ │ └───────────────────────────────────────────────────────┘ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Firebase Services (CRUD) │ │ │ │ ├─ addTodo(userId, text) │ │ │ │ ├─ getTodos(userId, callback) → unsubscribe │ │ │ │ ├─ toggleTodoCompleted(id, completed) │ │ │ │ └─ deleteTodo(id) │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘

4. 핵심 기능별 설계

4.1 인증 시스템 (Authentication)

// useAuth Hook 사용자 인증 상태를 실시간으로 추적 - onAuthStateChanged 리스너 등록 - user, loading 상태 반환 - cleanup 함수로 메모리 누수 방지 // LoginPage - 이메일/비밀번호 입력 - 회원가입: createUserWithEmailAndPassword - 로그인: signInWithEmailAndPassword - 에러 핸들링: AbortError 필터링

4.2 Todo CRUD 시스템

// Firestore 데이터 구조 interface Todo { id: string; text: string; completed: boolean; createdAt: Timestamp; userId: string; } // 보안 규칙 - allow list: 인증된 사용자만 쿼리 가능 - allow get: 자신의 문서만 읽기 가능 - allow create: 자신의 userId로만 생성 - allow update/delete: 자신의 문서만 수정/삭제

4.3 실시간 동기화 (Real-time Sync)

// useTodos Hook - getTodos() → onSnapshot 리스너 등록 - userId로 필터링된 쿼리 - createdAt 기준 내림차순 정렬 - 실시간 업데이트 자동 반영 - cleanup 시 unsubscribe() 호출

4.4 다국어 지원 (i18n)

// 지원 언어: en (영어), ko (한국어), ja (일본어) // 브라우저 언어 자동 감지 // 사용자가 수동으로 언어 변경 가능 // 모든 UI 텍스트 번역 파일로 관리

4.5 다크모드 (Theme)

// ThemeContext - localStorage에 테마 저장 - Bootstrap 5의 data-bs-theme 속성 활용 - light/dark 토글 - 앱 전체에 Context로 제공

4.6 AbortError 차단 시스템

// 3단계 방어 시스템 1. fetch 오버라이드: AbortError를 소스에서 차단 2. unhandledrejection: 놓친 에러 캐치 3. console.error 필터링: inspector.js 로그 차단

5. 프롬프트 엔지니어링 가이드

각 컴포넌트를 오류 없이 한 번에 작성하기 위한 프롬프트입니다.

Step 1: 프로젝트 초기화

React + TypeScript + Vite로 Todo 앱을 만들고 싶어요. 다음 요구사항을 충족하는 프로젝트를 생성해주세요: 1. React 19 + TypeScript 5 + Vite 7 사용 2. Firebase Authentication + Firestore 사용 3. React Router DOM으로 라우팅 4. i18next로 다국어 지원 (영어, 한국어, 일본어) 5. Bootstrap 5 스타일링 (CDN 사용) 다음 명령어로 프로젝트를 생성하고 필요한 패키지를 설치해주세요: npm create vite@latest todo-app -- --template react-ts cd todo-app npm install 그리고 다음 패키지들을 추가 설치해주세요: npm install firebase react-router-dom i18next react-i18next i18next-browser-languagedetector 개발 도구도 설치해주세요: npm install -D firebase-tools @types/node package.json을 확인하고 모든 의존성이 올바르게 설치되었는지 확인해주세요.

Step 2: Firebase 설정 파일 생성

Firebase 프로젝트를 설정하고 싶어요. 다음 파일들을 생성해주세요: 1. src/firebase/config.ts - Firebase 초기화 파일 - Vite 환경 변수 (import.meta.env.VITE_*) 사용 - getAuth, getFirestore import - 환경 변수 검증 로직 포함 2. src/firebase/services.ts - Firestore CRUD 서비스 - Todo 인터페이스 정의 (id, text, completed, createdAt, userId) - addTodo(userId, text) - 새 Todo 추가 - getTodos(userId, callback) - 실시간 리스너 (where userId, orderBy createdAt desc) - toggleTodoCompleted(docId, completed) - 완료 상태 토글 - deleteTodo(docId) - Todo 삭제 - 모든 함수에 AbortError 처리 포함 (error.name === 'AbortError'면 조용히 반환) - permission-denied 에러는 명확한 메시지로 로깅 3. firestore.rules - Firestore 보안 규칙 - todos 컬렉션에 대해: - allow list: 인증된 사용자만 - allow get: 자신의 문서만 - allow create: 자신의 userId로만 - allow update, delete: 자신의 문서만 4. firebase.json - Firebase 프로젝트 설정 - firestore rules 및 indexes 경로 지정 5. .env.local 템플릿 생성 - VITE_API_KEY, VITE_AUTH_DOMAIN, VITE_PROJECT_ID 등 환경 변수 예시 각 파일의 전체 코드를 TypeScript와 Firebase v10+ 최신 문법으로 작성해주세요. React 17+ 에서는 JSX 변환 시 `import React`가 불필요하므로 포함하지 마세요. type import는 `import type { ... }`나 `type ReactNode` 형식으로 작성해주세요.

Step 3: Custom Hooks 생성

React Custom Hooks를 만들고 싶어요. 다음 두 개의 hook을 생성해주세요: 1. src/hooks/useAuth.ts - Firebase Authentication 상태를 관리하는 hook - onAuthStateChanged 리스너 등록 - user (User | null)와 loading (boolean) 상태 반환 - useEffect cleanup에서 unsubscribe 호출 - TypeScript 타입 안전성 보장 2. src/hooks/useTodos.ts - useAuth hook 사용하여 현재 사용자 가져오기 - getTodos 서비스 사용하여 실시간 리스너 등록 - todos (Todo[])와 loading (boolean) 상태 반환 - user가 없으면 빈 배열 반환 - useEffect cleanup에서 리스너 해제 주의사항: - React 17+이므로 `import React` 불필요 - type import는 `import type { User }` 형식 사용 - dependency array 정확히 설정 - 메모리 누수 방지를 위한 cleanup 함수 필수

Step 4: Context 생성 (Theme)

다크모드를 지원하는 ThemeContext를 만들고 싶어요. src/context/ThemeContext.tsx 파일을 생성해주세요: 요구사항: 1. Theme 타입: 'light' | 'dark' 2. ThemeContextType 인터페이스: { theme: Theme, toggleTheme: () => void } 3. ThemeProvider 컴포넌트: - localStorage에서 초기 테마 로드 (기본값: 'light') - theme이 변경되면 document.documentElement.setAttribute('data-bs-theme', theme) 실행 - localStorage에 theme 저장 4. useTheme 커스텀 hook: - ThemeContext 사용 - context가 undefined면 에러 발생 주의사항: - type ReactNode는 `import { type ReactNode }` 형식으로 import - React import 불필요 - children props 타입 명시

Step 5: i18n 설정

다국어 지원 설정을 해주세요. 1. src/i18n.ts 파일 생성: - i18next, react-i18next, i18next-browser-languagedetector import - 영어(en), 한국어(ko), 일본어(ja) 번역 파일 import - LanguageDetector 사용하여 브라우저 언어 자동 감지 - fallbackLng: 'en' - interpolation.escapeValue: false 2. 번역 파일 생성: - src/locales/en/translation.json - src/locales/ko/translation.json - src/locales/ja/translation.json 번역 키: - loginTitle: "Login or Sign Up" / "로그인 또는 회원가입" / "ログインまたはサインアップ" - emailPlaceholder: "Email" / "이메일" / "Eメール" - passwordPlaceholder: "Password" / "비밀번호" / "パスワード" - loginButton, signupButton, logoutButton - todoTitle: "Todo List" / "할 일 목록" / "Todoリスト" - addTaskButton, taskPlaceholder, deleteButton - noTasks: "No tasks yet. Add one above!" - loading: "Loading..." / "로딩 중..." / "読み込み中..." - adding, deleting (로딩 상태 텍스트) 모든 파일을 JSON 형식으로 작성해주세요.

Step 6: 컴포넌트 생성 - AddTodoForm

Todo 추가 폼 컴포넌트를 만들고 싶어요. src/components/AddTodoForm.tsx 파일을 생성해주세요: 요구사항: 1. Props: { userId: string } 2. 로컬 상태: - text (string) - 입력 텍스트 - isAdding (boolean) - 추가 중 상태 3. handleSubmit 함수: - e.preventDefault() 호출 - text.trim() 검증 - isAdding이면 early return - setIsAdding(true) 설정 - try-catch-finally로 addTodo 호출 - 성공 시 setText('') 로 입력 필드 초기화 - permission-denied 에러는 명확히 로깅 - AbortError는 조용히 처리 - finally에서 setIsAdding(false) 4. UI: - form onSubmit={handleSubmit} - Bootstrap input-group 사용 - input: type="text", placeholder={t('taskPlaceholder')} - button: type="submit", {isAdding ? t('adding') : t('addTaskButton')} - isAdding 중에는 input과 button disabled 주의사항: - useTranslation() hook 사용 - React import 불필요 - async/await 사용

Step 7: 컴포넌트 생성 - TodoItem

개별 Todo 아이템 컴포넌트를 만들고 싶어요. src/components/TodoItem.tsx 파일을 생성해주세요: 요구사항: 1. Props: { todo: Todo } 2. 로컬 상태: - isToggling (boolean) - 토글 중 - isDeleting (boolean) - 삭제 중 3. handleToggle 함수: - isToggling이면 early return - setIsToggling(true) - try-catch-finally로 toggleTodoCompleted 호출 - permission-denied와 AbortError 처리 - finally에서 setIsToggling(false) 4. handleDelete 함수: - isDeleting이면 early return - setIsDeleting(true) - try-catch-finally로 deleteTodo 호출 - permission-denied와 AbortError 처리 - finally에서 setIsDeleting(false) 5. UI: - li.list-group-item - checkbox: checked={todo.completed}, onChange={handleToggle} - label: todo.completed이면 text-decoration-line-through, text-muted 클래스 - button: onClick={handleDelete}, {isDeleting ? t('deleting') : t('deleteButton')} - isToggling이나 isDeleting 중에는 모든 컨트롤 disabled 주의사항: - useTranslation() hook 사용 - async/await 사용 - 중복 클릭 방지 필수

Step 8: 컴포넌트 생성 - TodoList

Todo 목록을 렌더링하는 간단한 컨테이너 컴포넌트를 만들어주세요. src/components/TodoList.tsx 파일을 생성해주세요: 요구사항: 1. Props: { todos: Todo[] } 2. UI: - ul.list-group - todos.map()으로 TodoItem 렌더링 - key={todo.id}로 설정 주의사항: - React import 불필요 - React.FC<TodoListProps> 타입 명시 - TodoItem import

Step 9: 페이지 생성 - LoginPage

로그인/회원가입 페이지를 만들어주세요. src/pages/LoginPage.tsx 파일을 생성해주세요: 요구사항: 1. 로컬 상태: - email (string) - password (string) - error (string | null) 2. handleSignUp 함수: - React.MouseEvent<HTMLButtonElement> 타입 - e.preventDefault() 호출 - email, password 검증 - try-catch로 createUserWithEmailAndPassword 호출 - AbortError는 조용히 처리 - 다른 에러는 setError(err.message) 3. handleLogIn 함수: - handleSignUp과 유사하지만 signInWithEmailAndPassword 사용 4. UI: - Bootstrap card 레이아웃 - h2: {t('loginTitle')} - input email: placeholder={t('emailPlaceholder')} - input password: placeholder={t('passwordPlaceholder')} - button 로그인: onClick={handleLogIn}, type="submit" - button 회원가입: onClick={handleSignUp}, type="button" - error가 있으면 alert 표시 주의사항: - useTranslation() hook 사용 - React 19의 event handler 타입 사용 - async/await 사용

Step 10: 페이지 생성 - HomePage

메인 페이지 (Todo 관리)를 만들어주세요. src/pages/HomePage.tsx 파일을 생성해주세요: 요구사항: 1. Hooks: - useAuth() → user - useTodos() → todos, loading - useTheme() → theme, toggleTheme - useTranslation() → t, i18n 2. handleLogout 함수: - signOut(auth).catch() - AbortError 조용히 처리 3. handleLanguageChange 함수: - i18n.changeLanguage(lng) 호출 4. UI 구조: - card.card-header: - h1: {t('todoTitle')} - select: 언어 선택 (EN, KO, JA) - button: 테마 토글 ({theme === 'dark' ? '🌙' : '☀️'}) - button: 로그아웃 {t('logoutButton')} - card.card-body: - AddTodoForm (user가 있을 때만) - loading이면 spinner 표시 - todos.length === 0이고 loading이 아니면 {t('noTasks')} - todos.length > 0이면 TodoList 주의사항: - 모든 컴포넌트와 hook import - Bootstrap 클래스 사용 - 조건부 렌더링 정확히 구현

Step 11: App 라우팅 설정

앱의 라우팅을 설정해주세요. src/App.tsx 파일을 생성해주세요: 요구사항: 1. useAuth() hook으로 user, loading 가져오기 2. loading이면 "Loading..." 표시 3. BrowserRouter 사용: - Route "/" - user가 있으면 HomePage, 없으면 /login으로 Navigate - Route "/login" - user가 없으면 LoginPage, 있으면 /로 Navigate 4. 전체를 div.container.mt-5로 감싸기 주의사항: - React Router DOM의 Navigate 컴포넌트 사용 - 인증 상태에 따른 리다이렉트 정확히 구현 - App.css import (빈 파일이어도 됨)

Step 12: 진입점 설정 (main.tsx)

앱의 진입점 파일을 만들어주세요. 특히 AbortError 차단 시스템을 포함해야 합니다. src/main.tsx 파일을 생성해주세요: 요구사항: 1. 전역 AbortError 차단 시스템 (3단계): 1단계 - fetch 오버라이드: - const originalFetch = window.fetch 저장 - window.fetch를 새 함수로 오버라이드 - .catch()에서 AbortError 또는 code === 'cancelled' 체크 - AbortError면 new Promise(() => {}) 반환 (완전히 삼킴) - 다른 에러는 throw 2단계 - unhandledrejection 핸들러: - window.addEventListener('unhandledrejection', ...) - AbortError면 event.preventDefault() - 다른 에러는 console.error로 로깅 3단계 - console.error 필터링: - const originalConsoleError = console.error 저장 - console.error를 새 함수로 오버라이드 - 메시지에 'AbortError' 또는 'user aborted' 포함 체크 - AbortError 관련이면 return (로그 출력 안 함) - 다른 에러는 originalConsoleError로 로깅 2. React 앱 렌더링: - createRoot(document.getElementById('root')!) - StrictMode로 감싸기 - ThemeProvider로 감싸기 - App 컴포넌트 렌더링 3. 필요한 import: - React StrictMode, createRoot - './index.css', './i18n' (부수효과 import) - App, ThemeProvider 주의사항: - 3단계 AbortError 차단 시스템이 가장 중요 - 주석으로 각 단계 명확히 표시 - originalFetch, originalConsoleError 변수 사용

Step 13: CSS 파일 설정

스타일링 파일들을 설정해주세요. 1. src/index.css: - body의 background-color를 #f0f2f5로 설정 - !important 플래그 사용하여 Bootstrap 오버라이드 2. src/App.css: - 빈 파일 또는 필요한 앱별 스타일 추가 3. index.html: - Bootstrap 5 CSS CDN 추가 (<link> 태그) - Bootstrap 5 JS CDN 추가 (<script> 태그, body 끝) - 타이틀을 "Todo App"으로 변경 주의사항: - Bootstrap 5.3+ 버전 사용 - dark mode 지원을 위한 data-bs-theme 속성 지원 버전

Step 14: TypeScript 설정 검증

TypeScript 설정을 검증하고 필요하면 수정해주세요. tsconfig.app.json 파일을 확인하고: 1. verbatimModuleSyntax가 true로 설정되어 있는지 확인 2. 이 설정 때문에 type import는 반드시 `import type { ... }` 또는 inline `import { type ... }` 형식 사용 3. React 17+ JSX transform 사용 확인 (jsx: "react-jsx") 모든 .tsx 파일에서: 1. `import React`가 없는지 확인 (JSX 변환이므로 불필요) 2. type-only import는 올바른 형식인지 확인 3. 사용하지 않는 import가 없는지 확인 (TS6133 에러 방지) npm run build를 실행하여 에러가 없는지 확인해주세요.

Step 15: 환경 변수 및 Firebase 설정

Firebase 프로젝트를 설정하고 환경 변수를 구성해주세요. 1. Firebase Console에서 새 프로젝트 생성 (또는 기존 프로젝트 사용) 2. Authentication 활성화: - Email/Password 로그인 활성화 3. Firestore Database 생성: - 테스트 모드로 시작 4. Web 앱 추가하여 Firebase 설정 가져오기 5. .env.local 파일 생성: VITE_API_KEY=your-api-key VITE_AUTH_DOMAIN=your-project-id.firebaseapp.com VITE_PROJECT_ID=your-project-id VITE_STORAGE_BUCKET=your-project-id.firebasestorage.app VITE_MESSAGING_SENDER_ID=your-sender-id VITE_APP_ID=your-app-id 6. Firebase CLI로 보안 규칙 배포: npx firebase login npx firebase init firestore (기존 파일 덮어쓰지 않도록 주의) npx firebase deploy --only firestore:rules 또는 Firebase Console에서 수동으로 firestore.rules 내용을 복사하여 배포 주의사항: - .env.local은 .gitignore에 포함 - .env.example 파일을 만들어 변수 이름만 공유

Step 16: 빌드 및 테스트

프로젝트를 빌드하고 테스트해주세요. 1. 빌드 테스트: npm run build - 에러가 없어야 함 - dist 폴더 생성 확인 2. 로컬 개발 서버 실행: npm run dev - http://localhost:5173 접속 - 브라우저 콘솔에 에러가 없어야 함 3. 기능 테스트 체크리스트: - [ ] 회원가입 정상 작동 - [ ] 로그인 정상 작동 - [ ] Todo 추가 정상 작동 - [ ] Todo 체크/언체크 정상 작동 - [ ] Todo 삭제 정상 작동 - [ ] 다크모드 토글 정상 작동 - [ ] 언어 전환 정상 작동 (EN, KO, JA) - [ ] 로그아웃 정상 작동 - [ ] 브라우저 콘솔에 AbortError 없음 - [ ] 브라우저 콘솔에 permission-denied 없음 4. 보안 규칙 테스트: - [ ] 비로그인 사용자는 데이터 접근 불가 - [ ] 사용자 A는 사용자 B의 Todo 볼 수 없음 문제가 있으면 콘솔 에러를 확인하고 해당 단계로 돌아가 수정해주세요.

6. 주의사항 및 문제 해결

6.1 프롬프트 사용 시 주의사항

1. 순서대로 진행

반드시 Step 1부터 Step 16까지 순서대로 진행하세요
각 단계가 이전 단계에 의존합니다
단계를 건너뛰면 에러가 발생할 수 있습니다

2. 한 번에 하나씩

각 프롬프트를 개별적으로 AI에게 전달하세요
이전 단계가 완료되고 검증된 후 다음 단계로 진행하세요
급하게 여러 단계를 건너뛰지 마세요

3. 에러 처리 강조

모든 프롬프트에 AbortError 처리가 포함되어 있습니다
permission-denied 처리도 포함되어 있습니다
이 부분을 빠뜨리지 마세요

4. TypeScript 규칙 준수

React 17+ 이므로 import React 불필요
type import는 import type { ... } 형식
verbatimModuleSyntax 설정 준수

5. 검증 필수

각 단계 후 npm run build로 빌드 테스트
TypeScript 에러가 없는지 확인
브라우저 콘솔에서 런타임 에러 확인

6.2 일반적인 문제 해결

TypeScript 에러

TS6133: 'React' is declared but never used → import React 제거 TS1484: 'ReactNode' must be imported using type-only import → import { type ReactNode } 사용 TS2307: Cannot find module → npm install 재실행

Firebase 에러

permission-denied → Firestore 보안 규칙 확인 및 배포 AbortError in console → main.tsx의 3단계 차단 시스템 확인 Missing environment variables → .env.local 파일 생성 및 변수 설정

빌드 에러

Cannot resolve module → package.json 의존성 확인 TypeScript compilation errors → tsconfig.json 설정 확인

6.3 핵심 아키텍처 결정 사항

1.
AbortError 차단 시스템 (가장 중요!)
이 프로젝트의 가장 독특하고 중요한 부분입니다
main.tsx에서 3단계 방어 시스템 구축
Firebase의 정상적인 최적화 동작을 에러로 보이지 않게 처리
2.
Firestore 보안 규칙의 분리
allow read 대신 allow listallow get 분리
쿼리와 단일 문서 접근의 다른 권한 요구사항 반영
3.
로딩 상태 관리
모든 비동기 작업에 로딩 상태 추가
중복 클릭/제출 방지
사용자 경험 개선
4.
실시간 동기화
Firestore의 onSnapshot 사용
cleanup 함수로 메모리 누수 방지
userId 기반 필터링

7. 배포 가이드

7.1 Netlify 배포

# 1. Git 저장소 생성 git init git add . git commit -m "Initial commit: Firebase Todo App" # 2. GitHub에 푸시 git remote add origin <your-repo-url> git push -u origin main # 3. Netlify 설정 - Build command: npm run build - Publish directory: dist - Environment variables: VITE_* 변수들 설정

7.2 Firebase Hosting 배포

# 1. Firebase Hosting 초기화 npx firebase init hosting # 2. 설정 - Public directory: dist - Single-page app: Yes - GitHub Actions: No (선택) # 3. 빌드 및 배포 npm run build npx firebase deploy --only hosting

8. 학습 포인트

이 Todo 앱을 통해 배울 수 있는 것:

8.1 Firebase 통합

Authentication (이메일/비밀번호)
Firestore 실시간 데이터베이스
보안 규칙 설정

8.2 React 고급 패턴

Custom Hooks
Context API
실시간 데이터 동기화
로딩 상태 관리

8.3 국제화 (i18n)

다국어 지원
브라우저 언어 자동 감지
동적 언어 전환

8.4 테마 관리

다크모드 구현
localStorage 사용
Context로 전역 상태 관리

8.5 에러 처리

전역 에러 핸들링
Promise rejection 처리
Firebase 특정 에러 처리

8.6 TypeScript

타입 안전성
인터페이스 설계
제네릭 사용

9. 개발 순서 요약

1. 프로젝트 초기화 (Vite + React + TS) ↓ 2. Firebase 설정 (config, services, rules) ↓ 3. Custom Hooks (useAuth, useTodos) ↓ 4. Context (ThemeContext) ↓ 5. i18n 설정 (다국어) ↓ 6. Components (AddTodoForm, TodoItem, TodoList) ↓ 7. Pages (LoginPage, HomePage) ↓ 8. App 라우팅 ↓ 9. main.tsx (AbortError 차단 시스템 포함) ↓ 10. CSS 및 스타일링 ↓ 11. TypeScript 설정 검증 ↓ 12. Firebase 프로젝트 설정 ↓ 13. 빌드 및 테스트

10. 최종 체크리스트

기능 테스트

회원가입 정상 동작
로그인 정상 동작
로그아웃 정상 동작
작업 추가 정상 동작
작업 체크/언체크 정상 동작
작업 삭제 정상 동작
다크모드 토글 정상 동작
언어 전환 정상 동작

에러 테스트

로그인 시 콘솔 에러 없음
로그아웃 시 콘솔 에러 없음
작업 체크/언체크 시 콘솔 에러 없음
작업 삭제 시 콘솔 에러 없음
작업 추가 시 콘솔 에러 없음
Firebase 보안 규칙 permission-denied 에러 없음

보안 테스트

로그인하지 않은 사용자는 데이터 접근 불가
사용자 A는 사용자 B의 작업을 볼 수 없음
사용자 A는 사용자 B의 작업을 수정/삭제할 수 없음

결론

이 설계도와 프롬프트 가이드를 사용하면 처음부터 끝까지 오류 없이 Firebase Todo 앱을 만들 수 있습니다!
각 단계의 프롬프트를 순서대로 AI에게 제공하면, 체계적이고 안정적인 애플리케이션을 구축할 수 있습니다.

핵심 포인트

1.
순서대로 진행하세요
2.
검증을 빠뜨리지 마세요
3.
AbortError 차단 시스템을 정확히 구현하세요
4.
TypeScript 규칙을 준수하세요
5.
Firebase 보안 규칙을 올바르게 설정하세요
작성일: 2025년 10월 18일
작성자: conanssam
프로젝트: todo-app
버전: 1.0