- ๋ฐฐํฌ URL : https://loglife-rho.vercel.app/
LogLife๋ "์ฃฝ๊ธฐ ์ ์ ํ๊ณ ์ถ์ ๊ฒ๋ค"์ ๋ฒํท๋ฆฌ์คํธ๋ก ๋ฑ๋กํ๊ณ ๋ฌ์ฑํด๋๊ฐ๋ ์ธ์ ๊ฒฝํ ์์นด์ด๋ธ ์๋น์ค์
๋๋ค.
๋จ์ํ ํ ์ผ ์ฑ์ด๋ ์ฌํ ์ฑ์ด ์๋, ๋ฒํท๋ฆฌ์คํธ๋ฅผ ์ง๊ตฌ๋ณธ ์์ ํ์ผ๋ก ์๊ฐํํ๊ณ ์น๊ตฌ๋ค๊ณผ ๊ณต์ ํ๋ ๊ฒฝํ ๊ธฐ๋ก ๊ณต๊ฐ์
๋๋ค.
Google Places API์ Globe.gl์ ํ์ฉํด ๋ฒํท๋ฆฌ์คํธ ํญ๋ชฉ์ ์ง๊ตฌ๋ณธ ์์ ํํํ๋ฉฐ, PWA๋ก ๋ชจ๋ฐ์ผ์์๋ ์ค์นํด ์ฌ์ฉํ ์ ์์ต๋๋ค.
| ์ฉ๋ | ๊ธฐ์ |
|---|---|
| ORM / DB ์คํค๋ง | |
| ๋ฐ์ดํฐ๋ฒ ์ด์ค | |
| ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฆ | |
| ์ฅ์ ๊ฒ์ ยท ์๋์์ฑ |
| ์ฉ๋ | ๊ธฐ์ |
|---|---|
| ๋จ์ ยท ์ปดํฌ๋ํธ ํ ์คํธ | |
| API ๋ชจํน | |
| E2E ํ ์คํธ | |
| ์ปดํฌ๋ํธ ์นดํ๋ก๊ทธ | |
| ์๊ฐ ํ๊ท ํ ์คํธ ยท CI |
| ์ฉ๋ | ๊ธฐ์ |
|---|---|
| ๋ฐฐํฌ ํ๋ซํผ |
| ๋ฉ์ธ ํ์ด์ง |
|---|
![]() |
| ๐ก ๊ธ์ | ๐ด ๋ถ์์ | โฌ ํ์ |
|---|---|---|
| ์ ๋ถ ๋ฌ์ฑ | ํ๋๋ผ๋ ๋ง๊ฐ์ผ์ด ์ง๋จ | ๊ทธ ์ธ์ ๊ฒฝ์ฐ |
- ์ง๊ตฌ๋ณธ์ ๋๋๊ทธํด ์์ ๋กญ๊ฒ ํ์ ํ๋ฉฐ ๋ฑ๋กํ ๋ฒํท๋ฆฌ์คํธ ํ์ ํ๋์ ํ์ธํ ์ ์์ต๋๋ค.
- ํ์ ๊ตญ๊ฐ๋ณ๋ก ํด๋ฌ์คํฐ๋ง๋์ด ๊ฐ์๊ฐ ํจ๊ป ํ์๋ฉ๋๋ค.
- ํ ์์์ ํด๋น ๊ตญ๊ฐ ๋ฒํท๋ฆฌ์คํธ์ ๋ฌ์ฑ ์ํ์ ๋ฐ๋ผ ๋ณ๊ฒฝ๋ฉ๋๋ค.
- ํ๋จ ๋ด๋น๊ฒ์ด์ ์ ์ฐ์ธก ๋ฒํผ์ ๋๋ฅด๋ฉด ์์ฑ ํจ๋์ด ๋ํ๋ฉ๋๋ค.
- ์ ๋ชฉ, ๋ด์ฉ, ์ฅ์, ๋์ด๋, ์ค๋ ์, ๊ณต๊ฐ ๋ฒ์๋ฅผ ์ ๋ ฅํด ๋ฒํท๋ฆฌ์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
- ํ์ ํด๋ฆญํ๋ฉด ํด๋น ๊ตญ๊ฐ์ ๋ฒํท๋ฆฌ์คํธ ๋ชฉ๋ก์ด ์ฌ๋ผ์ด๋์ ํจ๋๋ก ํ์๋ฉ๋๋ค.
- ํญ๋ชฉ์ ์ ํํ๋ฉด ๋ฒํท๋ฆฌ์คํธ ์์ธ ํ๋ฉด์ผ๋ก ์ ํ๋ฉ๋๋ค.
- ์ฐ์ธก ์๋จ์ ๋ฒํผ์ ํตํด ๊ณต์ ํ ์ ์์ต๋๋ค.
- ๋ฏธ๋ฌ์ฑ ํญ๋ชฉ์ ๋ฌ์ฑ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
- ๋ฌ์ฑํ ํญ๋ชฉ์ ๋ฏธ๋ฌ์ฑ ์ํ๋ก ๋๋๋ฆด ์ ์์ต๋๋ค.
- ๋ง๊ฐ์ผ์ด ์ง๋ ํญ๋ชฉ์ ์ ๋ง๊ฐ์ผ์ ์ง์ ํ ์ ์์ต๋๋ค.
- ํ๋จ ๋ด๋น๊ฒ์ด์ ์ ๋์๋ณด๋ ๋ฒํผ์ ํด๋ฆญํ๋ฉด 4๊ฐ์ ํต๊ณ ์์ ฏ์ ํ์ธํ ์ ์์ต๋๋ค.
- ๋งคํธ๋ฆญ์ค ์์ ฏ์ ํด๋ฆญํ๋ฉด ์์ธ ์ฌ๋ผ์ด๋ ํจ๋๋ก ์ ํ๋ฉ๋๋ค.
- ์น๊ตฌ ์์ด์ฝ์ ํด๋ฆญํ๋ฉด ์น๊ตฌ ๋ชฉ๋ก ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.
- ์น๊ตฌ ์ด๋ฆ์ ํด๋ฆญํ๋ฉด ํด๋น ์ฌ์ฉ์์ ๋ฒํท๋ฆฌ์คํธ ํ์ด์ง๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
- ์น๊ตฌ ํ์ด์ง์์ ๋๋ค์์ผ๋ก ์ฌ์ฉ์๋ฅผ ๊ฒ์ํ๊ณ ์น๊ตฌ ์์ฒญ์ ๋ณด๋ผ ์ ์์ต๋๋ค.
- ํ๋กํ ๋ฐฐ์ง๋ฅผ ํด๋ฆญํ๋ฉด ๋ด ํ๋กํ ํ๋ฉด์ผ๋ก ์ด๋ํฉ๋๋ค.
- ํ๋กํ ํ๋ฉด์์ ๋ณ๊ฒฝ ๋ฒํผ์ ํด๋ฆญํด ํ๋ฆฌ์ ์๋ฐํ ์ค ์ํ๋ ์ฌ์ง์ผ๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
- ํ๋กํ ํ๋ฉด์์ ๋๋ค์ ๋ณ๊ฒฝ ๋ฒํผ์ ํด๋ฆญํด ์๋ก์ด ๋๋ค์์ผ๋ก ์์ ํ ์ ์์ต๋๋ค.
๋ณ๋ ๋ฐฑ์๋ ์๋ฒ ์์ด Next.js App Router ์์์ ์ธ์ฆยทDBยท์ธ๋ถ API๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ๋ ์๋ฒ๋ฆฌ์ค ์ํคํ ์ฒ์ ๋๋ค.
flowchart TD
User(["์ฌ์ฉ์\nBrowser / PWA"])
subgraph Vercel["Vercel โ Next.js 16"]
SSR["SSR / RSC\nํ์ด์ง ๋ ๋๋ง"]
API["API Routes\nPlaces ํ๋ก์ ยท Auth ์ฝ๋ฐฑ"]
SA["Server Actions\n๋ฒํท๋ฆฌ์คํธ CRUD"]
end
subgraph Supabase["Supabase"]
PG[("PostgreSQL")]
end
OAuth["Google / Kakao OAuth 2.0"]
Places["Google Places API\nAutocomplete ยท Details ยท Photos"]
User -->|HTTPS| SSR
User -->|OAuth ๋ก๊ทธ์ธ| OAuth
OAuth -->|"NextAuth v5 ์ฝ๋ฐฑ"| API
SSR --> SA
SA -->|"Prisma ORM"| PG
API -->|"Prisma ORM"| PG
API -->|"์๋ฒ ํ๋ก์"| Places
erDiagram
User {
String id PK
String email UK
String username UK
String name
String image
Boolean isOnboarded
Int tokenVersion
DateTime createdAt
DateTime updatedAt
}
Account {
String id PK
String userId FK
String provider
String providerAccountId
String type
}
Session {
String id PK
String userId FK
String sessionToken UK
DateTime expires
}
BucketList {
String id PK
String shareToken UK
String userId FK
String title
String description
Visibility visibility
DateTime deadlineAt
Int difficulty
Int excitement
Boolean achieved
DateTime achievedAt
String placeId
Float lat
Float lng
String countryCode
String displayName
DateTime createdAt
DateTime updatedAt
}
Friendship {
String id PK
String requesterId FK
String addresseeId FK
FriendshipStatus status
DateTime createdAt
DateTime respondedAt
}
User ||--o{ Account : "has"
User ||--o{ Session : "has"
User ||--o{ BucketList : "owns"
User ||--o{ Friendship : "sends"
User ||--o{ Friendship : "receives"
- ์ปดํฌ๋ํธ โ ๋ผ์ฐํธ๊ฐ ์๋ ๊ธฐ๋ฅ ๋จ์()๋ก ๊ตฌ์ฑ
- ๋ฐ์ดํฐ ๋ ์ด์ด โ
actions/(์ฐ๊ธฐ) ยทapp/api/(์ฝ๊ธฐยทํ๋ก์) ยทsrc/api/(ํด๋ผ์ด์ธํธ fetch) ์ธ ๋ ์ด์ด๋ก ๋ถ๋ฆฌ - ๋ผ์ฐํ โ Parallel + Intercepting Routes๋ก ๋ชจ๋ฌ์ URL ๊ธฐ๋ฐ์ผ๋ก ๊ด๋ฆฌ
LogLife/
โโโ prisma/
โ โโโ schema.prisma # DB ์คํค๋ง ์ ์ (UserยทBucketListยทFriendship ๋ฑ 5๊ฐ ๋ชจ๋ธ)
โโโ public/
โ โโโ avatars/ # 10์ข
ํ๋ฆฌ์
์๋ฐํ
โ โโโ geo/
โ โ โโโ countries-110m.json # ์ง๊ตฌ๋ณธ ๊ตญ๊ฐ ํด๋ฆฌ๊ณค ๋ฐ์ดํฐ
โ โโโ icons/
โ โโโ manifest.json # PWA manifest
โโโ src/
โ โโโ actions/ # Server Actions โ ๋๋ฉ์ธ๋ณ mutation
โ โโโ api/ # ํด๋ผ์ด์ธํธ fetch ํจ์ โ ๋๋ฉ์ธ๋ณ ํ์ผ๋ก ๋ถ๋ฅ
โ โโโ app/
โ โ โโโ (afterLogin)/
โ โ โ โโโ @modal/ # Parallel + Intercepting Routes (๋ชจ๋ฌ ์ค๋ฒ๋ ์ด)
โ โ โ โโโ friends/
โ โ โ โโโ main/
โ โ โ โโโ onboarding/
โ โ โ โโโ profile/
โ โ โโโ (auth)/
โ โ โ โโโ login/
โ โ โโโ (e2e)/ # E2E ํ
์คํธ ์ ์ฉ ๋ผ์ฐํธ
โ โ โโโ _providers/ # TanStack QueryยทNextAuth ๋ฑ ์ ์ญ Provider ๋ํผ
โ โ โโโ api/ # Route Handlers โ ๋๋ฉ์ธ๋ณ ์ฝ๊ธฐยทํ๋ก์ (authยทplaces ํฌํจ)
โ โ โโโ b/[token]/ # ๊ณต์ ํํ์ด์ง
โ โ โโโ u/[username]/ # ๊ณต๊ฐ ์ฌ์ฉ์ ํ์ด์ง
โ โ โโโ layout.tsx # ๋ฃจํธ ๋ ์ด์์ (ํฐํธยท๋ฉํ๋ฐ์ดํฐยทProvider ๋ง์ดํธ)
โ โ โโโ page.tsx # ๋๋ฉ ํ์ด์ง
โ โ โโโ sw.ts # PWA Service Worker
โ โโโ auth.ts # NextAuth v5 ์ค์ (OAuth ์ ๊ณต์ยท์ฝ๋ฐฑยท์ธ์
์ ๋ต)
โ โโโ components/ # ๊ธฐ๋ฅ ๋จ์(bucketยทdashboardยทfriendsยทglobeยทnav ๋ฑ)๋ก ๋ถ๋ฅ
โ โโโ lib/ # ์์ ์ ํธยท๋๋ฉ์ธ ๋ก์ง โ ๋๋ฉ์ธ๋ณ ๋ถ๋ฅ (bucketListยทfriendยทdate ๋ฑ)
โ โโโ types/ # next-auth ์ธ์
ํ์
ํ์ฅ ๋ฑ ์ ์ญ ๊ณต์ ํ์
โโโ tests/
โ โโโ e2e/
โ โโโ setup/ # globalSetup / teardown / auth
โ โโโ specs/ # E2E ์๋๋ฆฌ์ค
โโโ docs/ # ํ๋ก์ ํธ ๋ฌธ์
โ โโโ plan_spec.md # ๋น์ฆ๋์ค ๋๋ฉ์ธ ์ฌ์ ยท ADR ยท ํ์ด์ง ์ฌ์
โ โโโ cost_constraint.md # 0์ ์ด์ ์ ์ฝ ์ ์
โ โโโ templates/ # commit ยท issue ยท PR ๋ฉ์์ง ์์
โโโ .storybook/ # Storybook ์ค์ (addonยทwebpackยทpreview)
โโโ .claude/ # Claude Code ํ๋ค์ค ์ค์
โ โโโ rules/ # ์์
์ ํ๋ณ ๊ท์น ํ์ผ (code_styleยทsecurityยทdeployยทtesting ๋ฑ 8์ข
)
โ โโโ skills/ # ๋ก์ปฌ ์คํฌ ์ ์ (/commitยท/prยท/handoffยท/e2e ๋ฑ)
โ โโโ hooks/ # PreToolUseยทPostToolUse ์ด๋ฒคํธ ํ
์คํฌ๋ฆฝํธ
โ โโโ memory/ # ์ธ์
๊ฐ ์๋ ๋ฉ๋ชจ๋ฆฌ ์ ์ฅ์ (MEMORY.md + ๊ฐ๋ณ md ํ์ผ)
โ โโโ settings.json # ๋๊ตฌ ๊ถํยทํ๊ฒฝ๋ณ์ยทhooks ๋ฑ๋ก
โโโ .dev/ # AI ์์
ํ์ (git ์ถ์ ์ ์ธ)
โ โโโ learnings/ # ์์
์ค ๋ฐ๊ฒฌํ ํจํดยท์ด์ยท์ฌํ ์ด๋ ค์ ๋ ์ค๋ฅ ๊ธฐ๋ก
โ โโโ scratchpad/ # ์์ ๋ฉ๋ชจ (์์
์ข
๋ฃ ํ ์ญ์ โ ๋น์ด์๋ ๊ฒ ์ ์)
โโโ CLAUDE.md # AI ์์
์ง์นจยท๊ท์น ๋งต (์์
์ ํ๋
)
โโโ AGENTS.md # AI ์์ด์ ํธ ์ค์ ํ์ผ
โโโ proxy.ts # Next.js 16 ๋ฏธ๋ค์จ์ด ๋์ฒด ๋ผ์ฐํ
ํ๋ก์
โโโ next.config.ts # Next.js ๋น๋ยท์ด๋ฏธ์งยทPWA ์ค์
โโโ vitest.config.ts # unitยทstorybook ํ๋ก์ ํธ ๋ถ๋ฆฌ ํ
์คํธ ์ค์
โโโ package.json
flowchart TD
subgraph group_app["Next.js App"]
node_src_app_root["App shell<br/>nextjs shell<br/>[layout.tsx]"]
node_src_app_auth["Auth routes<br/>route group<br/>[page.tsx]"]
node_src_app_afterlogin["App routes<br/>route group<br/>[layout.tsx]"]
node_src_app_modal["Modal routes<br/>parallel routes<br/>[default.tsx]"]
node_src_app_e2e["E2E routes<br/>test routes<br/>[page.tsx]"]
end
subgraph group_ui["UI Components"]
node_src_store["Client stores<br/>state stores<br/>[globeStore.ts]"]
node_src_components_globe(("Globe view<br/>visualization UI<br/>[GlobeView.tsx]"))
node_src_components_bucket["Bucket tools<br/>feature UI"]
node_src_components_friends["Friends UI<br/>feature UI<br/>[FriendsView.tsx]"]
node_src_components_dashboard["Dashboard UI<br/>feature UI<br/>[DashboardPanel.tsx]"]
node_src_components_profile["Profile UI<br/>feature UI"]
node_src_components_user["Public profile UI<br/>feature UI"]
node_src_components_landing["Landing UI<br/>marketing UI<br/>[HeroContent.tsx]"]
node_src_components_shared["Shared UI<br/>base UI<br/>[Button.tsx]"]
end
subgraph group_logic["Domain Logic"]
node_src_lib_domain["Domain helpers<br/>pure logic<br/>[bucketStatus.ts]"]
end
subgraph group_data["Data Layer"]
node_src_app_api_auth["Auth callback<br/>api route<br/>[route.ts]"]
node_src_app_api_data["Read APIs<br/>api routes<br/>[route.ts]"]
node_src_actions["Server actions<br/>mutation layer<br/>[actions.ts]"]
node_src_auth["NextAuth setup<br/>auth config<br/>[auth.ts]"]
node_src_lib_prisma[("Prisma access<br/>db client<br/>[prisma.ts]")]
node_prisma_schema["DB schema<br/>[schema.prisma]"]
end
subgraph group_workflow["Workflow"]
node_tests_workflow["Tests<br/>quality stack<br/>[vitest.config.ts]"]
node_ops_workflow["Dev workflow<br/>tooling rules<br/>[CLAUDE.md]"]
end
node_src_app_root -->|"routes to"| node_src_app_auth
node_src_app_root -->|"hosts"| node_src_app_afterlogin
node_src_app_afterlogin -->|"overlays"| node_src_app_modal
node_src_app_afterlogin -->|"renders"| node_src_components_globe
node_src_app_afterlogin -->|"renders"| node_src_components_dashboard
node_src_app_afterlogin -->|"renders"| node_src_components_friends
node_src_app_afterlogin -->|"renders"| node_src_components_profile
node_src_app_afterlogin -->|"renders"| node_src_components_bucket
node_src_app_auth -->|"uses"| node_src_auth
node_src_app_api_auth -->|"calls"| node_src_auth
node_src_app_api_data -->|"reads/writes"| node_src_lib_prisma
node_src_actions -->|"mutates"| node_src_lib_prisma
node_src_lib_prisma -->|"implements"| node_prisma_schema
node_src_app_api_data -->|"computes"| node_src_lib_domain
node_src_actions -->|"validates"| node_src_lib_domain
node_src_components_globe -->|"uses"| node_src_store
node_src_components_bucket -->|"fetches"| node_src_app_api_data
node_src_components_friends -->|"fetches"| node_src_app_api_data
node_src_components_dashboard -->|"fetches"| node_src_app_api_data
node_src_components_profile -->|"submits"| node_src_actions
node_src_components_user -->|"fetches"| node_src_app_api_data
node_src_components_landing -->|"reuses"| node_src_components_globe
node_tests_workflow -.->|"covers"| node_src_components_shared
node_tests_workflow -.->|"stabilizes"| node_src_app_e2e
node_ops_workflow -.->|"guides"| node_src_actions
click node_src_app_root "https://github.com/coral0723/loglife/blob/main/src/app/layout.tsx"
click node_src_app_auth "https://github.com/coral0723/loglife/blob/main/src/app/(auth)/login/page.tsx"
click node_src_app_afterlogin "https://github.com/coral0723/loglife/blob/main/src/app/(afterLogin)/layout.tsx"
click node_src_app_modal "https://github.com/coral0723/loglife/blob/main/src/app/(afterLogin)/@modal/default.tsx"
click node_src_app_e2e "https://github.com/coral0723/loglife/blob/main/src/app/(e2e)/e2e-login/page.tsx"
click node_src_app_api_auth "https://github.com/coral0723/loglife/blob/main/src/app/api/auth/[...nextauth]/route.ts"
click node_src_app_api_data "https://github.com/coral0723/loglife/blob/main/src/app/api/bucketlists/[id]/route.ts"
click node_src_actions "https://github.com/coral0723/loglife/blob/main/src/actions/user/actions.ts"
click node_src_auth "https://github.com/coral0723/loglife/blob/main/src/auth.ts"
click node_src_lib_prisma "https://github.com/coral0723/loglife/blob/main/src/lib/prisma.ts"
click node_prisma_schema "https://github.com/coral0723/loglife/blob/main/prisma/schema.prisma"
click node_src_lib_domain "https://github.com/coral0723/loglife/blob/main/src/lib/bucketList/bucketStatus.ts"
click node_src_store "https://github.com/coral0723/loglife/blob/main/src/store/globeStore.ts"
click node_src_components_globe "https://github.com/coral0723/loglife/blob/main/src/components/globe/GlobeView.tsx"
click node_src_components_bucket "https://github.com/coral0723/loglife/blob/main/src/components/bucket/BucketDetailView.tsx"
click node_src_components_friends "https://github.com/coral0723/loglife/blob/main/src/components/friends/FriendsView.tsx"
click node_src_components_dashboard "https://github.com/coral0723/loglife/blob/main/src/components/dashboard/DashboardPanel.tsx"
click node_src_components_profile "https://github.com/coral0723/loglife/blob/main/src/components/profile/ProfileSettingsView.tsx"
click node_src_components_user "https://github.com/coral0723/loglife/blob/main/src/components/user/PublicProfileView.tsx"
click node_src_components_landing "https://github.com/coral0723/loglife/blob/main/src/components/landing/HeroContent.tsx"
click node_src_components_shared "https://github.com/coral0723/loglife/blob/main/src/components/ui/Button.tsx"
click node_tests_workflow "https://github.com/coral0723/loglife/blob/main/vitest.config.ts"
click node_ops_workflow "https://github.com/coral0723/loglife/blob/main/CLAUDE.md"
classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_src_app_root,node_src_app_auth,node_src_app_afterlogin,node_src_app_modal,node_src_app_e2e toneBlue
class node_src_store,node_src_components_globe,node_src_components_bucket,node_src_components_friends,node_src_components_dashboard,node_src_components_profile,node_src_components_user,node_src_components_landing,node_src_components_shared toneAmber
class node_src_lib_domain toneMint
class node_src_app_api_auth,node_src_app_api_data,node_src_actions,node_src_auth,node_src_lib_prisma,node_prisma_schema toneRose
class node_tests_workflow,node_ops_workflow toneIndigo
flowchart TD
User(["๐ค ์ฌ์ฉ์"])
subgraph P1["โ ๊ณํ โ ์น์ธ โ ๊ตฌํ"]
Plan["Plan Mode\n๊ณํ ์๋ฆฝ"]
Approve{"์ฌ์ฉ์ ์น์ธ"}
Impl["๊ตฌํ ์์
\nClaude Code"]
end
subgraph P2["โก ์ญํ ๋ณ AI ๋ถ๋ฆฌ"]
subgraph Auto["์๋ ์์ โ OMC"]
direction LR
explore["explore"]
executor["executor"]
debugger["debugger"]
end
subgraph Gates["์๋ ๊ฒ์ฆ ๊ฒ์ดํธ โ ์ ์ธ์
"]
direction LR
test["/test\ntest-engineer"]
e2e["/e2e\nqa-tester"]
sec["/security-review\nsecurity-reviewer"]
qual["/quality-review\ncode-reviewer"]
end
Gemini["Gemini Code Assistant\n๊ต์ฐจ ๋ฆฌ๋ทฐ"]
end
subgraph P3["โข ๋ก๊ทธ ํ์ดํ๋ผ์ธ"]
direction LR
Hooks["ํ
์๋ ์์ง\nUserPromptSubmit ยท PostToolUse"]
JSONL[".dev/session-logs/*.jsonl"]
NotionLog["Notion DB\n/sessionlog ยท /branchlog"]
end
subgraph P4["โฃ ์ง์ ๋์ ๋ฃจํ"]
direction LR
Learnings["/learnings\n.dev/learnings/"]
Rules[".claude/rules/\nknown_issues ยท code_style ยท security ยท testing ยท deploy"]
end
User --> Plan
Plan --> Approve
Approve -->|๋ฐ๋ ค| Plan
Approve -->|์น์ธ| Impl
Impl <-->|๋ณต์กํ ์์
์๋ ๋ถํด| Auto
Impl -->|๋จ๊ณ ์๋ฃ| Gates
Gates -->|PR ๋จ๊ณ| Gemini
Auto ~~~ Hooks
Impl --> Hooks
Hooks --> JSONL --> NotionLog
Hooks ~~~ Learnings
Impl -->|์ค์ ๋ฐ๋ณต| Learnings
Learnings --> Rules
Rules -.->|๋ค์ ์ธ์
์๋ ์ฃผ์
| Impl
AI๋ ์ฆ์ ๊ตฌํํ๋ ค๋ ๊ฒฝํฅ์ด ์๊ธฐ์ ๋ฐฉํฅ์ด ํ๋ฆฐ ์ฑ ์์
์ด ๋๋๋ฉด ๋๋๋ฆฌ๋ ๋น์ฉ์ด ํฝ๋๋ค.
๊ทธ๋์ ์๋์ ๋ฐฉ๋ฒ์ผ๋ก ์์
์ ์งํํ์ต๋๋ค.
- ๊ท์นํ: CLAUDE.md์ Karpathy 4์์น๊ณผ "Plan Mode ์ฐ์ , ์น์ธ ์ ๊ตฌํ ๊ธ์ง" ๋ช ์
- ์ด์: ๊ธฐ๋ฅ ์ธ์ ๋ง๋ค Plan Mode ์ง์ โ ๊ณํ ์๋ฆฝ โ ์ฌ์ฉ์ ์น์ธ โ ๊ตฌํ ์์ ์ค์
- ์ปจํ ์คํธ ๊ฒฉ๋ฆฌ: ๋ค๋ฅธ ์ญํ ์์ด์ ํธ๋ ํญ์ ์ ์ธ์ ์ผ๋ก ์ ํ โ ๊ตฌํ ์ปจํ ์คํธ ์ค์ผ ๋ฐฉ์ง
- ์๋ ์์: ๊ตฌํ ์ค OMC๊ฐ
exploreยทexecutor๋ฑ ์๋ธ์์ด์ ํธ๋ฅผ ์๋ ์ ํํด ๋ณต์ก ์์ ์ ์ ๋ฌธ ์ญํ ๋ก ๋ถํด - ์๋ ๊ฒ์ฆ ๊ฒ์ดํธ: ๋จ๊ณ๋ณ ์ ์ฉ ์คํฌ ์๋ ํธ์ถ:
/test(test-engineer) โ ์ฝ๋ ์์ฑ ํ/e2e(qa-tester) โ ๊ธฐ๋ฅ ํ๋ฆ ์์ฑ ํ/security-review(security-reviewer) โ auth ยท api ์์ ํ/quality-review(code-reviewer) โ PR ์
- ๊ต์ฐจ ๋ฆฌ๋ทฐ: PR ๋จ๊ณ์์ Gemini Code Assistant ์ถ๊ฐ โ ๋์ผ AI ํธํฅ ํด์
- ํฌ์ฐฉ:
/learnings์คํฌ๋ก.dev/learnings/YYYY-MM-DD_{topic}.md์ ์ฆ์ ยท ์์ธ ยท ๊ฒฐ๋ก ๊ตฌ์กฐํ - ์์ถ: ํต์ฌ 1~2์ค๋ก ์์ฝ ํ ์ ํ๋ณ md ํ์ผ์ ๋์ :
- ๋ฒ๊ทธ ยท ํ๊ฒฝ โ
known_issues.md - ์ฝ๋ฉ ์คํ์ผ โ
code_style.md - ํ
์คํธ โ
testing_guide.md - ๋ณด์ โ
security.md - ๋ฐฐํฌ โ
deploy.md
- ๋ฒ๊ทธ ยท ํ๊ฒฝ โ
- ์๋ ํ์ฑํ: CLAUDE.md์ ๋งคํ ๋ช
์ โ ๋ค์ ์ธ์
๋ถํฐ ์๋ ์ฃผ์
. ์ด์ ์ฆ์ ๋ฐ๊ฒฌ ์
known_issues.md์ฐ์ ํ์ธ
- ํ
์๋ ์์ง:
UserPromptSubmitยทPostToolUse์ ํ๋กฌํํธ ํ ์คํธ ยท ํ์ผ ์์ ยท ๋ช ๋ น์ด ์คํ์.dev/session-logs/{๋ธ๋์น}/{YYYY-MM-DD}_{์ธ์ ID ์ 8์}.jsonl์ ์ค์๊ฐ ๊ธฐ๋ก - ์ธ์
๋ก๊ทธ(
/sessionlog): โ JSONL์ ์ ํํ๋ฉด Notion "SessionLog" DB์ ์ฑํฐ๋ณ ์ ๋ฆฌ - ๋ธ๋์น ๋ก๊ทธ(
/branchlog): โgit diffยทgit log๊ธฐ๋ฐ ๋ถ์ยท์ ๋ฆฌ ํ Notion "BranchLog" DB์ ๊ธฐ๋ก./pr์คํ ์ ํฐ ์์ ๋ธ๋์น๋ก ํ๋จ๋๋ฉด ์๋ ๊ถ์ฅ
Node.js 20.9+
pnpm 10+
.env.example์ ๋ณต์ฌํด .env ํ์ผ์ ์์ฑํ๊ณ ์๋ ๊ฐ์ ์ฑ์ด๋ค.
# Supabase PostgreSQL
DATABASE_URL="postgresql://user:password@host/dbname?sslmode=verify-full"
# NextAuth v5
AUTH_SECRET=""
AUTH_GOOGLE_ID=""
AUTH_GOOGLE_SECRET=""
AUTH_KAKAO_ID=""
AUTH_KAKAO_SECRET=""
# Google Places API (์๋ฒ ์ ์ฉ)
GOOGLE_PLACES_API_KEY=""๋ก์ปฌ DB ์ค์น ๋ถํ์ โ Vercel Neon(์๋ฒ๋ฆฌ์ค PostgreSQL)์ ์ง์ ์ฐ๊ฒฐ
pnpm install # ํจํค์ง ์ค์น + prisma generate (postinstall ์๋ ์คํ)
pnpm prisma migrate deploy # ๋ง์ด๊ทธ๋ ์ด์
Neon DB์ ์ ์ฉpnpm devhttp://localhost:3000 ์์ ํ์ธ
pnpm test # ๋จ์ ํ
์คํธ (Vitest)
pnpm test:e2e:ui # E2E ํ
์คํธ (Playwright UI ๋ชจ๋)
pnpm storybook # ์ปดํฌ๋ํธ ์นดํ๋ก๊ทธ (ํฌํธ 6006)









