- λ°°ν¬ URL : https://taskmate-fe.vercel.app/login
- Test ID : admin@admin.com
- Test PW : admin123!
- TaskMateλ κ°μΈ ν μΌλΆν° ν νμ κΉμ§ νλμ μλΉμ€μμ κ΄λ¦¬ν μ μλ μ¬μΈμ νμ€ν¬ κ΄λ¦¬ νλ«νΌμ λλ€.
- λͺ©ν(Goal) κΈ°λ°μΌλ‘ ν μΌ(Todo)μ ꡬ쑰ννμ¬ λ§κ°μΌΒ·μ§μ²λ₯ μ νλμ νμ ν μ μμ΅λλ€.
- νμ μμ±νκ³ μ΄λ λ§ν¬λ₯Ό 곡μ ν΄ νμλ€κ³Ό λͺ©νλ₯Ό ν¨κ» κ΄λ¦¬ν μ μμ΅λλ€.
- μ¦κ²¨μ°ΎκΈ° λͺ©ν, λμ보λ μ§νλ₯ μμ½, μ€μκ° μλ¦Ό(SSE)μ ν΅ν΄ μ 무 νλ¦μ λΉ λ₯΄κ² νμ ν μ μμ΅λλ€.
- μμ ν ν μΌμ ν΄μ§ν΅μ 보κ΄λλ©° 볡ꡬνκ±°λ μꡬ μμ ν μ μμ΅λλ€.
| κΉμ’ μ§ | ν©ν¨μ§ | zaenny |
|---|---|---|
@SugarSyrup |
@hwanghyojin |
@zaenny |
- Front : Next.js 16, React 19, TypeScript, Tailwind CSS v4, Zustand, React Query
- λ²μ λ° μ΄μκ΄λ¦¬ : Github, Github Issues, Github Project
- νμ ν΄ : Discord, Notion, Github Wiki
- μλΉμ€ λ°°ν¬ νκ²½ : Vercel
- λμμΈ : Figma
- Next.js App Router
- μλ² μ»΄ν¬λνΈμ ν΄λΌμ΄μΈνΈ μ»΄ν¬λνΈλ₯Ό λͺ νν λΆλ¦¬ν΄ λΆνμν λ²λ€ ν¬κΈ°λ₯Ό μ€μμ΅λλ€.
- API Route(
/api/[...path])λ₯Ό νλ‘μλ‘ νμ©ν΄ λ°±μλ URL λ ΈμΆ μμ΄ μΈμ¦ ν ν°μ μλ²μμ μμ νκ² μ²¨λΆν©λλ€. - 401/403 μλ΅ μ ν ν°μ μλ κ°±μ νκ³ μλ μμ²μ μ¬μλν΄ μ¬μ©μκ° λ‘κ·ΈμΈ λ§λ£λ₯Ό μΈμνμ§ λͺ»νλλ‘ μ²λ¦¬νμ΅λλ€.
- TypeScript
- API Request/Response νμ
μ
entities/{domain}/types/μ μ μν΄ λ°νμ μλ¬λ₯Ό μ¬μ μ λ°©μ§νμ΅λλ€. - Zod μ€ν€λ§λ‘ νΌ μ ν¨μ± κ²μ¬ λ‘μ§μ νμ κ³Ό ν¨κ» κ΄λ¦¬νμ΅λλ€.
- API Request/Response νμ
μ
src/app/globals.cssμ@themeμ λμμΈ ν ν°(μμΒ·νμ΄ν¬κ·ΈλνΌΒ·λΈλ μ΄ν¬ν¬μΈνΈ)μ μ€μ κ΄λ¦¬ν΄ μΌκ΄λ UIλ₯Ό μ μ§νμ΅λλ€.typography-{scale}μ νΈλ¦¬ν° ν΄λμ€(typography-body-2,typography-label-1λ±)λ₯Ό μ μν΄ λμμΈ μμ€ν μ μ½λλ‘ κ°μ νμ΅λλ€.- μμκ°(
text-[14px]) μ¬μ©μ κΈμ§νκ³ ν ν° κΈ°λ° μ€νμΌλ§ νμ©ν΄ λμμΈ μΌκ΄μ±μ λμμ΅λλ€.
- React Query : μλ² μνλ₯Ό
entities/{domain}/query/μqueryOptionsλ‘ μ€μ κ΄λ¦¬νμ΅λλ€.staleTime60μ΄ κΈ°λ³Έκ°κ³ΌthrowOnError: trueλ‘ μλ¬λ₯ΌErrorBoundaryμ μμνμ΅λλ€. - Zustand : μ μ UI μν(λͺ¨λ¬/μ€λ²λ μ΄ μ€ν, μΈμ¦ μ 보)λ§ λ΄λΉν©λλ€. μΈμ¦ μνλ
persist + immerλ―Έλ€μ¨μ΄λ‘ localStorageμ μ μ§λ©λλ€.
app β widgets β features β entities β sharedλ¨λ°©ν₯ μμ‘΄ νλ¦μ κ°μ ν΄ μ½λ λ³κ²½ μν₯ λ²μλ₯Ό μμΈ‘ κ°λ₯νκ² μ μ§νμ΅λλ€.pnpm steigerλ‘ λ μ΄μ΄ μλ°μ μλ κ°μ§ν©λλ€.- κ° sliceλ
index.tsλ₯Ό ν΅ν΄μλ§ μΈλΆμ λ ΈμΆν΄ λ΄λΆ ꡬν λ³κ²½μ΄ μΈλΆμ μν₯μ λ―ΈμΉμ§ μλλ‘ νμ΅λλ€.
- κ°λ° νκ²½μμ μ€μ λ°±μλ μμ΄ API λμμ ν μ€νΈν μ μλλ‘ MSWλ₯Ό λμ νμ΅λλ€.
pnpm dev:fullλ‘ Next.js κ°λ° μλ²μ json-server(port 4000)λ₯Ό λμμ μ€νν μ μμ΅λλ€.
- Git-flow μ λ΅μ κΈ°λ°μΌλ‘
main,develop,feat보쑰 λΈλμΉλ₯Ό μ΄μ©νμ΅λλ€.- main λΈλμΉλ λ°°ν¬ λ¨κ³μμλ§ μ¬μ©ν©λλ€.
- develop λΈλμΉλ κ°λ° λ¨κ³μ ν΅ν© λΈλμΉμ λλ€.
- feat λΈλμΉλ κΈ°λ₯ λ¨μ(
feat/#μ΄μλ²νΈ)λ‘ λ 립 κ°λ°νκ³ merge ν μμ ν©λλ€.
βββ docs/
βββ src/
βββ app/
β βββ api/
β β βββ [...path]/route.ts # API νλ‘μ (ν ν° μ²¨λΆΒ·κ°±μ )
β β βββ auth/ # OAuth μ½λ°± (Google, Kakao)
β βββ (auth)/
β β βββ login/
β β βββ signup/
β βββ taskmate/
β β βββ page.tsx # λμ보λ
β β βββ personal/goal/ # κ°μΈ λͺ©ν
β β βββ team/ # ν λͺ©λ‘Β·μμΈΒ·κ΄λ¦¬
β β βββ my/ # λ΄ νλ‘ν
β β βββ trash/ # ν΄μ§ν΅
β β βββ invitations/ # ν μ΄λ
β βββ layout.tsx
β βββ page.tsx # λλ© νμ΄μ§
β βββ globals.css
βββ widgets/
β βββ auth/
β βββ home/
β βββ landing/
β βββ goal/
β βββ team/
β βββ todo/
β βββ trash/
β βββ management/
β βββ my/
β βββ NavigationBar/
βββ features/
β βββ auth/
β βββ todo/
β βββ goal/
β βββ team/
β βββ user/
β βββ management/
β βββ trash/
β βββ notification/
βββ entities/
β βββ auth/
β βββ todo/
β βββ goal/
β βββ team/
β βββ user/
β βββ dashboard/
β βββ notification/
β βββ trash/
βββ shared/
βββ ui/
β βββ Button/
β βββ Input/
β βββ Modal/
β βββ Icon/
β βββ AsyncBoundary/
β βββ Toast/
β βββ ...
βββ hooks/
β βββ useOverlay/
β βββ useInfiniteScroll/
β βββ ...
βββ lib/
β βββ api/client.ts
βββ store/
β βββ overlay/
βββ mock/
β βββ server.ts
β βββ browser.ts
βββ utils/
- UI
- νμ΄μ§ : λμ보λ, κ°μΈ λͺ©ν μμΈ, λλ© νμ΄μ§, ν λͺ©λ‘, ν μμΈ, ν μμ±
- κ³΅ν΅ μ»΄ν¬λνΈ : NavigationBar, AsyncBoundary, Overlay μμ€ν
- κΈ°λ₯
- API νλ‘μ λ° ν ν° μλ κ°±μ , FSD μν€ν μ² μ€κ³, MSW λͺ© νΈλ€λ¬
- ν μμ±Β·μ‘°νΒ·νμ κ΄λ¦¬, ν μ΄λ λ§ν¬
- ν μΌ CRUD, 무ν μ€ν¬λ‘€,
- UI
- νμ΄μ§ : λ‘κ·ΈμΈ, νμκ°μ , λ΄ νλ‘ν
- κ³΅ν΅ μ»΄ν¬λνΈ : μΈμ¦ νΌ, InputBox
- κΈ°λ₯
- ν κ΄λ¦¬
- μλ¦Ό
- UI
- νμ΄μ§ : ν μΌ μμΈ λͺ¨λ¬, ν΄μ§ν΅
- κ³΅ν΅ μ»΄ν¬λνΈ : TodoDetailModal, νν°Β·μ λ ¬ UI
- κΈ°λ₯
- Auth, λ‘κ·ΈμΈ μΈμ¦/μΈκ°
- OAuth(Google, Kakao) λ‘κ·ΈμΈ, νμκ°μ μ ν¨μ± κ²μ¬, νλ‘ν μμ
- ν΄μ§ν΅ 볡ꡬ·μμ
- μ 체 κ°λ° κΈ°κ° : 2026-03-12 ~ μ§ν μ€
- κΈ°ν λ° μ€κ³ : 2026-03-12 ~ 2026-03-18
- UI ꡬν : 2026-03-19 ~ 2026-04-06
- κΈ°λ₯ ꡬν : 2026-04-07 ~ νμ¬
- GitHub Projectsμ Issuesλ₯Ό μ¬μ©νμ¬ κΈ°λ₯ λ¨μλ‘ μμ μ λΆλ°°νκ³ μ§ν μν©μ 곡μ νμ΅λλ€.
- μ κΈ° νμλ₯Ό ν΅ν΄ μμ μμμ FSD λ μ΄μ΄ κ²½κ³μ λν λ Όμλ₯Ό μ§ννκ³ Notionμ κΈ°λ‘νμ΅λλ€.
- λͺ¨λ ν΄λΌμ΄μΈνΈ μμ²μ΄
src/app/api/[...path]/route.tsλ₯Ό κ²½μ νλλ‘ μ€κ³νμ΅λλ€. - μΏ ν€μμ
accessTokenμ μ½μ΄Authorizationν€λλ₯Ό μλ²μμ 첨λΆνλ―λ‘ ν ν°μ΄ ν΄λΌμ΄μΈνΈ μ½λμ λ ΈμΆλμ§ μμ΅λλ€. - 401/403 μλ΅ μ ν ν°μ μλ κ°±μ νκ³ μλ μμ²μ μ¬μλν΄ μ¬μ©μκ° λ‘κ·ΈμΈ λ§λ£λ₯Ό μΈμνμ§ λͺ»νλλ‘ μ²λ¦¬νμ΅λλ€.
- Zustand λ μ΄μ΄ μ€νμΌλ‘ λͺ¨λ¬Β·λ°ν μνΈλ₯Ό μ μμμ κ΄λ¦¬ν©λλ€.
useOverlay().open("id", <Component />)ν μ€λ‘ μ΄λ λ μ΄μ΄μμλ λͺ¨λ¬μ μ΄ μ μλλ‘ μΆμννμ΅λλ€.exitOnUnmount: true(κΈ°λ³Έκ°)λ‘ νμ΄μ§ μ΄λ μ λ¨μ λͺ¨λ¬μ΄ μλμΌλ‘ λ«νλλ€.
pnpm steigerλ‘ λ μ΄μ΄ μλ°μ μλ κ°μ§ν©λλ€.entitiesλ μ΄μ΄λ μμ HTTP νΈμΆλ§ λ΄λΉνκ³ , μΊμ 무ν¨νΒ·λ€λΉκ²μ΄μ λ± μ¬μ΄λ μ΄ννΈλ λ°λμfeatures/mutationν μonSuccessμμ μ²λ¦¬ν©λλ€.
- μλΉμ€ μκ°, μ£Όμ κΈ°λ₯ μλ΄, νμ μ¨λ³΄λ© λ¨κ³λ₯Ό μκ°μ μΌλ‘ μ λ¬ν©λλ€.
- λ‘κ·ΈμΈ μνμ λ°λΌ λμ보λ λλ λ‘κ·ΈμΈ νμ΄μ§λ‘ μλ μ΄λν©λλ€.
| λλ© νμ΄μ§ |
|---|
- μ΄λ©μΌΒ·λΉλ°λ²νΈ μ λ ₯ μ μ€μκ° μ ν¨μ± κ²μ¬κ° μ§νλκ³ ν΅κ³Όνμ§ λͺ»ν κ²½μ° κ²½κ³ λ¬Έκ΅¬κ° νμλ©λλ€.
- Google, Kakao OAuth μμ λ‘κ·ΈμΈμ μ§μν©λλ€.
- μΈμ¦ μνλ Zustand
persistλ―Έλ€μ¨μ΄λ‘ localStorageμ μ μ§λ©λλ€.
| λ‘κ·ΈμΈ | νμκ°μ |
|---|---|
- λ‘κ·ΈμΈ ν 첫 νλ©΄μΌλ‘, κ°μΈ μ§νλ₯ μμ½, μ¦κ²¨μ°ΎκΈ° λͺ©ν, μ€λμ ν μΌ νν©μ νλμ νμΈν μ μμ΅λλ€.
- μ¦κ²¨μ°ΎκΈ° λͺ©νλ 무ν μ€ν¬λ‘€λ‘ νμν μ μμ΅λλ€.
| λμ보λ |
|---|
- λͺ©νλ³λ‘ ν μΌ(Todo)μ μμ±Β·μμ Β·μμ ν μ μμ΅λλ€.
- λ§κ°μΌΒ·μμ±μΌ κΈ°μ€ μ λ ¬, To Do / Done νν°λ₯Ό μ§μν©λλ€.
- 컀μ κΈ°λ° λ¬΄ν μ€ν¬λ‘€λ‘ λλμ ν μΌμ μ±λ₯ μ ν μμ΄ νμν©λλ€.
- ν μΌ μμΈ λͺ¨λ¬μμ λͺ©ν μ°κ²°, λ§κ°μΌ, λ©λͺ¨, νμΌ μ²¨λΆλ₯Ό κ΄λ¦¬ν©λλ€.
| κ°μΈ λͺ©ν μμΈ | ν μΌ μμ± |
|---|---|
- νμ μμ±νκ³ μ΄λ λ§ν¬λ₯Ό 곡μ ν΄ νμμ μΆκ°ν μ μμ΅λλ€.
- ν λͺ©νλ₯Ό μμ±νκ³ νμμκ² ν μΌμ ν λΉν μ μμ΅λλ€.
- ν κ΄λ¦¬ νμ΄μ§μμ λ©€λ² λͺ©λ‘ μ‘°ν λ° μΆλ°©μ΄ κ°λ₯ν©λλ€.
| ν λͺ©λ‘ | ν μμΈ |
|---|---|
- νλ‘ν μ΄λ―Έμ§, μ΄λ¦, μ΄λ©μΌ μ 보λ₯Ό νμΈνκ³ μμ ν μ μμ΅λλ€.
- λ‘κ·Έμμ μ μ μ₯λ μΈμ¦ μ λ³΄κ° μ΄κΈ°νλκ³ λλ© νμ΄μ§λ‘ μ΄λν©λλ€.
| λ΄ νλ‘ν |
|---|
- μμ ν ν μΌμ΄ 보κ΄λλ©° 볡ꡬνκ±°λ μꡬ μμ ν μ μμ΅λλ€.
| ν΄μ§ν΅ |
|---|
- SSE(Server-Sent Events)λ₯Ό ν΅ν΄ ν μ΄λ, ν μΌ λ³κ²½ λ±μ μλ¦Όμ μ€μκ°μΌλ‘ μμ ν©λλ€.
- μλ¦Ό λλ‘μ΄μμ μ½μ μ²λ¦¬ λ° λͺ©λ‘ νμΈμ΄ κ°λ₯ν©λλ€.
| μλ¦Ό |
|---|
- μ κ·Όμ± κ°μ : ν€λ³΄λ λ€λΉκ²μ΄μ , ARIA μμ± μΆκ°λ‘ μ€ν¬λ¦° 리λ νΈνμ± ν₯μ
- μ±λ₯ μ΅μ ν
- μ΄λ―Έμ§ μ»΄ν¬λνΈ
next/imageμ ν λ° lazy loading μ μ© - λ²λ€ ν¬κΈ° λΆμ ν heavy dependency κ²½λν
- μ΄λ―Έμ§ μ»΄ν¬λνΈ
- ν μ€νΈ 컀λ²λ¦¬μ§ νλ : ν΅μ¬ mutation ν κ³Ό μ£Όμ μ»΄ν¬λνΈ λ¨μ ν μ€νΈ μΆκ°
- μλ¬ μ²λ¦¬ κ³ λν : λ€νΈμν¬ μλ¬Β·νμμμ μν©μ λν μ¬μ©μ νΌλλ°± κ°μ