@peopl-health/nexus 1.2.0 → 1.3.1

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.
@@ -1,388 +1,80 @@
1
- # Migration Guide: From Original Codebase to @peopl/nexus
2
-
3
- This guide helps you migrate from the original WhatsApp messaging platform to the new `@peopl/nexus` library.
4
-
5
- ## Overview
6
-
7
- The original codebase has been transformed into a reusable library that provides:
8
- - **Provider abstraction** (Twilio/Baileys)
9
- - **Configurable message handling**
10
- - **MongoDB storage interface**
11
- - **AI assistant integration**
12
- - **Event-driven architecture**
13
-
14
- ## Migration Steps
15
-
16
- ### 1. Install the Library
17
-
18
- ```bash
19
- npm install @peopl/nexus
20
- ```
21
-
22
- Install peer dependencies based on your needs:
23
- ```bash
24
- # For Twilio
25
- npm install twilio
26
-
27
- # For Baileys
28
- npm install baileys
29
-
30
- # For AI assistants
31
- npm install openai
32
- ```
33
-
34
- ### 2. Replace Original Server Code
35
-
36
- **Before (Original):**
37
- ```javascript
38
- // src/index.js
39
- const express = require('express');
40
- const { initWhatsApp } = require('./adapters/baileys');
41
- const { initTwilio } = require('./adapters/twilio');
42
- // ... lots of setup code
43
- ```
44
-
45
- **After (With @peopl/nexus):**
46
- ```javascript
47
- const express = require('express');
48
- const { Nexus } = require('@peopl/nexus');
49
-
50
- const nexus = new Nexus();
51
- await nexus.initialize({
52
- provider: 'twilio', // or 'baileys'
53
- providerConfig: { /* your config */ }
54
- });
55
- ```
56
-
57
- ### 3. Migrate Message Handlers
58
-
59
- **Before:**
60
- ```javascript
61
- // Scattered across multiple files
62
- async function processIncomingMessage(twilioClient, message) {
63
- // Complex processing logic
64
- }
65
- ```
66
-
67
- **After:**
68
- ```javascript
69
- nexus.setHandlers({
70
- onMessage: async (messageData, nexus) => {
71
- // Your message logic here
72
- },
73
- onCommand: async (messageData, nexus) => {
74
- // Your command logic here
75
- }
76
- });
77
- ```
78
-
79
- ### 4. Migrate Assistant Integration
80
-
81
- **Before:**
82
- ```javascript
83
- // src/services/assistantService.js
84
- const { replyAssistant } = require('./assistantService');
85
- // Complex assistant management
86
- ```
87
-
88
- **After:**
89
- ```javascript
90
- await nexus.initialize({
91
- assistant: {
92
- llmClient: openai,
93
- assistants: {
94
- 'SUPPORT_ASST': 'asst_abc123'
95
- }
96
- }
97
- });
98
-
99
- // Use assistants
100
- const response = await nexus.sendToAssistant(userId, message);
101
- ```
102
-
103
- ### 5. Migrate Database Models
104
-
105
- **Before:**
106
- ```javascript
107
- // src/models/messageModel.js
108
- const Message = mongoose.model('Message', messageSchema);
109
- ```
110
-
111
- **After:**
112
- ```javascript
113
- // Models are handled automatically by the library
114
- // Access via nexus.getStorage() if needed
115
- const storage = nexus.getStorage();
116
- const messages = await storage.getMessages(userId);
117
- ```
118
-
119
- ## Configuration Mapping
120
-
121
- ### Environment Variables
122
-
123
- **Before:**
124
- ```env
125
- TWILIO_ACCOUNT_SID=your_sid
126
- TWILIO_AUTH_TOKEN=your_token
127
- MONGO_URI=mongodb://localhost:27017/db
128
- ```
129
-
130
- **After:**
131
- ```javascript
1
+ # Migration Guide
2
+
3
+ This guide summarizes changes introduced in the current Nexus library refresh to help you migrate quickly with minimal breakage.
4
+
5
+ ## TL;DR
6
+ - Twilio remains first‑class; Baileys is supported for messaging but not for templates/flows (returns clear errors).
7
+ - Message sends accept both `to` (preferred) and legacy `code` (normalized internally).
8
+ - Templates and flows are supported through Twilio Content API; provider is auto‑injected into template controllers on `Nexus.initialize()` when Twilio is active.
9
+ - New event bus + middleware model; existing handlers continue to work.
10
+ - Storage adapter registry; use built‑in `mongo`/`noop` or plug your own adapter or instance.
11
+ - Interactive/flows now have a provider‑agnostic API with Twilio mapping and event‑driven routing.
12
+ - Assistant registry with optional override for `getAssistantById`.
13
+
14
+ ## Messaging API
15
+ - BREAKING (soft): Prefer `to` over `code` in `sendMessage`. Legacy `code` is still accepted and normalized internally.
16
+
17
+ Before:
18
+ ```js
19
+ await nexus.sendMessage({ code: 'whatsapp:+521555...', message: 'Hi' });
20
+ ```
21
+ After (preferred):
22
+ ```js
23
+ await nexus.sendMessage({ to: '+521555...', message: 'Hi' });
24
+ ```
25
+
26
+ ## Templates & Flows (Twilio)
27
+ - Twilio provider now implements content operations: `listTemplates`, `getTemplate`, `createTemplate`, `deleteTemplate`, `submitForApproval`, `checkApprovalStatus`.
28
+ - On `Nexus.initialize()` with Twilio, the provider is auto‑injected into template controllers — default routes under `/api/template` work immediately.
29
+ - Baileys: content/template operations are not supported; a clear error is thrown if called.
30
+
31
+ ## Interactive & Flows (Provider‑agnostic)
32
+ - New helper APIs:
33
+ - `registerFlow(id, spec)`, `sendInteractive(nexus, { to, id | spec, variables })`.
34
+ - Twilio: spec is converted to Content API payload and sent; if `spec.contentSid` is provided, it is used directly.
35
+ - Baileys: currently unsupported.
36
+ - Event‑driven routing:
37
+ - `registerInteractiveHandler(match, handler)` and `attachInteractiveRouter(nexus)`; handlers are called when interactive messages are received.
38
+
39
+ ## Middleware & Events
40
+ - New event bus on `NexusMessaging`: subscribe to `*:received` and `*:handled` (message, media, interactive, command, keyword, flow).
41
+ - New middleware: `nexus.getMessaging().use(type?, async (msg, nexus, next) => { ... })`.
42
+ - Existing `setHandlers` and `onMessage`/`onInteractive`/etc. continue to work.
43
+
44
+ ## Storage
45
+ - Storage is now pluggable via a registry:
46
+ - Built‑ins: `mongo` (default), `noop`.
47
+ - Register your adapter: `registerStorage('src', MyStorageClass)` then `storage: 'src'`.
48
+ - Or pass an instance: `storage: new MyStorageClass()`.
49
+ - If the adapter has `connect()`, Nexus calls it automatically.
50
+ - Controllers that rely on your Mongo models can continue to do so — no change required.
51
+
52
+ ## Assistants
53
+ - Register assistant classes at init:
54
+ ```js
132
55
  await nexus.initialize({
133
56
  provider: 'twilio',
134
- providerConfig: {
135
- accountSid: process.env.TWILIO_ACCOUNT_SID,
136
- authToken: process.env.TWILIO_AUTH_TOKEN,
137
- whatsappNumber: process.env.TWILIO_WHATSAPP_NUMBER
138
- },
139
- storage: 'mongo',
140
- storageConfig: {
141
- mongoUri: process.env.MONGO_URI,
142
- dbName: 'your_db_name'
143
- }
144
- });
145
- ```
146
-
147
- ### Assistant Configuration
148
-
149
- **Before:**
150
- ```javascript
151
- // src/config/assistantConfig.js
152
- module.exports = {
153
- SALES_ASST: "asst_HjYiVBQ8ye1yl1Iu9mcqF83b",
154
- DOCTOR_SCHEDULE_ASST: "asst_5cw2tRHI7ze6FHgtlId6ideH"
155
- };
156
- ```
157
-
158
- **After:**
159
- ```javascript
160
- await nexus.initialize({
161
- assistant: {
162
- llmClient: openai,
163
- assistants: {
164
- 'SALES_ASST': process.env.SALES_ASSISTANT_ID,
165
- 'DOCTOR_SCHEDULE_ASST': process.env.DOCTOR_SCHEDULE_ASSISTANT_ID
166
- }
57
+ llm: 'openai', llmConfig: { apiKey: process.env.OPENAI_API_KEY },
58
+ assistants: {
59
+ registry: { SUPPORT: SupportAssistantClass, SALES: SalesAssistantClass },
60
+ getAssistantById: (id, thread) => null // optional override
167
61
  }
168
62
  });
169
63
  ```
64
+ - An internal override for `getAssistantById` is supported; if provided, it is tried first, then fallback to registry.
170
65
 
171
- ## Feature Migration
172
-
173
- ### 1. Message Sending
174
-
175
- **Before:**
176
- ```javascript
177
- const { sendMessage } = require('./messaging/messageService');
178
- await sendMessage(twilioClient, messageData);
179
- ```
180
-
181
- **After:**
182
- ```javascript
183
- await nexus.sendMessage({
184
- to: '+1234567890',
185
- message: 'Hello World!',
186
- fileUrl: 'https://example.com/file.pdf',
187
- fileType: 'document'
188
- });
189
- ```
190
-
191
- ### 2. Template Messages
192
-
193
- **Before:**
194
- ```javascript
195
- await sendMessage(twilioClient, {
196
- code: phoneNumber,
197
- contentSid: templateId,
198
- variables: { '1': 'John', '2': 'Doe' }
199
- });
200
- ```
201
-
202
- **After:**
203
- ```javascript
204
- await nexus.sendMessage({
205
- to: phoneNumber,
206
- contentSid: templateId,
207
- variables: { '1': 'John', '2': 'Doe' }
208
- });
209
- ```
210
-
211
- ### 3. Interactive Messages
212
-
213
- **Before:**
214
- ```javascript
215
- // src/adapters/interactive/processButton.js
216
- async function processButtonPayload(twilioClient, message) {
217
- // Complex button handling
218
- }
219
- ```
220
-
221
- **After:**
222
- ```javascript
223
- nexus.setHandlers({
224
- onInteractive: async (messageData, nexus) => {
225
- const { type, payload } = messageData.interactive;
226
-
227
- if (type === 'button') {
228
- // Handle button click
229
- await nexus.sendMessage({
230
- to: messageData.from,
231
- message: `You clicked: ${payload}`
232
- });
233
- }
234
- }
235
- });
236
- ```
237
-
238
- ### 4. Command Processing
239
-
240
- **Before:**
241
- ```javascript
242
- // Hardcoded command processing in multiple files
243
- if (message.Body.startsWith('/help')) {
244
- // Handle help command
245
- }
246
- ```
247
-
248
- **After:**
249
- ```javascript
250
- nexus.setHandlers({
251
- onCommand: async (messageData, nexus) => {
252
- const { command, args } = messageData.command;
253
-
254
- switch (command) {
255
- case 'help':
256
- await nexus.sendMessage({
257
- to: messageData.from,
258
- message: 'Available commands: /help, /status'
259
- });
260
- break;
261
- }
262
- }
263
- });
264
- ```
265
-
266
- ### 5. Keyword Detection
267
-
268
- **Before:**
269
- ```javascript
270
- // Hardcoded keyword detection
271
- const keywords = ['hola', 'dr.', 'bienvenida'];
272
- if (keywords.some(k => message.Body.includes(k))) {
273
- // Handle keywords
274
- }
275
- ```
276
-
277
- **After:**
278
- ```javascript
279
- await nexus.initialize({
280
- parserConfig: {
281
- keywords: ['hola', 'dr.', 'bienvenida', 'help', 'support']
282
- }
283
- });
284
-
285
- nexus.setHandlers({
286
- onKeyword: async (messageData, nexus) => {
287
- const keyword = messageData.keyword;
288
- // Handle keyword detection
289
- }
290
- });
291
- ```
292
-
293
- ## Webhook Migration
294
-
295
- ### Before (Express Routes)
296
- ```javascript
297
- // src/routes/index.js
298
- app.post('/twilio/webhook', async (req, res) => {
299
- await processIncomingMessage(twilioClient, req.body);
300
- res.sendStatus(200);
301
- });
302
- ```
303
-
304
- ### After (Simplified)
305
- ```javascript
306
- app.post('/webhook/twilio', async (req, res) => {
307
- await nexus.processMessage(req.body);
308
- res.sendStatus(200);
309
- });
310
- ```
311
-
312
- ## Benefits After Migration
313
-
314
- ### ✅ Reduced Code Complexity
315
- - **Before**: ~2000+ lines across multiple files
316
- - **After**: ~200 lines for equivalent functionality
317
-
318
- ### ✅ Better Maintainability
319
- - Centralized configuration
320
- - Clear separation of concerns
321
- - Standardized error handling
322
-
323
- ### ✅ Enhanced Flexibility
324
- - Easy provider switching (Twilio ↔ Baileys)
325
- - Configurable message parsing
326
- - Pluggable storage backends
327
-
328
- ### ✅ Improved Testing
329
- - Mockable components
330
- - Isolated business logic
331
- - Clear interfaces
332
-
333
- ## Common Migration Issues
334
-
335
- ### 1. **Missing Dependencies**
336
- ```bash
337
- # Install missing peer dependencies
338
- npm install twilio baileys openai
339
- ```
340
-
341
- ### 2. **Configuration Errors**
342
- ```javascript
343
- // Ensure all required config is provided
344
- await nexus.initialize({
345
- provider: 'twilio',
346
- providerConfig: {
347
- accountSid: 'required',
348
- authToken: 'required',
349
- whatsappNumber: 'required'
350
- }
351
- });
352
- ```
353
-
354
- ### 3. **Handler Registration**
355
- ```javascript
356
- // Set handlers AFTER initialization
357
- await nexus.initialize(config);
358
- nexus.setHandlers(handlers); // ✅ Correct order
359
- ```
360
-
361
- ### 4. **Database Connection**
362
- ```javascript
363
- // Storage is handled automatically
364
- await nexus.initialize({
365
- storage: 'mongo',
366
- storageConfig: {
367
- mongoUri: 'mongodb://localhost:27017/db',
368
- dbName: 'your_db'
369
- }
370
- });
371
- // No need to call connectMongoose() manually
372
- ```
373
-
374
- ## Next Steps
375
-
376
- 1. **Start Small**: Migrate one feature at a time
377
- 2. **Test Thoroughly**: Verify each migrated component works
378
- 3. **Remove Old Code**: Clean up original files after successful migration
379
- 4. **Optimize**: Use library features to simplify your code further
66
+ ## Utilities & Fixes
67
+ - Utils index corrected to export existing files: `{ DefaultLLMProvider, MessageParser, logger }`.
68
+ - Default OpenAI import fixed for CommonJS: `const OpenAI = require('openai');`.
69
+ - Message model helpers unified; `LegacyMessage` references replaced with `Message` and a new exported `insertMessage`.
70
+ - Types `declare module` now matches package name: `@peopl-health/nexus`.
380
71
 
381
- ## Support
72
+ ## Routes
73
+ - Built‑in route bundles remain available and importable via `setupDefaultRoutes(app)` or per‑group via `routes` + `createRouter()`.
382
74
 
383
- For migration assistance:
384
- - Check the [README.md](./README.md) for detailed API documentation
385
- - Review [examples/](./examples/) for complete implementations
386
- - Refer to the original codebase for complex business logic patterns
75
+ ## Testing
76
+ - If your environment restricts forking, run Jest in‑band: `jest --runInBand`.
387
77
 
388
- The migration should significantly reduce your codebase size while maintaining all functionality and adding new capabilities for future development.
78
+ ## Notes
79
+ - Twilio approvals data shape varies by account/region. The provider looks up `content.links` and falls back to the documented REST path; data is normalized where possible.
80
+ - Baileys: templates/flows remain unsupported; messaging and media send/receive are supported.