Skip to content

Ensil-dev/DogGain_Forum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

12 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿถ DogGain Forum

๊ฐœ์ด๋“ ์ •๋ณด๋ฅผ ๋‚˜๋ˆ„๋Š” ํ•ซ๋”œ ์ปค๋ฎค๋‹ˆํ‹ฐ ํฌ๋Ÿผ
์‹ค์‹œ๊ฐ„ ํ•ซ๋”œ ์ •๋ณด์™€ ์†Œ๋น„์ž ํ›„๊ธฐ, ๊ฟ€ํŒ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋ชฉํ‘œ๋กœ ์ง์ ‘ ๊ธฐํšํ•˜๊ณ  ๊ฐœ๋ฐœํ•œ ์›น ํฌ๋Ÿผ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.


๐Ÿ“š ๋ชฉ์ฐจ


๐Ÿ“ธ ๋ฐ๋ชจ ๋ฐ ๋ฐฐํฌ ๋งํฌ


๐Ÿ’ก ํ”„๋กœ์ ํŠธ ํƒ„์ƒ ๋ฐฐ๊ฒฝ

๊ธฐ์กด ํ•ซ๋”œ ๊ณต์œ ์˜ ๊ตฌ์กฐ์  ๋ฌธ์ œ์ 

๊ธฐ์กด ํ•ซ๋”œ ์ •๋ณด ๊ณต์œ ๋Š” ์ฃผ๋กœ ํŠน์ • ๋ถ„์•ผ ์ค‘์‹ฌ์˜ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ƒํ™ฉ:

  • ์˜๋ฅ˜ ์ปค๋ฎค๋‹ˆํ‹ฐ โ†’ ์˜๋ฅ˜ ๊ด€๋ จ ํ•ซ๋”œ๋งŒ ๊ณต์œ 
  • ์ „์ž๊ธฐ๊ธฐ ์ปค๋ฎค๋‹ˆํ‹ฐ โ†’ ์ „์ž์ œํ’ˆ ํ•ซ๋”œ๋งŒ ๊ณต์œ 
  • ํœด๋Œ€ํฐ ์ปค๋ฎค๋‹ˆํ‹ฐ โ†’ ํ†ต์‹  ๊ด€๋ จ ํ•ซ๋”œ๋งŒ ๊ณต์œ 

ํ•ต์‹ฌ ๋ฌธ์ œ์ :

  • ์นดํ…Œ๊ณ ๋ฆฌ ํŽธํ–ฅ: ํŠน์ • ๋ถ„์•ผ์— ๊ด€์‹ฌ ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์ด ํ•ด๋‹น ์นดํ…Œ๊ณ ๋ฆฌ ํ•ซ๋”œ๋งŒ ์ง‘์ค‘ ๊ณต์œ 
  • ์ •๋ณด ๋ถ„์‚ฐ: ๋‹ค์–‘ํ•œ ๋ถ„์•ผ์˜ ํ•ซ๋”œ์„ ์ฐพ์œผ๋ ค๋ฉด ์—ฌ๋Ÿฌ ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋Œ์•„๋‹ค๋…€์•ผ ํ•จ
  • ํ•ซ๋”œ ๋ณธ์งˆ ํฌ์„: "ํ•ซ๋”œ ์ž์ฒด"๋ณด๋‹ค๋Š” "ํ•ด๋‹น ์นดํ…Œ๊ณ ๋ฆฌ ์ œํ’ˆ"์— ๋Œ€ํ•œ ๊ด€์‹ฌ์ด ์šฐ์„ 

DogGain_Forum์ด ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•œ ํ•ต์‹ฌ ๋ฌธ์ œ

์ง„์งœ ํ•ซ๋”œ๋Ÿฌ๋“ค์„ ์œ„ํ•œ, ํ•ซ๋”œ ๊ทธ ์ž์ฒด์— ์ง‘์ค‘ํ•˜๋Š” ํ”Œ๋žซํผ์ด ์—†๋‹ค

