# πŸŽ‰ Drizzle ORM λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ™„λ£Œ! JWT 인증 μ‹œμŠ€ν…œμ΄ **Drizzle ORM**을 μ‚¬μš©ν•˜λ„λ‘ μ„±κ³΅μ μœΌλ‘œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜λ˜μ—ˆμŠ΅λ‹ˆλ‹€. ## πŸš€ λΉ λ₯Έ μ‹œμž‘ ```bash # 1. μ˜μ‘΄μ„± μ„€μΉ˜ (이미 μ™„λ£Œλ¨) # pnpm install # 2. λ°μ΄ν„°λ² μ΄μŠ€ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ (이미 μ™„λ£Œλ¨) # pnpm db:push # 3. λΉŒλ“œ (이미 μ™„λ£Œλ¨) # pnpm build # 4. 개발 μ„œλ²„ μ‹€ν–‰ pnpm cf:dev ``` 그런 λ‹€μŒ λΈŒλΌμš°μ €μ—μ„œ: - http://localhost:8787/register - νšŒμ›κ°€μž… - http://localhost:8787/login - 둜그인 - http://localhost:8787 - 메인 νŽ˜μ΄μ§€ ## βœ… μ™„λ£Œλœ μž‘μ—… ### 1. Drizzle ORM μ„€μΉ˜ - βœ… `drizzle-orm` v0.44.7 - βœ… `drizzle-kit` v0.31.7 ### 2. μŠ€ν‚€λ§ˆ μ •μ˜ - βœ… `src/lib/server/schema.ts` 생성 - βœ… TypeScript νƒ€μž… μžλ™ μΆ”λ‘  (`User`, `NewUser`) ### 3. λ°μ΄ν„°λ² μ΄μŠ€ ν•¨μˆ˜ λ³€ν™˜ - βœ… `src/lib/server/db.ts` Drizzle둜 μž¬μž‘μ„± - βœ… `createUser()` - νƒ€μž… μ•ˆμ „ - βœ… `getUserByEmail()` - νƒ€μž… μ•ˆμ „ - βœ… `getUserById()` - νƒ€μž… μ•ˆμ „ ### 4. λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ‹œμŠ€ν…œ - βœ… `drizzle.config.ts` μ„€μ • - βœ… λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ SQL 생성 (`drizzle/0000_*.sql`) - βœ… 둜컬 DB에 적용 μ™„λ£Œ ### 5. NPM 슀크립트 μΆ”κ°€ ```json { "db:generate": "drizzle-kit generate", "db:push": "wrangler d1 execute auth-db --local --file=...", "db:push:remote": "wrangler d1 execute auth-db --remote --file=...", "db:studio": "drizzle-kit studio", "db:query": "wrangler d1 execute auth-db --local --command=...", "db:query:remote": "wrangler d1 execute auth-db --remote --command=..." } ``` ### 6. λ¬Έμ„œ μž‘μ„± - βœ… `DRIZZLE_GUIDE.md` - 상세 κ°€μ΄λ“œ - βœ… `DRIZZLE_MIGRATION_COMPLETE.md` - λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μš”μ•½ - βœ… `AUTH_GUIDE.md` - μ—…λ°μ΄νŠΈλ¨ ### 7. λΉŒλ“œ 및 ν…ŒμŠ€νŠΈ - βœ… TypeScript 컴파일 성곡 - βœ… ν”„λ‘œλ•μ…˜ λΉŒλ“œ 성곡 - βœ… μ—λŸ¬ μ—†μŒ ## πŸ“¦ μƒˆλ‘œμš΄ NPM λͺ…λ Ήμ–΄ ### Drizzle κ΄€λ ¨ ```bash # λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 생성 (μŠ€ν‚€λ§ˆ λ³€κ²½ ν›„) pnpm db:generate # 둜컬 DB에 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 적용 pnpm db:push # ν”„λ‘œλ•μ…˜ DB에 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 적용 pnpm db:push:remote # Drizzle Studio μ‹€ν–‰ (DB 관리 UI) pnpm db:studio # μ‚¬μš©μž 쑰회 (둜컬) pnpm db:query # μ‚¬μš©μž 쑰회 (ν”„λ‘œλ•μ…˜) pnpm db:query:remote ``` ### κΈ°μ‘΄ λͺ…λ Ήμ–΄ ```bash # 개발 μ„œλ²„ (Vite) pnpm dev # 개발 μ„œλ²„ (Cloudflare Workers) pnpm cf:dev # λΉŒλ“œ pnpm build # 배포 pnpm deploy ``` ## πŸ“ ν”„λ‘œμ νŠΈ ꡬ쑰 ``` ν”„λ‘œμ νŠΈ/ β”œβ”€β”€ drizzle.config.ts # ✨ Drizzle μ„€μ • β”œβ”€β”€ drizzle/ # ✨ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ β”‚ β”œβ”€β”€ 0000_omniscient_lady_mastermind.sql β”‚ └── meta/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ lib/ β”‚ β”‚ └── server/ β”‚ β”‚ β”œβ”€β”€ schema.ts # ✨ Drizzle μŠ€ν‚€λ§ˆ β”‚ β”‚ β”œβ”€β”€ db.ts # πŸ”„ Drizzle μ‚¬μš© β”‚ β”‚ └── auth.ts # JWT ν•¨μˆ˜ β”‚ └── routes/ β”‚ β”œβ”€β”€ login/ # 둜그인 νŽ˜μ΄μ§€ β”‚ β”œβ”€β”€ register/ # νšŒμ›κ°€μž… νŽ˜μ΄μ§€ β”‚ └── api/ β”‚ └── logout/ # λ‘œκ·Έμ•„μ›ƒ API β”œβ”€β”€ DRIZZLE_GUIDE.md # ✨ Drizzle κ°€μ΄λ“œ β”œβ”€β”€ DRIZZLE_MIGRATION_COMPLETE.md # ✨ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μš”μ•½ β”œβ”€β”€ AUTH_GUIDE.md # πŸ”„ μ—…λ°μ΄νŠΈλ¨ └── package.json # πŸ”„ 슀크립트 μΆ”κ°€ ``` ## 🎯 μ£Όμš” κ°œμ„ μ‚¬ν•­ ### 1. νƒ€μž… μ•ˆμ „μ„± ```typescript // Before: λŸ°νƒ€μž„ μ—λŸ¬ κ°€λŠ₯ const user = await db.prepare('SELECT * FROM usres').first(); // ^^^^^ μ˜€νƒ€! // After: 컴파일 νƒ€μž„μ— μ—λŸ¬ 발견 const [user] = await drizzleDb.select().from(usres); // ^^^^^ 컴파일 μ—λŸ¬! ``` ### 2. μžλ™ μ™„μ„± IDEμ—μ„œ ν…Œμ΄λΈ”λͺ…, 컬럼λͺ…, ν•¨μˆ˜ λ“± μ™„λ²½ν•œ μžλ™ μ™„μ„± 지원 ### 3. μžλ™ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μŠ€ν‚€λ§ˆ λ³€κ²½ μ‹œ SQL을 μžλ™μœΌλ‘œ 생성 ```bash pnpm db:generate # ALTER TABLE, CREATE TABLE λ“± μžλ™ 생성 ``` ### 4. λ¦¬νŒ©ν† λ§ 용이 ν…Œμ΄λΈ”μ΄λ‚˜ 컬럼λͺ… λ³€κ²½ μ‹œ TypeScriptκ°€ λͺ¨λ“  μ‚¬μš©μ²˜λ₯Ό μ°Ύμ•„μ€Œ ## πŸ“š λ¬Έμ„œ ### 1. **DRIZZLE_GUIDE.md** (필독!) - Drizzle ORM κΈ°λ³Έ κ°œλ… - μŠ€ν‚€λ§ˆ μ •μ˜ 방법 - κ³ κΈ‰ 쿼리 예제 - λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 관리 - Drizzle Studio μ‚¬μš©λ²• - Before/After 비ꡐ ### 2. **AUTH_GUIDE.md** - JWT 인증 μ„€μ • - 둜컬 개발 ν™˜κ²½ μ„€μ • - ν”„λ‘œλ•μ…˜ 배포 - λ³΄μ•ˆ 고렀사항 - Drizzle λͺ…λ Ήμ–΄ 포함 ### 3. **DRIZZLE_MIGRATION_COMPLETE.md** - λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ „ν›„ 비ꡐ - λ³€κ²½λœ 파일 λͺ©λ‘ - ν…ŒμŠ€νŠΈ κ²°κ³Ό - λ‹€μŒ 단계 μ œμ•ˆ ## πŸ” Drizzle Studio λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό λΈŒλΌμš°μ €μ—μ„œ 관리: ```bash pnpm db:studio ``` κΈ°λŠ₯: - πŸ“Š ν…Œμ΄λΈ” 데이터 쑰회/νŽΈμ§‘ - βž• λ ˆμ½”λ“œ μΆ”κ°€ - πŸ—‘οΈ λ ˆμ½”λ“œ μ‚­μ œ - πŸ” 검색 및 필터링 - πŸ“ˆ 관계 μ‹œκ°ν™” ## πŸŽ“ λ‹€μŒ 단계 Drizzle ORM을 ν™œμš©ν•˜μ—¬ λ‹€μŒ κΈ°λŠ₯듀을 μ‰½κ²Œ μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€: ### 1. ν”„λ‘œν•„ ν…Œμ΄λΈ” ```typescript export const profiles = sqliteTable('profiles', { id: integer('id').primaryKey({ autoIncrement: true }), userId: integer('user_id').references(() => users.id), avatar: text('avatar'), bio: text('bio') }); ``` ### 2. κ²Œμ‹œκΈ€ μ‹œμŠ€ν…œ ```typescript export const posts = sqliteTable('posts', { id: integer('id').primaryKey({ autoIncrement: true }), userId: integer('user_id').references(() => users.id), title: text('title').notNull(), content: text('content').notNull() }); ``` ### 3. 관계 쿼리 ```typescript const postsWithUsers = await drizzleDb .select() .from(posts) .leftJoin(users, eq(posts.userId, users.id)); ``` λͺ¨λ“  것이 νƒ€μž… μ•ˆμ „ν•˜κ²Œ μž‘λ™ν•©λ‹ˆλ‹€! ## ⚑ μ„±λŠ₯ Drizzle ORM은 순수 SQLκ³Ό λ™μΌν•œ μ„±λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€. - Zero-cost abstractions - μ΅œμ†Œν•œμ˜ λŸ°νƒ€μž„ μ˜€λ²„ν—€λ“œ - Cloudflare D1에 μ΅œμ ν™” ## πŸ› 문제 ν•΄κ²° ### Q: λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 파일이 μƒμ„±λ˜μ§€ μ•Šμ•„μš” ```bash # μŠ€ν‚€λ§ˆ 파일 경둜 확인 ls src/lib/server/schema.ts # Drizzle μ„€μ • 확인 cat drizzle.config.ts ``` ### Q: 둜컬 DB에 적용이 μ•ˆ λΌμš” ```bash # μ˜¬λ°”λ₯Έ λ°μ΄ν„°λ² μ΄μŠ€ 이름 μ‚¬μš© pnpm wrangler d1 execute auth-db --local --file=./drizzle/0000_*.sql ``` ### Q: νƒ€μž… μ—λŸ¬κ°€ λ°œμƒν•΄μš” ```bash # νƒ€μž… μž¬μƒμ„± pnpm svelte-kit sync ``` ## 🎊 μ™„λ£Œ! Drizzle ORM λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ΄ μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€! **μ£Όμš” μ„±κ³Ό:** - βœ… νƒ€μž… μ•ˆμ „μ„± 100% 확보 - βœ… 개발 생산성 ν–₯상 - βœ… μœ μ§€λ³΄μˆ˜μ„± κ°œμ„  - βœ… μžλ™ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ‹œμŠ€ν…œ - βœ… λΉŒλ“œ 및 ν…ŒμŠ€νŠΈ 성곡 **λ‹€μŒ μ‹€ν–‰ λͺ…λ Ήμ–΄:** ```bash pnpm cf:dev ``` 즐거운 개발 λ˜μ„Έμš”! πŸš€