@nago730/chatbot-library 1.1.0 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,392 +1,392 @@
1
- # @nago730/chatbot-library
2
-
3
- > **JSON 하나로 만드는 프로덕션 레디 챗봇 엔진** — React 환경에서 복잡한 대화형 인터페이스를 5분 안에 구축하세요.
4
-
5
- <p align="left">
6
- <img src="https://img.shields.io/npm/v/@nago730/chatbot-library" alt="npm version" />
7
- <img src="https://img.shields.io/github/license/Nago730/chatbot-library" alt="license" />
8
- <img src="https://img.shields.io/npm/dm/@nago730/chatbot-library" alt="downloads" />
9
- </p>
10
-
11
- ---
12
-
13
- ## 🎯 핵심 기능 3가지
14
-
15
- | 기능 | 설명 | 효과 |
16
- |------|------|------|
17
- | 🗂️ **JSON 기반 시나리오** | 코드 없이 대화 흐름 설계 | 개발 시간 **90% 단축** |
18
- | 🔄 **멀티 세션 관리** | 한 사용자가 여러 상담 진행 | 사용자 경험 **향상** |
19
- | 🔥 **프로덕션 레디** | Firebase 연동 + 비용 최적화 | 운영 비용 **98% 절감** |
20
-
21
- ---
22
-
23
- ## ⚡ 5분 빠른 시작
24
-
25
- ### 1. 설치
26
-
27
- ```bash
28
- npm install @nago730/chatbot-library
29
- ```
30
-
31
- ### 2. Flow 정의 (JSON)
32
-
33
- ```typescript
34
- const SUPPORT_FLOW = {
35
- start: {
36
- id: 'start',
37
- question: '무엇을 도와드릴까요?',
38
- type: 'button',
39
- options: ['주문 문의', '배송 조회', '취소/환불'],
40
- next: (answer) => {
41
- if (answer === '주문 문의') return 'order';
42
- if (answer === '배송 조회') return 'delivery';
43
- return 'refund';
44
- }
45
- },
46
- order: {
47
- id: 'order',
48
- question: '주문번호를 입력해주세요',
49
- type: 'input',
50
- next: 'complete'
51
- },
52
- complete: {
53
- id: 'complete',
54
- question: '감사합니다. 곧 연락드리겠습니다.',
55
- next: '',
56
- isEnd: true
57
- }
58
- };
59
- ```
60
-
61
- ### 3. 컴포넌트에서 사용
62
-
63
- ```tsx
64
- import { useChat } from '@nago730/chatbot-library';
65
-
66
- function ChatBot() {
67
- const { node, submitAnswer, submitInput, messages, isEnd } = useChat(
68
- SUPPORT_FLOW,
69
- 'user_123'
70
- );
71
-
72
- if (isEnd) {
73
- return <div>✅ {node.question}</div>;
74
- }
75
-
76
- return (
77
- <div>
78
- {/* 대화 히스토리 */}
79
- {messages.map((msg, i) => (
80
- <div key={i}>
81
- <p>🤖 {msg.question}</p>
82
- <p>👤 {msg.answer}</p>
83
- </div>
84
- ))}
85
-
86
- {/* 현재 질문 */}
87
- <p>{node.question}</p>
88
-
89
- {/* 버튼형 */}
90
- {node.type === 'button' && node.options?.map(opt => (
91
- <button key={opt} onClick={() => submitAnswer(opt)}>
92
- {opt}
93
- </button>
94
- ))}
95
-
96
- {/* 입력형 */}
97
- {node.type === 'input' && (
98
- <input onKeyDown={(e) => {
99
- if (e.key === 'Enter') submitInput(e.currentTarget.value);
100
- }} />
101
- )}
102
- </div>
103
- );
104
- }
105
- ```
106
-
107
- **🎉 완료!** 이제 작동하는 챗봇이 생겼습니다.
108
-
109
- ---
110
-
111
- ## 📚 핵심 개념
112
-
113
- ### Flow 구조
114
-
115
- Flow는 **노드(Node)의 집합**입니다. 각 노드는 질문과 다음 단계를 정의합니다.
116
-
117
- ```typescript
118
- interface ChatNode {
119
- id: string; // 고유 ID
120
- question: string; // 사용자에게 보여줄 질문
121
- type?: 'button' | 'input'; // 답변 받는 방식 (기본: button)
122
- options?: string[]; // 선택지 (type='button'일 때)
123
- next: string | ((answer) => string); // 다음 노드 ID (동적 가능)
124
- isEnd?: boolean; // 대화 종료 표시
125
- }
126
- ```
127
-
128
- ### 세션 관리
129
-
130
- 한 사용자가 **여러 번 상담**을 시작할 수 있습니다.
131
-
132
- ```typescript
133
- const { sessionId, reset } = useChat(FLOW, userId, 'start', adapter, {
134
- sessionId: 'auto' // 'auto' | 'new' | 'specific_id'
135
- });
136
-
137
- // 새 상담 시작
138
- <button onClick={() => reset()}>새 상담</button>
139
- ```
140
-
141
- ### 저장 전략
142
-
143
- ```typescript
144
- const chat = useChat(FLOW, userId, 'start', adapter, {
145
- saveStrategy: 'onEnd' // 'always' | 'onEnd'
146
- });
147
- ```
148
-
149
- | 전략 | 저장 시점 | 추천 대상 |
150
- |------|-----------|-----------|
151
- | `'always'` | 매 답변마다 | 데이터 무결성이 중요한 경우 |
152
- | `'onEnd'` | 대화 종료 시 | **비용 절감** (권장) |
153
-
154
- ---
155
-
156
- ## 🔥 Firebase 연동 (프로덕션)
157
-
158
- ### Quick Start
159
-
160
- ```typescript
161
- import { createHybridFirebaseAdapter } from '@nago730/chatbot-library/examples';
162
- import { getFirestore } from 'firebase/firestore';
163
-
164
- const db = getFirestore(app);
165
- const adapter = createHybridFirebaseAdapter(db, {
166
- timeout: 5000,
167
- fallbackToLocal: true,
168
- debug: false
169
- });
170
-
171
- const chat = useChat(FLOW, userId, 'start', adapter, {
172
- saveStrategy: 'onEnd' // 비용 98% 절감!
173
- });
174
- ```
175
-
176
- ### 비용 최적화
177
-
178
- **10만 사용자, 일 10회 대화 기준 (Firestore)**
179
-
180
- | 구성 | 월 비용 | 절감율 |
181
- |------|---------|--------|
182
- | 기본 설정 (always + 전체 데이터) | $2,700 | - |
183
- | **하이브리드 + onEnd** ⭐ | **$5.4** | **99.8%** |
184
-
185
- ### 핵심 개선사항
186
-
187
- - ✅ **기기 전환 복구**: PC → 모바일 대화 이어가기 100%
188
- - ✅ **네트워크 안정성**: 타임아웃 + 자동 폴백
189
- - ✅ **타입 안전**: Firebase Timestamp 자동 정규화
190
- - ✅ **비용 최적화**: 스마트 저장 전략
191
-
192
- 📖 [Firebase 상세 가이드](./docs/firebase-adapter-guide.md)
193
-
194
- ---
195
-
196
- ## 🔄 멀티 세션
197
-
198
- 한 사용자가 **여러 상담을 진행**하고 **이전 대화를 불러올** 수 있습니다.
199
-
200
- ```typescript
201
- const { sessionId, reset, isEnd } = useChat(FLOW, userId, 'start', adapter, {
202
- sessionId: 'auto'
203
- });
204
-
205
- // UI 예제
206
- <div>
207
- <p>현재 세션: {sessionId}</p>
208
-
209
- {isEnd && (
210
- <button onClick={() => reset()}>
211
- 새 상담 시작
212
- </button>
213
- )}
214
-
215
- <button onClick={() => reset('session_1706000000_abc')}>
216
- 이전 상담 보기
217
- </button>
218
- </div>
219
- ```
220
-
221
- 📖 [멀티 세션 완벽 가이드](./docs/multi-session-guide.md)
222
-
223
- ---
224
-
225
- ## 📖 API Reference
226
-
227
- ### useChat
228
-
229
- ```typescript
230
- useChat(
231
- flow: Record<string, ChatNode>,
232
- userId: string,
233
- initialNodeId?: string,
234
- adapter?: StorageAdapter,
235
- options?: ChatOptions
236
- )
237
- ```
238
-
239
- #### Parameters
240
-
241
- | 파라미터 | 타입 | 설명 |
242
- |----------|------|------|
243
- | `flow` | `Record<string, ChatNode>` | 시나리오 Flow 객체 |
244
- | `userId` | `string` | 사용자 ID (세션 키로 사용) |
245
- | `initialNodeId` | `string` | 시작 노드 ID (기본: `'start'`) |
246
- | `adapter` | `StorageAdapter` | 저장소 어댑터 (선택) |
247
- | `options` | `ChatOptions` | 추가 옵션 (선택) |
248
-
249
- #### ChatOptions
250
-
251
- ```typescript
252
- interface ChatOptions {
253
- saveStrategy?: 'always' | 'onEnd'; // 저장 시점
254
- scenarioId?: string; // 시나리오 ID
255
- sessionId?: 'auto' | 'new' | string; // 세션 전략
256
- }
257
- ```
258
-
259
- #### Return Values
260
-
261
- ```typescript
262
- {
263
- node: ChatNode; // 현재 노드
264
- submitAnswer: (value: any) => Promise<void>; // 버튼 답변 제출
265
- submitInput: (value: string) => Promise<void>; // 텍스트 답변 제출
266
- answers: Record<string, any>; // 수집된 답변
267
- messages: ChatMessage[]; // 대화 히스토리
268
- isEnd: boolean; // 종료 여부
269
- sessionId: string; // 현재 세션 ID
270
- reset: (sessionId?: string) => void; // 세션 리셋
271
- }
272
- ```
273
-
274
- ### StorageAdapter
275
-
276
- ```typescript
277
- interface StorageAdapter {
278
- saveState: (userId: string, state: ChatState) => Promise<void>;
279
- loadState: (userId: string) => Promise<ChatState | null>;
280
- }
281
- ```
282
-
283
- ---
284
-
285
- ## 📚 전체 문서
286
-
287
- ### 가이드
288
- - 📘 [**Complete Guide**](./docs/complete-guide.md) - 모든 기능 + 실전 패턴
289
- - 🔥 [Firebase Adapter Guide](./docs/firebase-adapter-guide.md)
290
- - 🔄 [Multi-Session Guide](./docs/multi-session-guide.md)
291
- - ⚡ [Quick Reference](./docs/firebase-quick-reference.md)
292
-
293
- ### 학습 자료
294
- - ✅ [Best Practices](./docs/best-practices.md) - DO's & DON'Ts
295
- - 💡 [Examples](./docs/examples.md) - 실전 코드 모음
296
- - 🔧 [예제 코드](./src/examples/)
297
-
298
- ---
299
-
300
- ## ⚠️ Common Pitfalls
301
-
302
- 개발 시 자주 발생하는 실수들:
303
-
304
- 1. ❌ **sessionId 없이 멀티 상담 구현** → `reset()` 사용하세요
305
- 2. ❌ **saveStrategy: 'always' + 실시간 타이핑** → `'onEnd'` 사용 권장
306
- 3. ❌ **Firebase Timestamp 정규화 누락** → 어댑터 예제 코드 사용
307
- 4. ❌ **에러 핸들링 없음** → `fallbackToLocal: true` 설정 필수
308
-
309
- 📖 [전체 Best Practices 보기](./docs/best-practices.md)
310
-
311
- ---
312
-
313
- ## 🚀 실전 예제
314
-
315
- ### 고객 지원 챗봇
316
-
317
- ```typescript
318
- const SUPPORT_FLOW = {
319
- start: { /* ... */ },
320
- order_inquiry: { /* ... */ },
321
- delivery_status: { /* ... */ },
322
- refund: { /* ... */ }
323
- };
324
-
325
- function CustomerSupport() {
326
- const { node, submitAnswer, reset, sessionId } = useChat(
327
- SUPPORT_FLOW,
328
- customerId,
329
- 'start',
330
- firebaseAdapter,
331
- { sessionId: 'auto', saveStrategy: 'onEnd' }
332
- );
333
-
334
- return <ChatUI node={node} onAnswer={submitAnswer} onReset={reset} />;
335
- }
336
- ```
337
-
338
- 더 많은 예제: [Examples](./docs/examples.md)
339
-
340
- ---
341
-
342
- ## 🛠️ 타입 정의
343
-
344
- ```typescript
345
- // ChatNode
346
- interface ChatNode {
347
- id: string;
348
- question: string;
349
- type?: 'button' | 'input';
350
- options?: string[];
351
- next: string | ((answer: any) => string);
352
- isEnd?: boolean;
353
- }
354
-
355
- // ChatMessage
356
- interface ChatMessage {
357
- nodeId: string;
358
- question: string;
359
- answer: any;
360
- timestamp: number;
361
- }
362
-
363
- // ChatState
364
- interface ChatState {
365
- answers: Record<string, any>;
366
- currentStep: string;
367
- messages: ChatMessage[];
368
- flowHash: string;
369
- updatedAt: number;
370
- }
371
- ```
372
-
373
- ---
374
-
375
- ## 🤝 기여하기
376
-
377
- 이 라이브러리는 프리랜서 외주 작업을 하며 반복되는 챗봇 구현에 지쳐 만들어졌습니다.
378
- AI 기반 개발에 최적화된 문서를 목표로 하고 있습니다.
379
-
380
- - ⭐ **Star** 하나가 개발 동기부여가 됩니다!
381
- - 🐛 버그 제보: [Issues](https://github.com/Nago730/chatbot-library/issues)
382
- - 💡 기능 제안: [Issues](https://github.com/Nago730/chatbot-library/issues) (기능 제안도 환영합니다!)
383
-
384
- ---
385
-
386
- ## 📄 라이선스
387
-
388
- MIT License
389
-
390
- ---
391
-
392
- **Made with ❤️ for Vibe Coders** — AI 시대의 더 나은 개발 경험을 위해
1
+ # @nago730/chatbot-library
2
+
3
+ > **JSON 하나로 만드는 프로덕션 레디 챗봇 엔진** — React 환경에서 복잡한 대화형 인터페이스를 5분 안에 구축하세요.
4
+
5
+ <p align="left">
6
+ <img src="https://img.shields.io/npm/v/@nago730/chatbot-library" alt="npm version" />
7
+ <img src="https://img.shields.io/github/license/Nago730/chatbot-library" alt="license" />
8
+ <img src="https://img.shields.io/npm/dm/@nago730/chatbot-library" alt="downloads" />
9
+ </p>
10
+
11
+ ---
12
+
13
+ ## 🎯 핵심 기능 3가지
14
+
15
+ | 기능 | 설명 | 효과 |
16
+ |------|------|------|
17
+ | 🗂️ **JSON 기반 시나리오** | 코드 없이 대화 흐름 설계 | 개발 시간 **90% 단축** |
18
+ | 🔄 **멀티 세션 관리** | 한 사용자가 여러 상담 진행 | 사용자 경험 **향상** |
19
+ | 🔥 **프로덕션 레디** | Firebase 연동 + 비용 최적화 | 운영 비용 **98% 절감** |
20
+
21
+ ---
22
+
23
+ ## ⚡ 5분 빠른 시작
24
+
25
+ ### 1. 설치
26
+
27
+ ```bash
28
+ npm install @nago730/chatbot-library
29
+ ```
30
+
31
+ ### 2. Flow 정의 (JSON)
32
+
33
+ ```typescript
34
+ const SUPPORT_FLOW = {
35
+ start: {
36
+ id: 'start',
37
+ question: '무엇을 도와드릴까요?',
38
+ type: 'button',
39
+ options: ['주문 문의', '배송 조회', '취소/환불'],
40
+ next: (answer) => {
41
+ if (answer === '주문 문의') return 'order';
42
+ if (answer === '배송 조회') return 'delivery';
43
+ return 'refund';
44
+ }
45
+ },
46
+ order: {
47
+ id: 'order',
48
+ question: '주문번호를 입력해주세요',
49
+ type: 'input',
50
+ next: 'complete'
51
+ },
52
+ complete: {
53
+ id: 'complete',
54
+ question: '감사합니다. 곧 연락드리겠습니다.',
55
+ next: '',
56
+ isEnd: true
57
+ }
58
+ };
59
+ ```
60
+
61
+ ### 3. 컴포넌트에서 사용
62
+
63
+ ```tsx
64
+ import { useChat } from '@nago730/chatbot-library';
65
+
66
+ function ChatBot() {
67
+ const { node, submitAnswer, submitInput, messages, isEnd } = useChat(
68
+ SUPPORT_FLOW,
69
+ 'user_123'
70
+ );
71
+
72
+ if (isEnd) {
73
+ return <div>✅ {node.question}</div>;
74
+ }
75
+
76
+ return (
77
+ <div>
78
+ {/* 대화 히스토리 */}
79
+ {messages.map((msg, i) => (
80
+ <div key={i}>
81
+ <p>🤖 {msg.question}</p>
82
+ <p>👤 {msg.answer}</p>
83
+ </div>
84
+ ))}
85
+
86
+ {/* 현재 질문 */}
87
+ <p>{node.question}</p>
88
+
89
+ {/* 버튼형 */}
90
+ {node.type === 'button' && node.options?.map(opt => (
91
+ <button key={opt} onClick={() => submitAnswer(opt)}>
92
+ {opt}
93
+ </button>
94
+ ))}
95
+
96
+ {/* 입력형 */}
97
+ {node.type === 'input' && (
98
+ <input onKeyDown={(e) => {
99
+ if (e.key === 'Enter') submitInput(e.currentTarget.value);
100
+ }} />
101
+ )}
102
+ </div>
103
+ );
104
+ }
105
+ ```
106
+
107
+ **🎉 완료!** 이제 작동하는 챗봇이 생겼습니다.
108
+
109
+ ---
110
+
111
+ ## 📚 핵심 개념
112
+
113
+ ### Flow 구조
114
+
115
+ Flow는 **노드(Node)의 집합**입니다. 각 노드는 질문과 다음 단계를 정의합니다.
116
+
117
+ ```typescript
118
+ interface ChatNode {
119
+ id: string; // 고유 ID
120
+ question: string; // 사용자에게 보여줄 질문
121
+ type?: 'button' | 'input'; // 답변 받는 방식 (기본: button)
122
+ options?: string[]; // 선택지 (type='button'일 때)
123
+ next: string | ((answer) => string); // 다음 노드 ID (동적 가능)
124
+ isEnd?: boolean; // 대화 종료 표시
125
+ }
126
+ ```
127
+
128
+ ### 세션 관리
129
+
130
+ 한 사용자가 **여러 번 상담**을 시작할 수 있습니다.
131
+
132
+ ```typescript
133
+ const { sessionId, reset } = useChat(FLOW, userId, 'start', adapter, {
134
+ sessionId: 'auto' // 'auto' | 'new' | 'specific_id'
135
+ });
136
+
137
+ // 새 상담 시작
138
+ <button onClick={() => reset()}>새 상담</button>
139
+ ```
140
+
141
+ ### 저장 전략
142
+
143
+ ```typescript
144
+ const chat = useChat(FLOW, userId, 'start', adapter, {
145
+ saveStrategy: 'onEnd' // 'always' | 'onEnd'
146
+ });
147
+ ```
148
+
149
+ | 전략 | 저장 시점 | 추천 대상 |
150
+ |------|-----------|-----------|
151
+ | `'always'` | 매 답변마다 | 데이터 무결성이 중요한 경우 |
152
+ | `'onEnd'` | 대화 종료 시 | **비용 절감** (권장) |
153
+
154
+ ---
155
+
156
+ ## 🔥 Firebase 연동 (프로덕션)
157
+
158
+ ### Quick Start
159
+
160
+ ```typescript
161
+ import { createHybridFirebaseAdapter } from '@nago730/chatbot-library/examples';
162
+ import { getFirestore } from 'firebase/firestore';
163
+
164
+ const db = getFirestore(app);
165
+ const adapter = createHybridFirebaseAdapter(db, {
166
+ timeout: 5000,
167
+ fallbackToLocal: true,
168
+ debug: false
169
+ });
170
+
171
+ const chat = useChat(FLOW, userId, 'start', adapter, {
172
+ saveStrategy: 'onEnd' // 비용 98% 절감!
173
+ });
174
+ ```
175
+
176
+ ### 비용 최적화
177
+
178
+ **10만 사용자, 일 10회 대화 기준 (Firestore)**
179
+
180
+ | 구성 | 월 비용 | 절감율 |
181
+ |------|---------|--------|
182
+ | 기본 설정 (always + 전체 데이터) | $2,700 | - |
183
+ | **하이브리드 + onEnd** ⭐ | **$5.4** | **99.8%** |
184
+
185
+ ### 핵심 개선사항
186
+
187
+ - ✅ **기기 전환 복구**: PC → 모바일 대화 이어가기 100%
188
+ - ✅ **네트워크 안정성**: 타임아웃 + 자동 폴백
189
+ - ✅ **타입 안전**: Firebase Timestamp 자동 정규화
190
+ - ✅ **비용 최적화**: 스마트 저장 전략
191
+
192
+ 📖 [Firebase 상세 가이드](./docs/firebase-adapter-guide.md)
193
+
194
+ ---
195
+
196
+ ## 🔄 멀티 세션
197
+
198
+ 한 사용자가 **여러 상담을 진행**하고 **이전 대화를 불러올** 수 있습니다.
199
+
200
+ ```typescript
201
+ const { sessionId, reset, isEnd } = useChat(FLOW, userId, 'start', adapter, {
202
+ sessionId: 'auto'
203
+ });
204
+
205
+ // UI 예제
206
+ <div>
207
+ <p>현재 세션: {sessionId}</p>
208
+
209
+ {isEnd && (
210
+ <button onClick={() => reset()}>
211
+ 새 상담 시작
212
+ </button>
213
+ )}
214
+
215
+ <button onClick={() => reset('session_1706000000_abc')}>
216
+ 이전 상담 보기
217
+ </button>
218
+ </div>
219
+ ```
220
+
221
+ 📖 [멀티 세션 완벽 가이드](./docs/multi-session-guide.md)
222
+
223
+ ---
224
+
225
+ ## 📖 API Reference
226
+
227
+ ### useChat
228
+
229
+ ```typescript
230
+ useChat(
231
+ flow: Record<string, ChatNode>,
232
+ userId: string,
233
+ initialNodeId?: string,
234
+ adapter?: StorageAdapter,
235
+ options?: ChatOptions
236
+ )
237
+ ```
238
+
239
+ #### Parameters
240
+
241
+ | 파라미터 | 타입 | 설명 |
242
+ |----------|------|------|
243
+ | `flow` | `Record<string, ChatNode>` | 시나리오 Flow 객체 |
244
+ | `userId` | `string` | 사용자 ID (세션 키로 사용) |
245
+ | `initialNodeId` | `string` | 시작 노드 ID (기본: `'start'`) |
246
+ | `adapter` | `StorageAdapter` | 저장소 어댑터 (선택) |
247
+ | `options` | `ChatOptions` | 추가 옵션 (선택) |
248
+
249
+ #### ChatOptions
250
+
251
+ ```typescript
252
+ interface ChatOptions {
253
+ saveStrategy?: 'always' | 'onEnd'; // 저장 시점
254
+ scenarioId?: string; // 시나리오 ID
255
+ sessionId?: 'auto' | 'new' | string; // 세션 전략
256
+ }
257
+ ```
258
+
259
+ #### Return Values
260
+
261
+ ```typescript
262
+ {
263
+ node: ChatNode; // 현재 노드
264
+ submitAnswer: (value: any) => Promise<void>; // 버튼 답변 제출
265
+ submitInput: (value: string) => Promise<void>; // 텍스트 답변 제출
266
+ answers: Record<string, any>; // 수집된 답변
267
+ messages: ChatMessage[]; // 대화 히스토리
268
+ isEnd: boolean; // 종료 여부
269
+ sessionId: string; // 현재 세션 ID
270
+ reset: (sessionId?: string) => void; // 세션 리셋
271
+ }
272
+ ```
273
+
274
+ ### StorageAdapter
275
+
276
+ ```typescript
277
+ interface StorageAdapter {
278
+ saveState: (userId: string, state: ChatState) => Promise<void>;
279
+ loadState: (userId: string) => Promise<ChatState | null>;
280
+ }
281
+ ```
282
+
283
+ ---
284
+
285
+ ## 📚 전체 문서
286
+
287
+ ### 가이드
288
+ - 📘 [**Complete Guide**](./docs/complete-guide.md) - 모든 기능 + 실전 패턴
289
+ - 🔥 [Firebase Adapter Guide](./docs/firebase-adapter-guide.md)
290
+ - 🔄 [Multi-Session Guide](./docs/multi-session-guide.md)
291
+ - ⚡ [Quick Reference](./docs/firebase-quick-reference.md)
292
+
293
+ ### 학습 자료
294
+ - ✅ [Best Practices](./docs/best-practices.md) - DO's & DON'Ts
295
+ - 💡 [Examples](./docs/examples.md) - 실전 코드 모음
296
+ - 🔧 [예제 코드](./src/examples/)
297
+
298
+ ---
299
+
300
+ ## ⚠️ Common Pitfalls
301
+
302
+ 개발 시 자주 발생하는 실수들:
303
+
304
+ 1. ❌ **sessionId 없이 멀티 상담 구현** → `reset()` 사용하세요
305
+ 2. ❌ **saveStrategy: 'always' + 실시간 타이핑** → `'onEnd'` 사용 권장
306
+ 3. ❌ **Firebase Timestamp 정규화 누락** → 어댑터 예제 코드 사용
307
+ 4. ❌ **에러 핸들링 없음** → `fallbackToLocal: true` 설정 필수
308
+
309
+ 📖 [전체 Best Practices 보기](./docs/best-practices.md)
310
+
311
+ ---
312
+
313
+ ## 🚀 실전 예제
314
+
315
+ ### 고객 지원 챗봇
316
+
317
+ ```typescript
318
+ const SUPPORT_FLOW = {
319
+ start: { /* ... */ },
320
+ order_inquiry: { /* ... */ },
321
+ delivery_status: { /* ... */ },
322
+ refund: { /* ... */ }
323
+ };
324
+
325
+ function CustomerSupport() {
326
+ const { node, submitAnswer, reset, sessionId } = useChat(
327
+ SUPPORT_FLOW,
328
+ customerId,
329
+ 'start',
330
+ firebaseAdapter,
331
+ { sessionId: 'auto', saveStrategy: 'onEnd' }
332
+ );
333
+
334
+ return <ChatUI node={node} onAnswer={submitAnswer} onReset={reset} />;
335
+ }
336
+ ```
337
+
338
+ 더 많은 예제: [Examples](./docs/examples.md)
339
+
340
+ ---
341
+
342
+ ## 🛠️ 타입 정의
343
+
344
+ ```typescript
345
+ // ChatNode
346
+ interface ChatNode {
347
+ id: string;
348
+ question: string;
349
+ type?: 'button' | 'input';
350
+ options?: string[];
351
+ next: string | ((answer: any) => string);
352
+ isEnd?: boolean;
353
+ }
354
+
355
+ // ChatMessage
356
+ interface ChatMessage {
357
+ nodeId: string;
358
+ question: string;
359
+ answer: any;
360
+ timestamp: number;
361
+ }
362
+
363
+ // ChatState
364
+ interface ChatState {
365
+ answers: Record<string, any>;
366
+ currentStep: string;
367
+ messages: ChatMessage[];
368
+ flowHash: string;
369
+ updatedAt: number;
370
+ }
371
+ ```
372
+
373
+ ---
374
+
375
+ ## 🤝 기여하기
376
+
377
+ 이 라이브러리는 프리랜서 외주 작업을 하며 반복되는 챗봇 구현에 지쳐 만들어졌습니다.
378
+ AI 기반 개발에 최적화된 문서를 목표로 하고 있습니다.
379
+
380
+ - ⭐ **Star** 하나가 개발 동기부여가 됩니다!
381
+ - 🐛 버그 제보: [Issues](https://github.com/Nago730/chatbot-library/issues)
382
+ - 💡 기능 제안: [Issues](https://github.com/Nago730/chatbot-library/issues) (기능 제안도 환영합니다!)
383
+
384
+ ---
385
+
386
+ ## 📄 라이선스
387
+
388
+ MIT License
389
+
390
+ ---
391
+
392
+ **Made with ❤️ for Vibe Coders** — AI 시대의 더 나은 개발 경험을 위해