๋ชฉํ‘œํ•œ ์ฐจ๋ณ„์ :

  • ์นดํ…Œ๊ณ ๋ฆฌ์— ์ƒ๊ด€์—†์ด ํ• ์ธ์œจ๊ณผ ๊ฐ€์„ฑ๋น„ ์ž์ฒด์— ์ง‘์ค‘
  • ์˜๋ฅ˜๋ถ€ํ„ฐ ์ „์ž๊ธฐ๊ธฐ, ์ƒํ•„ํ’ˆ๊นŒ์ง€ ๋ชจ๋“  ๋ถ„์•ผ์˜ ํ•ซ๋”œ์„ ํ•œ ๊ณณ์—์„œ
  • ํŠน์ • ๋ถ„์•ผ ์ „๋ฌธ๊ฐ€๊ฐ€ ์•„๋‹Œ ํ•ซ๋”œ ์ฐพ๊ธฐ์˜ ๋‹ฌ์ธ๋“ค์ด ๋ชจ์ด๋Š” ๊ณต๊ฐ„

ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•œ ํ•ต์‹ฌ ๊ฐ€์น˜

  1. ์‹ค์‹œ๊ฐ„์„ฑ: ํ•ซ๋”œ ์ •๋ณด๋ฅผ ์ฆ‰์‹œ ๊ณต์œ ํ•˜๊ณ  ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ
  2. ์‹ ๋ขฐ์„ฑ: ๊ตฌ๋งค ํ›„๊ธฐ์™€ ์ฃผ์˜์‚ฌํ•ญ์„ ํ†ตํ•œ ๊ฒ€์ฆ๋œ ์ •๋ณด ์ œ๊ณต
  3. ์‚ฌ์šฉ์„ฑ: ์ง๊ด€์ ์ธ UI๋กœ ๋ˆ„๊ตฌ๋‚˜ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋žซํผ

๐ŸŽฏ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ๋ฐ ์‚ฌ์šฉ์ž ์‹œ๋‚˜๋ฆฌ์˜ค

1. ํ•ซ๋”œ ์ •๋ณด ์‹ค์‹œ๊ฐ„ ๊ณต์œ 

์‚ฌ์šฉ์ž ์Šคํ† ๋ฆฌ: "๋ฐฉ๊ธˆ ๋ฐœ๊ฒฌํ•œ ์ข‹์€ ๋”œ์„ ๋น ๋ฅด๊ฒŒ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์–ด์š”"

  • ๊ฐ„ํŽธํ•œ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ (์ œ๋ชฉ 10์ž ์ด์ƒ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋กœ ํ’ˆ์งˆ ๊ด€๋ฆฌ)
  • ์‹ค์‹œ๊ฐ„ ๊ฒŒ์‹œ๊ธ€ ์—…๋ฐ์ดํŠธ
  • ์ข‹์•„์š”/๋ถ๋งˆํฌ๋กœ ์œ ์šฉํ•œ ์ •๋ณด ์ €์žฅ

2. ์Šค๋งˆํŠธ ๊ฒ€์ƒ‰ ์‹œ์Šคํ…œ

์‚ฌ์šฉ์ž ์Šคํ† ๋ฆฌ: "์›ํ•˜๋Š” ์ƒํ’ˆ์˜ ํ•ซ๋”œ ์ •๋ณด๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ๊ณ  ์‹ถ์–ด์š”"

  • ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰์œผ๋กœ ์ฆ‰์‹œ ๊ฒฐ๊ณผ ํ™•์ธ
  • ๊ฒ€์ƒ‰ ๋ชจ๋‹ฌ UI๋กœ ๋Š๊น€ ์—†๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜
  • Firestore ์ธ๋ฑ์Šค ์ตœ์ ํ™”๋กœ ๋น ๋ฅธ ๊ฒ€์ƒ‰ ์†๋„ ๊ตฌํ˜„

3. ์‚ฌ์šฉ์ž ๋งž์ถค ๊ฒฝํ—˜

์‚ฌ์šฉ์ž ์Šคํ† ๋ฆฌ: "๋‚ด ์ทจํ–ฅ์— ๋งž๋Š” ํ™˜๊ฒฝ์—์„œ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ด์šฉํ•˜๊ณ  ์‹ถ์–ด์š”"

  • Google ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ
  • ๋‹คํฌ/๋ผ์ดํŠธ ๋ชจ๋“œ ์ง€์›
  • ๊ฐœ์ธ ํ™œ๋™ ํžˆ์Šคํ† ๋ฆฌ ๊ด€๋ฆฌ

