์ฌ์ฉ์ ๊ธฐ๋ณธ ์ํ์ ์ทจํฅ์ ๋ฐํ์ผ๋ก ์ํฉ ๋ง์ถค ๋ฉ๋ด/๋ง์ง์ ์ถ์ฒํ๋ ์น ์๋น์ค
๐ฅ ๋ฐฐํฌ URL ยท
๋ฐ๋ชจ ๊ณ์ : user@example.com / User1234!
์ค๋ฉ์ถ๋ ์ฌ์ฉ์์ ๊ธฐ๋ณธ ์ํยท์ทจํฅยท์ปจ๋์ ๊ฐ์ ๋งฅ๋ฝ์ ๋ฐ์ํด ๋ง์ถค ๋ฉ๋ด์ ๊ทผ์ฒ ๋ง์ง์ ๋น ๋ฅด๊ฒ ์ถ์ฒํฉ๋๋ค. ๋ชฉํ๋ ๋จ์ํฉ๋๋ค. ๊ณ ๋ฏผ ์๊ฐ์ ์ค์ด๊ณ , ์ ํ์ ๋ ์ฆ๊ฒ๊ฒ ๋ง๋ค๊ธฐ.
- ๋ฐ๋ณต๋๋ โ์ค๋ ๋ญ ๋จน์ง?โ์์ ์ค๋ ์์ฌ๊ฒฐ์ ํผ๋ก
- ๊ด๊ณ /๊ฒ์ ์ค์ฌ ๋ฆฌ์คํธ๋ก ์ธํ ์ ๋ณด ๊ณผ์๊ณผ ๊ฐ์ธ ๋งฅ๋ฝ ๋ฏธ๋ฐ์
- ์๋ก๊ณ ์นจ/์ดํ ์ ์ํ ์ ์ค, ๋๋ฆฐ ์๋ต, ๋น์ฝํ ํด๋ฐฑ ๋ฑ UX ๋๊น
- ์จ๋ณด๋ฉ 5๋จ๊ณ๋ก ์ต์ ์ ๋ ฅ์ผ๋ก ํต์ฌ ์ ํธ ์์ง
- ์ปจํ ์คํธ ๊ธฐ๋ฐ ํ์: ํ๊ทธยท๊ฐ๊ฒฉยท์ ๋ ฌยท๊ฒ์(๋๋ฐ์ด์ค) + ๋ฌดํ ์คํฌ๋กค
- ์์ธ ํ์ด์ง ์ค์ฌ์ฉ ์๋๋ฆฌ์ค: ๋ฆฌ๋ทฐ ์ ๋ ฌ/ํํฐ, ์ ๊ณ , ์ด๋ฏธ์ง ํด๋ฐฑ, ํ์ ์์ฝ
- ๋ง์ดํ์ด์ง์์ ์ํ/์ทจํฅ ์ฌ์ค์ โ ์ถ์ฒ ํ์ง ์ํ ๊ฐ์
ํ์ฌ ์ถ์ฒ์ ๊ท์น ๊ธฐ๋ฐ ํํฐ+์ ๋ ฌ๋ก ์์ ์ด์ ์ค์ด๋ฉฐ, ์ดํ ๊ฐ์ธํ ์ ์/๊ฐ์ค์น ๊ธฐ๋ฐ ๋ชจ๋ธ๋ก ๊ณ ๋ํ ์์ .
- ์ํคํ ์ฒ
- ์ฃผ์ ๊ธฐ๋ฅ
- ์ค์น ๋ฐ ์คํ
- ํด๋ ๊ตฌ์กฐ
- ๊ธฐ์ ์คํ
- ํ์ ๊ท์น/์ปค๋ฐ ์ปจ๋ฒค์
- ํธ๋ฌ๋ธ์ํ
- AI ํ์ฉ
- ๋ก๋๋งต
- ์๋ฒ ์ํ: TanStack Query๋ก ์บ์ฑ/๋ฌดํจํ/๋๊ด์ ์ ๋ฐ์ดํธ/๋ฌดํ ์คํฌ๋กค ๊ด๋ฆฌ
- ํด๋ผ์ด์ธํธ ์ํ: Zustand๋ก ์จ๋ณด๋ฉ ์งํ/๋ชจ๋ฌ/๋ทฐ ๋ก์ปฌ ์ํ ๊ด๋ฆฌ
- ๋คํธ์ํฌ ๊ณ์ธต ๋ถ๋ฆฌ:
axiosInstance(์ธ์ฆ) ยทaxiosPublicInstance(๊ณต๊ฐ ์ ๋ก๋) - ์ด๋ฏธ์ง ์์ ํ: ํ๊ธ ํ์ผ๋ช NFC ์ ๊ทํ, ํ์ฅ์ ์๋ฌธ์, onError ํด๋ฐฑ/์ฌ์๋
flowchart LR
UI[Next.js App Router UI] -->|useQuery| RQ[React Query Cache]
RQ -->|Axios| API[(REST API)]
UI -->|Zustand| CS[Client State]
subgraph Client
UI
RQ
CS
end
subgraph Server
API
end
- ๊ฐ์น: ์ต์ ์ ๋ ฅ์ผ๋ก ๋ง์ถค ์ด๊ธฐ ์ถ์ฒ ์์ฑ, ์ฌ๋ฐฉ๋ฌธ ๋ณต์
- ๊ธฐ์ : Zustand ์ํ/๊ฒ์ฆ, ๋ก์ปฌ ์ค๋ ์ท, ์๋ฒ ๋๊ธฐํ
- ํ ์คํธ: ์๋ก๊ณ ์นจ/๋ค๋ก๊ฐ๊ธฐ ์์ , ๋ชจ๋ฐ์ผ ํค๋ณด๋ UX
- ๊ฐ์น: ์กฐ๊ฑด ๋ณ๊ฒฝ์๋ ๋๊ธฐ์ง ์๋ ํ์ ๋ฆฌ๋ฌ
- ๊ธฐ์ :
useInfiniteQuery, ์ฟผ๋ฆฌํค/staleTimeยทgcTime์ค๊ณ, ํ๋ฆฌํจ์นญ - ํ ์คํธ: ํํฐ ์กฐํฉ ์บ์ ๋ฌดํจํ, ์คํฌ๋กค ๊ฒฝ๊ณ, ์คํจ ํด๋ฐฑ
- ๊ฐ์น: ์ฌ์งยท๋ฆฌ๋ทฐยทํ์ ์ ํ ํ๋ฉด์์ ๋น ๋ฅด๊ฒ ํ๋จ
- ๊ธฐ์ : ์ด๋ฏธ์ง ํด๋ฐฑ/NFC ์ ๊ทํ, ์ ๊ทผ์ฑ alt, ๋ฅ๋งํฌ ๊ฒฝ๋ก
- ํ ์คํธ: ๋น ์ํ/์ง์ฐ/์คํจ ํด๋ฐฑ, ๋ชจ๋ฌ ํฌ์ปค์ค ํธ๋ฉ
- ๊ฐ์น: ์ฆ์ ๋ฐ์/๋กค๋ฐฑ์ผ๋ก ์ผ๊ด UX
- ๊ธฐ์ :
useMutation๋๊ด์ ์ ๋ฐ์ดํธ + ์ค๋ฅ ๋กค๋ฐฑ, ์ฟผ๋ฆฌ ๋๊ธฐํ - ํ ์คํธ: ์ฐ์ ํ ๊ธ/401 ๋ง๋ฃ/๋กค๋ฐฑ ์ฒดํฌ
- ๊ฐ์น: ์ง์ ๋ณด์ ์ผ๋ก ๊ฐ์ธํ ํ์ง ํฅ์
- ๊ธฐ์ : ๋ณดํธ ๋ผ์ฐํ , ์๋ฒ/ํด๋ผ ์ํ ๋ถ๋ฆฌ ์ ์ฅ, ํ์ด์ง๋ค์ด์
- ๊ฐ์น: ๋ช ํํ ๊ฐ์ ํ๋ก์ฐ, ๋ณด์ ์ ์ง๋ ๊ฐ์ธํ
- ๊ธฐ์ : JWT, ์ธํฐ์ ํฐ ํ ํฐ ๋ถ์ฐฉ/์๋ฌ ๊ณตํต ์ฒ๋ฆฌ, ๋ผ์ฐํธ ๊ฐ๋
- ๊ฐ์น: ์คํจ ํ๋ฅ โ, ์ฌ์ฉ์ ํผ๋ ์ต์ํ
- ๊ธฐ์ :
/v1/uploads/publicvs/v1/uploads, ํ์ผ๋ช ์ ๊ทํ/์๋ฌธ์ํ, ์ธ๋ค์ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
# 1) ํด๋ก
git clone <your-repo-url>
cd omechu
# 2) ํจํค์ง ์ค์น
yarn install
# 3) ๊ฐ๋ฐ ์๋ฒ
yarn dev # http://localhost:3000
# 4) ๋น๋/๋ฏธ๋ฆฌ๋ณด๊ธฐ
yarn build
yarn startNEXT_PUBLIC_API_BASE_URL=https://api.example.com
NEXT_PUBLIC_KAKAO_MAP_API_KEY=...
NEXT_PUBLIC_GOOGLE_PLACE_API_KEY=...
GOOGLE_MAP_SERVER_API_KEY=...์ด๋ฏธ์ง ์ต์ ํ๋ฅผ ์ํด
sharp์ค์น๋ฅผ ๊ถ์ฅํฉ๋๋ค:pnpm add sharp.
.
โโโ (auth) # ์ธ์ฆ ์ ์ฉ ๋ผ์ฐํธ ๊ทธ๋ฃน(์ค์ URL ๋
ธ์ถ ์์)
โโโ api/ # Next.js Route Handler: ์๋ฒ API ํ๋ก์/์ ํธ(์: ์ง์ค์ฝ๋)
โโโ auth/ # ์ธ์ฆ ๊ด๋ จ ํ์ด์ง ๋ฌถ์(์ฝ๋ฐฑ, ์ฌ์ค์ ๋ฑ)
โโโ components/ # ๊ณต์ฉ UI ์ปดํฌ๋ํธ(๋ชจ๋ฌ/์
๋ ฅ/์ค์ผ๋ ํค/ํค๋ ๋ฑ)
โโโ constant/ # ๋๋ฏธ ๋ฐ์ดํฐยท์์ยท์ต์
โโโ fullmenu/ # ์ ์ฒด ๋ฉ๋ด ํ์(ํํฐ/๊ฒ์/๋ฆฌ์คํธ)
โโโ lib/ # API ์ธ์คํด์ค, ๊ณต์ฉ ํ
, ํ๋ก๋ฐ์ด๋, ์ํ ์คํ ์ด, ํ์
โโโ mainpage/ # ์ง๋ฌธ ๊ธฐ๋ฐ ์ถ์ฒ ํ๋ก์ฐ(์์ฐ/๋ชฉ์ /๋ฌด๋ ๋ฑ)
โโโ mypage/ # ํ๋กํ/๊ธฐ๋ณธ ์ํ/๋จน๋ถ๋ฆผ ๊ธฐ๋ก/์ค์
โโโ onboarding/ # 5๋จ๊ณ ์จ๋ณด๋ฉ UI/ํ
โโโ restaurant/ # ๋ง์ง ๋ฆฌ์คํธยท์์ธยท์ง๋(์นด์นด์ค ์ง๋ ํฌํจ)
โโโ globals.css # ์ ์ญ ์คํ์ผ
โโโ layout.tsx # ๋ฃจํธ ๋ ์ด์์(App Router)
โโโ ClientLayout.tsx # ํด๋ผ์ด์ธํธ ์ ์ฉ ๋ ์ด์์
โโโ page.tsx # ๋ฃจํธ ํ์ด์ง ์ํธ๋ฆฌ
์์น: Server State=React Query, Client State=Zustand, ๊ณต์ฉ ๋ก์ง=lib, ๊ณต์ฉ UI=components.
ํ๊ทธ ๊ธฐ๋ฐ ์ปค๋ฐ ์ปจ๋ฒค์ ์ ์ฌ์ฉํฉ๋๋ค.
| ํ๊ทธ | ์ค๋ช |
|---|---|
feat |
์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ |
fix |
๋ฒ๊ทธ ์์ |
docs |
๋ฌธ์ ์์ |
style |
์ฝ๋ ์คํ์ผ ๋ณ๊ฒฝ |
design |
UI ๋์์ธ ๋ณ๊ฒฝ |
test |
ํ ์คํธ ์์ฑ/์์ |
refactor |
๋ฆฌํฉํ ๋ง(๊ธฐ๋ฅ ๋ณํ ์์) |
build |
๋น๋ ์ค์ ์์ |
ci |
CI ์ค์ ๋ณ๊ฒฝ |
perf |
์ฑ๋ฅ ๊ฐ์ |
chore |
์ค์ /ํจํค์ง ๋ฑ ๊ธฐํ |
rename |
ํ์ผ/ํด๋๋ช ๋ณ๊ฒฝ |
remove |
ํ์ผ/๋ฆฌ์์ค ์ญ์ |
wip |
์งํ ์ค ์์ ์ปค๋ฐ |
hotfix |
์ด์ ๊ธด๊ธ ์์ |
์์ฑ ๊ท์น ์์
feat: ๊ฐ์ ์ ํ ํ์ด์ง ๋ ์ด์์ ๊ตฌํ #12
fix: ๋ก๊ทธ์ธ ์คํจ ์ ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ์ค๋ฅ ์์ #7- ๊ฒ์ ์งํ ์๋ ์ฌ๊ฒ์:
submittedTermvsinputValue๋ถ๋ฆฌ, ์ด๊ธฐํ ์งํ ์ ๋ ฅ ๋ฌด์ ๊ฐ๋ - ์ด๋ฏธ์ง ํ๊ธ ํ์ผ๋ช (NFC/NFD): ์ ๋ก๋ NFC ์ ๊ทํ, ํ์ฅ์ ์๋ฌธ์, onError ์ฌ์๋/ํด๋ฐฑ
- ๊ณต๊ฐ/์ธ์ฆ ์
๋ก๋ ๋ถ๋ฆฌ:
axiosPublicInstance+/v1/uploads/public๋์ ์ผ๋ก 401 ์ด์ ํด์ - ๋์ ๋ผ์ฐํ
ํ์
์ค๋ฅ: ์ผ๋ถ ํ์ด์ง Client Component ์ ํ +
useParams()์ฌ์ฉ - react-datepicker ๊ฒ์ฆ: ์ ์ดํ props๋ก ๊ฐ์ , setState ์ง์ ๊ฐ๋
- ์ฐ ํ ๊ธ ์ง์ฐ:
onMutate/onError/onSettled๋๊ด์ ์ ๋ฐ์ดํธ + ๋กค๋ฐฑ
์์ธ ๋ก๊ทธ/์คํฌ๋ฆฐ์ท์ ๋ณ๋ ๋ฌธ์(๋ ธ์ ) ์ฐธ๊ณ .
- Gemini ๊ธฐ๋ฐ ์ฝ๋ ๋ฆฌ๋ทฐ: ์ปดํฌ๋ํธ ๊ฒฝ๊ณ, prop ๋๋ฆด๋ง, ์ฟผ๋ฆฌํค/์๋ฌ ํจํด ์ ๊ฒ ๋ฐ ๋ฆฌํฉํฐ๋ง ์์ด๋์ด ๋์ถ
- ๊ฐ์ธํ ์ ์/๊ฐ์ค์น ๊ธฐ๋ฐ ์ถ์ฒ ์์ง ๊ณ ๋ํ
- ๋ฆฌ๋ทฐ ํ์ง ์ ๋ขฐ๋(๊ฐ์ค์น) ๋ฐ์ ์ ๋ ฌ
- ์ด๋ฏธ์ง ์ ๋ก๋ ํ์ดํ๋ผ์ธ ๋ฆฌํธ๋ผ์ด/์ธ๋ค์ผ ์์ปค
- i18n(ํ/์) ๋ฐ ์ ๊ทผ์ฑ ๊ฐ์ฌ(a11y)
- ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง(LCP/CLS/INP) ๋์๋ณด๋
- @theSnackOverflow - theSnackOverflow 2ssac
- @Head-ddy - Head-ddy ๋ผํฌ์
- @IISweetHeartII - IISweetHeartII ๊น๋ํ
- @jeonbinggu - jeonbinggu Jeonbyeongguk
Made with โค๏ธ ยฉ 2025 OMECHU Team