๐Ÿ›  ๊ธฐ์ˆ  ์Šคํƒ ๋ฐ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ

๊ตฌ๋ถ„ ๋‚ด์šฉ
Frontend React, React Router
Language TypeScript (JavaScript์—์„œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์™„๋ฃŒ)
State Management Redux Toolkit, React Query
State Persistence redux-persist
Styling styled-components, ThemeProvider
Custom Hook useOnClickOutside, useInfinitePosts ๋“ฑ ์ž์ฒด ๊ตฌํ˜„
Architecture FSD (Feature-Sliced Design)
Build Tool CRA โ†’ Vite
Authentication Firebase Authentication (Google Login)
Database Firebase Cloud Firestore
์ปจํ…Œ์ด๋„ˆํ™” Docker, Docker Compose, Nginx
๋ฐฐํฌ ํ™˜๊ฒฝ GitHub Pages, Docker Container

๐Ÿ›  ๊ธฐ์ˆ  ์Šคํƒ ์„ ํƒ ์ด์œ 

Frontend

  • React + TypeScript: ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ํ†ตํ•œ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ
  • Redux Toolkit: ๋ณต์žกํ•œ ์‚ฌ์šฉ์ž ์ƒํƒœ์™€ ๊ฒŒ์‹œ๋ฌผ ์ƒํƒœ์˜ ์ผ๊ด€๋œ ๊ด€๋ฆฌ
  • React Query: ์„œ๋ฒ„ ์ƒํƒœ ์บ์‹ฑ์œผ๋กœ ๋ถˆํ•„์š”ํ•œ API ํ˜ธ์ถœ ์ตœ์†Œํ™”

Backend & Database

  • Firebase: ๋น ๋ฅธ ํ”„๋กœํ† ํƒ€์ดํ•‘๊ณผ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™” ์ง€์›
  • Firestore: NoSQL์˜ ์œ ์—ฐ์„ฑ๊ณผ ์‹ค์‹œ๊ฐ„ ๋ฆฌ์Šค๋„ˆ๋ฅผ ํ†ตํ•œ ์ฆ‰์‹œ ์—…๋ฐ์ดํŠธ

๋นŒ๋“œ & ๋ฐฐํฌ

  • Vite: CRA ๋Œ€๋น„ 3๋ฐฐ ๋น ๋ฅธ ๋นŒ๋“œ ์†๋„๋กœ ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ
  • GitHub Pages: ๋ฌด๋ฃŒ ํ˜ธ์ŠคํŒ…์œผ๋กœ ๋น ๋ฅธ MVP ๊ฒ€์ฆ
  • Docker: ํ™˜๊ฒฝ ๋…๋ฆฝ์  ์‹คํ–‰๊ณผ ์ผ๊ด€๋œ ๋ฐฐํฌ ํ™˜๊ฒฝ ์ œ๊ณต

์ปจํ…Œ์ด๋„ˆํ™”

  • Docker + Nginx: ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ๊ณผ ๋™์ผํ•œ ๋ฉ€ํ‹ฐ ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ
  • Docker Compose: ๊ฐœ๋ฐœ์ž ์นœํ™”์ ์ธ ๊ฐ„ํŽธํ•œ ๋กœ์ปฌ ์‹คํ–‰ ํ™˜๊ฒฝ
  • ํ™˜๊ฒฝ ๊ฒฉ๋ฆฌ: Node.js ๋ฒ„์ „์ด๋‚˜ ์˜์กด์„ฑ ์ถฉ๋Œ ์—†๋Š” ์•ˆ์ •์  ์‹คํ–‰

๐Ÿš€ ์‹คํ–‰ ๋ฐฉ๋ฒ•

ํ•„์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ

  • Node.js 18.0 ์ด์ƒ
  • npm ๋˜๋Š” yarn

๋กœ์ปฌ ํ™˜๊ฒฝ ์„ค์ •

# 1. ์ €์žฅ์†Œ ํด๋ก 
git clone https://github.com/ensil-dev/DogGain_Forum.git
cd DogGain_Forum/forum_client
# 2. ์˜์กด์„ฑ ์„ค์น˜
npm install --legacy-peer-deps
# 3. ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰
npm start
# 4. ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ
npm run build

3. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •

# .env ํŒŒ์ผ ์ƒ์„ฑ ํ›„ Firebase ์„ค์ •, kakao api key ์ถ”๊ฐ€
VITE_apiKey=your_api_key
VITE_authDomain=your_auth_domain
VITE_projectId=your_project_id
VITE_storageBucket=your_storageBucket
VITE_messagingSenderId=your_messagingSenderId
VITE_appId=your_appId
VITE_measurementId=your_measurementId
VITE_KAKAO_JAVASCRIPT_KEY=your_KAKAO_JAVASCRIPT_KEY

๐Ÿณ Docker๋กœ ์‹คํ–‰ํ•˜๊ธฐ

Docker๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ™˜๊ฒฝ์— ๊ด€๊ณ„์—†์ด ์ผ๊ด€๋œ ์‹คํ–‰ ํ™˜๊ฒฝ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ ์‹œ๋ฎฌ๋ ˆ์ด์…˜๊ณผ ๋ฐฐํฌ ํ…Œ์ŠคํŠธ์— ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ

์‹คํ–‰ ๋ฐฉ๋ฒ•

# 1. ์ €์žฅ์†Œ ํด๋ก  ๋ฐ ์˜์กด์„ฑ ์„ค์น˜
git clone https://github.com/ensil-dev/DogGain_Forum.git
cd DogGain_Forum/forum_client
npm install

# 2. ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ • (.env ํŒŒ์ผ ์ƒ์„ฑ)
# โš ๏ธ ์ด ๋‹จ๊ณ„ ์—†์ด๋Š” Firebase ์—ฐ๊ฒฐ์ด ์‹คํŒจํ•˜์—ฌ ์•ฑ์ด ์ •์ƒ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค
# ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ • ๋ฐฉ๋ฒ•์€ ์œ„ '์‹คํ–‰ ๋ฐฉ๋ฒ•' ์„น์…˜์˜ 'ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •' ์ฐธ๊ณ 

# 3. ์›์Šคํ†ฑ ๋ฐฐํฌ ํ…Œ์ŠคํŠธ (๋นŒ๋“œ + ์‹คํ–‰)
npm run docker:test

๋‹จ๊ณ„๋ณ„ ์‹คํ–‰ (์„ ํƒ์‚ฌํ•ญ)

npm run docker:build    # Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ
npm run docker:start    # ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘ (8080 ํฌํŠธ)
npm run docker:stop     # ์ปจํ…Œ์ด๋„ˆ ์ค‘์ง€

์ ‘์† ํ™•์ธ

์‹คํ–‰ ์™„๋ฃŒ ํ›„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋‹ค์Œ ์ฃผ์†Œ๋กœ ์ ‘์†:

์ปจํ…Œ์ด๋„ˆ ๊ด€๋ฆฌ

# ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ํ™•์ธ
docker ps -f name=doggain-forum

# ์ปจํ…Œ์ด๋„ˆ ์ค‘์ง€
docker stop doggain-forum

# ์ปจํ…Œ์ด๋„ˆ ์ œ๊ฑฐ
docker rm doggain-forum

# ์ด๋ฏธ์ง€ ์ œ๊ฑฐ
docker rmi doggain-forum:latest

๋กœ๊ทธ ํ™•์ธ

# ์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ ํ™•์ธ
docker logs -f doggain-forum

๐Ÿ“ธ ์ฃผ์š” ํ™”๋ฉด ์Šคํฌ๋ฆฐ์ƒท

๊ฒŒ์‹œํŒ ๊ด€๋ จ

  • ๋ฌดํ•œ ์Šคํฌ๋กค๋กœ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ๋กœ๋”ฉ
  • ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ
  • ์ƒ์„ธ ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒยท์ˆ˜์ •ยท์‚ญ์ œ
  • ์ข‹์•„์š”
  • ๋ถ๋งˆํฌ ์„ค์ •
  • ๊ฒŒ์‹œ๊ธ€ ๊ณต์œ 
  • ์กฐํšŒ์ˆ˜ ์นด์šดํŠธ
  • ๋Œ“๊ธ€ ๋‹ฌ๊ธฐ

๊ฒ€์ƒ‰

  • ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰๊ณผ ๊ฒ€์ƒ‰ ๋ชจ๋‹ฌ UI ์ œ๊ณต

์ธ์ฆยท์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ

  • Google ๋กœ๊ทธ์ธ ๋ฐ ๋กœ๊ทธ์•„์›ƒ
  • ํ”„๋กœํ•„ ์„ค์ •(ํ”„๋กœํ•„ ์‚ฌ์ง„ ๋ณ€๊ฒฝ, ๋‹‰๋„ค์ž„ ํŽธ์ง‘)
  • ์‚ฌ์šฉ์ž ํžˆ์Šคํ† ๋ฆฌ
  • ๋ถ๋งˆํฌ ๊ด€๋ฆฌ

๊ด€๋ฆฌ์ž ๋Œ€์‹œ๋ณด๋“œ

  • ์‚ฌ์šฉ์ž ํ†ต๊ณ„ ๊ทธ๋ž˜ํ”„ / ๊ด€๋ฆฌ์ž ์ด๋ฉ”์ผ ๋“ฑ๋กยท์‚ญ์ œ / ์‚ฌ์šฉ์ž ๊ฒŒ์‹œ๊ธ€ยท๋Œ“๊ธ€ ๊ด€๋ฆฌ

ํ…Œ๋งˆ

  • ๋‹คํฌ ๋ชจ๋“œยท๋ผ์ดํŠธ ๋ชจ๋“œ ์ „ํ™˜ ํ† ๊ธ€

๐Ÿ”ง ์ฃผ์š” ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… ํžˆ์Šคํ† ๋ฆฌ

1. ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ์„ฑ๋Šฅ ์ตœ์ ํ™”

๋ฌธ์ œ: ๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰ ์‹œ ์ „์ฒด ๋ฐ์ดํ„ฐ ๋กœ๋“œ๋กœ ์ธํ•œ ์‘๋‹ต ์ง€์—ฐ ๋ฐ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ ๊ณผ๋‹ค ๋ฐœ์ƒ

์›์ธ ๋ถ„์„:

  • ์ „์ฒด ๊ฒŒ์‹œ๊ธ€์„ ๊ฐ€์ ธ์˜จ ํ›„ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•„ํ„ฐ๋งํ•˜๋Š” ๋น„ํšจ์œจ์  ๊ตฌ์กฐ
  • Firestore ๊ฒ€์ƒ‰ ์ธ๋ฑ์Šค(keywords ํ•„๋“œ) ๋ถ€์žฌ
  • ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ ์ตœ์ ํ™” ๋ฏธ์ ์šฉ

ํ•ด๊ฒฐ ๊ณผ์ •:

// Before: ์ „์ฒด ๋ฐ์ดํ„ฐ ๋กœ๋“œ ํ›„ ํด๋ผ์ด์–ธํŠธ ํ•„ํ„ฐ๋ง
const q = query(collection(db, 'posts'), orderBy('created', 'desc'));
const snap = await getDocs(q);
const posts = snap.docs.map((d) => ({ ...d.data(), id: d.id }));
return filterPostsByKeyword(posts, keyword, type).slice(0, limitCount);

// After: Firestore ์ธ๋ฑ์Šค ์ฟผ๋ฆฌ ํ™œ์šฉ
// ๋‹จ์ผ ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰
const q = query(
  collection(db, 'posts'),
  where('keywords', 'array-contains', keyword.toLowerCase()),
  orderBy('created', 'desc'),
  limit(limitCount)
);

// ๋‹ค์ค‘ ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰
const q = query(
  collection(db, 'posts'),
  where('keywords', 'array-contains-any', tokens),
  orderBy('created', 'desc'),
  limit(limitCount)
);

์„ฑ๊ณผ: ๊ฒ€์ƒ‰ ์‘๋‹ต์‹œ๊ฐ„ 70-80% ๋‹จ์ถ•, ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ 90% ๊ฐ์†Œ, ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ์ฟผ๋ฆฌ ์ตœ์ ํ™”๋กœ ํ™•์žฅ์„ฑ ๋Œ€ํญ ํ–ฅ์ƒ

2. ์กฐํšŒ์ˆ˜ ์ค‘๋ณต ์ฆ๊ฐ€ ๋ฌธ์ œ ํ•ด๊ฒฐ

๋ฌธ์ œ: ์ƒˆ๋กœ๊ณ ์นจํ•  ๋•Œ๋งˆ๋‹ค ์กฐํšŒ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š” ํ˜„์ƒ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

  • ์„ธ์…˜ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ํ™œ์šฉํ•œ ์กฐํšŒ ๊ธฐ๋ก ๊ด€๋ฆฌ
  • ๋™์ผ ์‚ฌ์šฉ์ž์˜ 24์‹œ๊ฐ„ ๋‚ด ์ค‘๋ณต ์กฐํšŒ ๋ฐฉ์ง€ ๋กœ์ง ๊ตฌํ˜„

์˜ํ–ฅ: ์ •ํ™•ํ•œ ์ธ๊ธฐ ๊ฒŒ์‹œ๊ธ€ ์ˆœ์œ„ ์ œ๊ณต์œผ๋กœ ์‚ฌ์šฉ์ž ๋งŒ์กฑ๋„ ํ–ฅ์ƒ

3. TypeScript ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

๋ฌธ์ œ: JavaScript ํ™˜๊ฒฝ์—์„œ ๋นˆ๋ฒˆํ•œ ํƒ€์ž… ๊ด€๋ จ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ „๋žต:

  1. ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ๋ถ€ํ„ฐ ์ ์ง„์  ์ ์šฉ
  2. ๊ณตํ†ต ํƒ€์ž… ์ •์˜๋ฅผ ํ†ตํ•œ ์žฌ์‚ฌ์šฉ์„ฑ ํ™•๋ณด
  3. Strict ๋ชจ๋“œ ํ™œ์„ฑํ™”๋กœ ํƒ€์ž… ์•ˆ์ „์„ฑ ๊ทน๋Œ€ํ™”

์„ฑ๊ณผ: ๊ฐœ๋ฐœ ์ค‘ ํƒ€์ž… ๊ด€๋ จ ์˜ค๋ฅ˜ ์‚ฌ์ „ ๋ฐœ๊ฒฌ, ์ฝ”๋“œ ํ’ˆ์งˆ ๋Œ€ํญ ํ–ฅ์ƒ

4. ์ƒํƒœ ๊ด€๋ฆฌ ์ตœ์ ํ™”

๋ฌธ์ œ: Redux store๊ฐ€ ๋น„๋Œ€ํ•ด์ง€๋ฉด์„œ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง ๋ฐœ์ƒ

ํ•ด๊ฒฐ:

  • React Query๋กœ ์„œ๋ฒ„ ์ƒํƒœ ๋ถ„๋ฆฌ
  • Redux๋Š” ์‚ฌ์šฉ์ž ์ธ์ฆ ์ƒํƒœ๋งŒ ๊ด€๋ฆฌํ•˜๋„๋ก ์—ญํ•  ์ถ•์†Œ
  • useMemo, useCallback ์ ์ ˆํ•œ ํ™œ์šฉ์œผ๋กœ ์„ฑ๋Šฅ ์ตœ์ ํ™”

๐Ÿ“ˆ ํ”„๋กœ์ ํŠธ ์„ฑ๊ณผ ๋ฐ ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ

์ •๋Ÿ‰์  ์„ฑ๊ณผ

  • ๊ฒ€์ƒ‰ ์†๋„: 3์ดˆ โ†’ 1์ดˆ ์ด๋‚ด (3๋ฐฐ ํ–ฅ์ƒ)
  • ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜: TypeScript ๋„์ž…์œผ๋กœ 90% ๊ฐ์†Œ
  • ๋นŒ๋“œ ์‹œ๊ฐ„: CRA โ†’ Vite ์ „ํ™˜์œผ๋กœ 70% ๋‹จ์ถ•

์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ (๊ธฐ๋Šฅ๋ณ„)

  • ๋‹คํฌ ๋ชจ๋“œ: "๋ˆˆ์˜ ํ”ผ๋กœ๊ฐ€ ์ค„์–ด๋“ค์–ด ๋” ์˜ค๋ž˜ ์‚ฌ์šฉํ•˜๊ฒŒ ๋จ"
  • ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰: "์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์–ด ํŽธ๋ฆฌํ•จ"
  • ๋ฌดํ•œ ์Šคํฌ๋กค: "ํŽ˜์ด์ง€ ์ด๋™ ์—†์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ฝ˜ํ…์ธ  ํƒ์ƒ‰ ๊ฐ€๋Šฅ"

๐ŸŽ‰ ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ๋ฐฐ์šด ์ 

๊ธฐ์ˆ ์  ํ•™์Šต

  1. ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ์ค‘์š”์„ฑ: ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์€ ๊ธฐ๋Šฅ๋ณด๋‹ค ์†๋„์— ๋” ๋ฏผ๊ฐ
  2. ์ ์ง„์  ๊ฐœ์„ : JavaScript โ†’ TypeScript ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ†ตํ•œ ์•ˆ์ „ํ•œ ์ฝ”๋“œ๋ฒ ์ด์Šค ๊ตฌ์ถ•
  3. ์ ์ ˆํ•œ ๊ธฐ์ˆ  ์„ ํƒ: Firebase์˜ ์‹ค์‹œ๊ฐ„ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•œ ๋น ๋ฅธ MVP ๊ตฌํ˜„

์„ค๊ณ„ ์ฒ ํ•™

  • ์‚ฌ์šฉ์ž ์ค‘์‹ฌ ์‚ฌ๊ณ : ๊ธฐ์ˆ ์  ์™„์„ฑ๋„๋ณด๋‹ค ์‹ค์ œ ์‚ฌ์šฉ์„ฑ ์šฐ์„ 
  • ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ: FSD ์•„ํ‚คํ…์ฒ˜๋กœ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ์‹œ ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ™•๋ณด
  • ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์˜์‚ฌ๊ฒฐ์ •: ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ์„ ํ†ตํ•œ ์ง€์†์  ๊ฐœ์„ 

๐Ÿ”„ ํ–ฅํ›„ ๋ฐœ์ „ ๋ฐฉํ–ฅ

๋‹จ๊ธฐ ๋ชฉํ‘œ (1๊ฐœ์›”)

  • PWA ์ง€์›์œผ๋กœ ๋ชจ๋ฐ”์ผ ์•ฑ ๊ฐ™์€ ๊ฒฝํ—˜ ์ œ๊ณต
  • ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ ์‹œ์Šคํ…œ ๊ตฌํ˜„
  • Vitest ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ

์žฅ๊ธฐ ๋ชฉํ‘œ (3๊ฐœ์›”)

  • AI ๊ธฐ๋ฐ˜ ๊ฐœ์ธ ๋งž์ถค ํ•ซ๋”œ ์ถ”์ฒœ
  • ์ƒํ’ˆ ๊ฐ€๊ฒฉ ๋ณ€๋™ ์•Œ๋ฆผ ๊ธฐ๋Šฅ
  • ์†Œ์…œ ๋กœ๊ทธ์ธ ํ™•์žฅ (์นด์นด์˜ค, ๋„ค์ด๋ฒ„)

๐Ÿ‘จโ€๐Ÿ’ป ๊ฐœ๋ฐœ์ž ์ •๋ณด

์ด์ •์œค - Full Stack Developer

๊ธฐ์—ฌ๋„

  • ์„œ๋น„์Šค ๊ธฐํš ๋ฐ UX ์„ค๊ณ„ (100%)
  • Frontend ๊ฐœ๋ฐœ (100%)
  • Firebase ๋ฐฑ์—”๋“œ ๊ตฌ์ถ• (100%)
  • ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… (100%)

๐Ÿ™ ๋งˆ์น˜๋ฉฐ

DogGain Forum์€ ๋‹จ์ˆœํ•œ ๊ฐœ๋ฐœ ์‹ค์Šต์„ ๋„˜์–ด, ์‹ค์ œ ์ปค๋ฎค๋‹ˆํ‹ฐ ์‚ฌ์šฉ์ž๋“ค์ด ๊ฒช๋Š” ๊ตฌ์กฐ์ ์ธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•œ ๋ฌธ์ œ์˜์‹์—์„œ ์ถœ๋ฐœํ•œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.

์ฒ˜์Œ์—๋Š” ๋‹จ์ˆœํžˆ "ํ•ซ๋”œ ์ •๋ณด๋ฅผ ๋ชจ์•„๋ณด์ž"๋Š” ์•„์ด๋””์–ด์˜€์ง€๋งŒ, ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๊ธฐ์กด ์ปค๋ฎค๋‹ˆํ‹ฐ๋“ค์ด ๊ฐ–๋Š” ์นดํ…Œ๊ณ ๋ฆฌ ํŽธํ–ฅ, ์ •๋ณด ๋ถ„์‚ฐ, UX ๋น„ํšจ์œจ๊ณผ ๊ฐ™์€ ์‹ค์งˆ์ ์ธ ๋ฌธ์ œ๋“ค์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ๋„˜์–ด์„œ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ค‘์‹ฌ์œผ๋กœ ๊ธฐ๋Šฅ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์กฐ์ •ํ•˜๊ณ , ๊ฒ€์ƒ‰ ์ตœ์ ํ™”ยท์ค‘๋ณต ์กฐํšŒ ๋ฐฉ์ง€ยท๋‹คํฌ๋ชจ๋“œ ์ง€์› ๋“ฑ ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒช๋Š” ๋ถˆํŽธํ•จ์„ ์ง์ ‘ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํŠนํžˆ, ๊ฒ€์ƒ‰ ์„ฑ๋Šฅ ๊ฐœ์„ ์„ ์œ„ํ•œ Firestore ์ฟผ๋ฆฌ ์ตœ์ ํ™”, ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์กฐํšŒ์ˆ˜ ์ค‘๋ณต ๋ฐฉ์ง€, ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™” ๋ฐ ๋ฌดํ•œ ์Šคํฌ๋กค ์„ค๊ณ„ ๋“ฑ์€ ๋ชจ๋‘ "์‚ฌ์šฉ์ž"๋ฅผ ๊ณ ๋ คํ•œ ์˜์‚ฌ๊ฒฐ์ •์ด์—ˆ๊ณ , ์ด๋Š” ๊ธฐ์ˆ ์  ํ•™์Šต ๊ทธ ์ด์ƒ์œผ๋กœ ํฐ ์„ฑ์žฅ์„ ์ด๋Œ์—ˆ์Šต๋‹ˆ๋‹ค.

DogGain Forum์€ ๋‹จ์ˆœํžˆ ํ•ซ๋”œ ์ •๋ณด๋ฅผ ๋ชจ์œผ๋Š” ์„œ๋น„์Šค๊ฐ€ ์•„๋‹ˆ๋ผ, ํ•ซ๋”œ์„ ์‚ฌ๋ž‘ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•œ ํšจ์œจ์ ์ธ ์ •๋ณด ๊ณต์œ  ํ”Œ๋žซํผ์„ ์ง€ํ–ฅํ•ฉ๋‹ˆ๋‹ค. ์•ž์œผ๋กœ๋„ ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ”ํƒ•์œผ๋กœ, ์‹ค์งˆ์ ์ธ ๋ฌธ์ œ๋ฅผ ์ •์˜ํ•˜๊ณ  ํ•ด๊ฒฐํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋กœ์„œ ๊พธ์ค€ํžˆ ๊ฐœ์„ ํ•ด ๋‚˜๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ์ปค๋ฎค๋‹ˆํ‹ฐ, ๋” ์œ ์šฉํ•œ ํ•ซ๋”œ ๊ฒฝํ—˜์„ ํ•จ๊ป˜ ๋งŒ๋“ค์–ด๊ฐ€๊ณ  ์‹ถ๋‹ค๋ฉด ์–ธ์ œ๋“  ํŽธํ•˜๊ฒŒ ์—ฐ๋ฝ ์ฃผ์„ธ์š”! ๐Ÿถ๐Ÿš€

About

๐Ÿถ๊ฐœ์ด๋“ ์ •๋ณด๋ฅผ ๋‚˜๋ˆ„๋Š” ํ•ซ๋”œ ์ปค๋ฎค๋‹ˆํ‹ฐ ํฌ๋Ÿผ

Resources

Stars

Watchers

Forks

Contributors

Languages