@supsis/supsis-js 1.0.0

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.
@@ -0,0 +1,4045 @@
1
+ /**
2
+ * Supsis JS SDK v1.0.0
3
+ * Supsis API SDK - Browser ve Node.js için omnichannel messaging, chatbot, automation, task, ticket ve voice agent entegrasyonu
4
+ *
5
+ * @license MIT
6
+ * @author Supsis <info@supsis.com>
7
+ * @see https://supsis.com
8
+ */
9
+ /**
10
+ * Supsis API ortam URL'leri
11
+ * @readonly
12
+ * @enum {string}
13
+ */
14
+ const ENVIRONMENTS = {
15
+ /** Production API - api.supsis.live */
16
+ production: 'https://api.supsis.live',
17
+ /** Stage/Beta API - beta-api.supsis.live */
18
+ stage: 'https://beta-api.supsis.live',
19
+ /** Local development API */
20
+ local: 'https://tablet-api-local.supsis.live'
21
+ };
22
+
23
+ /**
24
+ * Varsayılan SDK konfigürasyonu
25
+ * @type {SupsisConfig}
26
+ */
27
+ const DEFAULT_CONFIG = {
28
+ /** Varsayılan ortam (production) */
29
+ env: 'production',
30
+ /** Custom API adresi (null ise env'den alınır) - OnPrem kurulumları için */
31
+ baseApiAddress: null,
32
+ /** HTTP istek timeout süresi (ms) */
33
+ timeout: 30000,
34
+ /** Başarısız isteklerde retry sayısı */
35
+ retryCount: 3,
36
+ /** Retry'lar arası bekleme süresi (ms) */
37
+ retryDelay: 1000
38
+ };
39
+
40
+ /**
41
+ * HTTP Status kodları
42
+ * @readonly
43
+ * @enum {number}
44
+ */
45
+ const HTTP_STATUS = {
46
+ UNAUTHORIZED: 401,
47
+ FORBIDDEN: 403};
48
+
49
+ /**
50
+ * SDK Versiyon bilgisi
51
+ */
52
+ const SDK_VERSION = '1.0.0';
53
+
54
+ /**
55
+ * Supsis API hatası
56
+ * @class SupsisAPIError
57
+ * @extends Error
58
+ */
59
+ class SupsisAPIError extends Error {
60
+ /**
61
+ * @param {string} message - Hata mesajı
62
+ * @param {number} statusCode - HTTP status kodu
63
+ * @param {Object} [response] - API yanıtı
64
+ */
65
+ constructor(message, statusCode, response) {
66
+ super(message);
67
+ this.name = 'SupsisAPIError';
68
+ this.statusCode = statusCode;
69
+ this.response = response;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * HTTP isteklerini yöneten client sınıfı
75
+ * Browser ve Node.js ortamlarında çalışır
76
+ * @class HttpClient
77
+ */
78
+ class HttpClient {
79
+ /**
80
+ * HttpClient oluşturur
81
+ * @param {Object} config - Konfigürasyon
82
+ * @param {string} [config.env='production'] - Ortam (production, stage, local)
83
+ * @param {string} [config.baseApiAddress] - Custom API adresi (OnPrem için)
84
+ * @param {string} [config.siteId] - Site ID (multi-tenant)
85
+ * @param {number} [config.timeout=30000] - İstek timeout süresi (ms)
86
+ * @param {number} [config.retryCount=3] - Retry sayısı
87
+ * @param {number} [config.retryDelay=1000] - Retry arası bekleme (ms)
88
+ */
89
+ constructor(config) {
90
+ this.config = Object.assign({}, DEFAULT_CONFIG, config);
91
+ this.baseUrl = this._resolveBaseUrl();
92
+ this.token = null;
93
+ this.siteId = config.siteId || null;
94
+ }
95
+
96
+ /**
97
+ * API base URL'sini çözümler
98
+ * @private
99
+ * @returns {string} Base URL
100
+ */
101
+ _resolveBaseUrl() {
102
+ // Custom baseApiAddress varsa onu kullan (OnPrem)
103
+ if (this.config.baseApiAddress) {
104
+ return this.config.baseApiAddress.replace(/\/$/, ''); // Trailing slash temizle
105
+ }
106
+ // Yoksa env'e göre belirle
107
+ return ENVIRONMENTS[this.config.env] || ENVIRONMENTS.production;
108
+ }
109
+
110
+ /**
111
+ * Authorization token'ı ayarlar
112
+ * @param {string} token - JWT token
113
+ */
114
+ setToken(token) {
115
+ this.token = token;
116
+ }
117
+
118
+ /**
119
+ * Site ID'yi ayarlar
120
+ * @param {string} siteId - Site ID
121
+ */
122
+ setSiteId(siteId) {
123
+ this.siteId = siteId;
124
+ }
125
+
126
+ /**
127
+ * HTTP isteği yapar
128
+ * @param {string} method - HTTP metodu (GET, POST, PUT, DELETE, PATCH)
129
+ * @param {string} endpoint - API endpoint'i
130
+ * @param {Object} [options] - İstek seçenekleri
131
+ * @param {Object} [options.body] - İstek body'si
132
+ * @param {Object} [options.query] - Query parametreleri
133
+ * @param {Object} [options.headers] - Ek header'lar
134
+ * @param {boolean} [options.skipAuth=false] - Auth header'ı atla
135
+ * @returns {Promise<Object>} API yanıtı
136
+ * @throws {SupsisAPIError} API hatası
137
+ */
138
+ async request(method, endpoint, options) {
139
+ options = options || {};
140
+ const url = this._buildUrl(endpoint, options.query);
141
+ const headers = this._buildHeaders(options.headers, options.skipAuth);
142
+
143
+ const fetchOptions = {
144
+ method: method.toUpperCase(),
145
+ headers: headers
146
+ };
147
+
148
+ if (options.body && method.toUpperCase() !== 'GET') {
149
+ fetchOptions.body = JSON.stringify(options.body);
150
+ }
151
+
152
+ let lastError;
153
+ const retryCount = options.retryCount !== undefined ? options.retryCount : this.config.retryCount;
154
+
155
+ for (let attempt = 0; attempt <= retryCount; attempt++) {
156
+ try {
157
+ const response = await this._fetchWithTimeout(url, fetchOptions);
158
+ return await this._handleResponse(response);
159
+ } catch (error) {
160
+ lastError = error;
161
+
162
+ // Auth hatalarında retry yapma
163
+ if (error.statusCode === HTTP_STATUS.UNAUTHORIZED ||
164
+ error.statusCode === HTTP_STATUS.FORBIDDEN) {
165
+ throw error;
166
+ }
167
+
168
+ // Son deneme değilse bekle ve tekrar dene
169
+ if (attempt < retryCount) {
170
+ await this._sleep(this.config.retryDelay * (attempt + 1));
171
+ }
172
+ }
173
+ }
174
+
175
+ throw lastError;
176
+ }
177
+
178
+ /**
179
+ * Timeout'lu fetch işlemi
180
+ * @private
181
+ */
182
+ async _fetchWithTimeout(url, options) {
183
+ const controller = new AbortController();
184
+ const timeoutId = setTimeout(function() {
185
+ controller.abort();
186
+ }, this.config.timeout);
187
+
188
+ try {
189
+ const response = await fetch(url, Object.assign({}, options, {
190
+ signal: controller.signal
191
+ }));
192
+ clearTimeout(timeoutId);
193
+ return response;
194
+ } catch (error) {
195
+ clearTimeout(timeoutId);
196
+ if (error.name === 'AbortError') {
197
+ throw new SupsisAPIError('Request timeout', 408);
198
+ }
199
+ throw error;
200
+ }
201
+ }
202
+
203
+ /**
204
+ * URL oluşturur
205
+ * @private
206
+ */
207
+ _buildUrl(endpoint, query) {
208
+ let url = this.baseUrl + endpoint;
209
+
210
+ if (query && Object.keys(query).length > 0) {
211
+ const params = new URLSearchParams();
212
+ Object.keys(query).forEach(function(key) {
213
+ if (query[key] !== undefined && query[key] !== null) {
214
+ params.append(key, query[key]);
215
+ }
216
+ });
217
+ url = url + '?' + params.toString();
218
+ }
219
+
220
+ return url;
221
+ }
222
+
223
+ /**
224
+ * Header'ları oluşturur
225
+ * @private
226
+ */
227
+ _buildHeaders(customHeaders, skipAuth) {
228
+ const headers = {
229
+ 'Content-Type': 'application/json',
230
+ 'Accept': 'application/json'
231
+ };
232
+
233
+ // Site ID header'ı
234
+ if (this.siteId) {
235
+ headers['site-id'] = this.siteId;
236
+ }
237
+
238
+ // Authorization header
239
+ if (!skipAuth && this.token) {
240
+ headers['Authorization'] = 'Bearer ' + this.token;
241
+ }
242
+
243
+ // Custom header'ları merge et
244
+ if (customHeaders) {
245
+ Object.assign(headers, customHeaders);
246
+ }
247
+
248
+ return headers;
249
+ }
250
+
251
+ /**
252
+ * API yanıtını işler
253
+ * @private
254
+ */
255
+ async _handleResponse(response) {
256
+ let data;
257
+
258
+ try {
259
+ const contentType = response.headers.get('content-type');
260
+ if (contentType && contentType.indexOf('application/json') !== -1) {
261
+ data = await response.json();
262
+ } else {
263
+ data = await response.text();
264
+ }
265
+ } catch (e) {
266
+ data = null;
267
+ }
268
+
269
+ if (!response.ok) {
270
+ const message = (data && data.message) || (data && data.error) || response.statusText || 'API Error';
271
+ throw new SupsisAPIError(message, response.status, data);
272
+ }
273
+
274
+ return data;
275
+ }
276
+
277
+ /**
278
+ * Promise tabanlı sleep
279
+ * @private
280
+ */
281
+ _sleep(ms) {
282
+ return new Promise(function(resolve) {
283
+ setTimeout(resolve, ms);
284
+ });
285
+ }
286
+
287
+ // Convenience methods
288
+
289
+ /**
290
+ * GET isteği yapar
291
+ * @param {string} endpoint - API endpoint'i
292
+ * @param {Object} [options] - İstek seçenekleri
293
+ * @returns {Promise<Object>} API yanıtı
294
+ */
295
+ get(endpoint, options) {
296
+ return this.request('GET', endpoint, options);
297
+ }
298
+
299
+ /**
300
+ * POST isteği yapar
301
+ * @param {string} endpoint - API endpoint'i
302
+ * @param {Object} [body] - İstek body'si
303
+ * @param {Object} [options] - İstek seçenekleri
304
+ * @returns {Promise<Object>} API yanıtı
305
+ */
306
+ post(endpoint, body, options) {
307
+ return this.request('POST', endpoint, Object.assign({}, options, { body: body }));
308
+ }
309
+
310
+ /**
311
+ * PUT isteği yapar
312
+ * @param {string} endpoint - API endpoint'i
313
+ * @param {Object} [body] - İstek body'si
314
+ * @param {Object} [options] - İstek seçenekleri
315
+ * @returns {Promise<Object>} API yanıtı
316
+ */
317
+ put(endpoint, body, options) {
318
+ return this.request('PUT', endpoint, Object.assign({}, options, { body: body }));
319
+ }
320
+
321
+ /**
322
+ * PATCH isteği yapar
323
+ * @param {string} endpoint - API endpoint'i
324
+ * @param {Object} [body] - İstek body'si
325
+ * @param {Object} [options] - İstek seçenekleri
326
+ * @returns {Promise<Object>} API yanıtı
327
+ */
328
+ patch(endpoint, body, options) {
329
+ return this.request('PATCH', endpoint, Object.assign({}, options, { body: body }));
330
+ }
331
+
332
+ /**
333
+ * DELETE isteği yapar
334
+ * @param {string} endpoint - API endpoint'i
335
+ * @param {Object} [options] - İstek seçenekleri
336
+ * @returns {Promise<Object>} API yanıtı
337
+ */
338
+ delete(endpoint, options) {
339
+ return this.request('DELETE', endpoint, options);
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Tüm SDK modüllerinin base sınıfı
345
+ * @class BaseModule
346
+ */
347
+ class BaseModule {
348
+ /**
349
+ * BaseModule oluşturur
350
+ * @param {import('./HttpClient.js').HttpClient} httpClient - HTTP client instance
351
+ */
352
+ constructor(httpClient) {
353
+ if (!httpClient) {
354
+ throw new Error('HttpClient is required');
355
+ }
356
+ /** @protected */
357
+ this.http = httpClient;
358
+ }
359
+
360
+ /**
361
+ * Pagination parametrelerini normalize eder
362
+ * @protected
363
+ * @param {Object} options - Pagination seçenekleri
364
+ * @param {number} [options.page=1] - Sayfa numarası
365
+ * @param {number} [options.limit=20] - Sayfa başına kayıt sayısı
366
+ * @param {number} [options.offset] - Offset (alternatif pagination)
367
+ * @returns {Object} Normalize edilmiş pagination parametreleri
368
+ */
369
+ _normalizePagination(options) {
370
+ options = options || {};
371
+ const page = options.page || 1;
372
+ const limit = options.limit || 20;
373
+
374
+ return {
375
+ page: page,
376
+ limit: limit,
377
+ offset: options.offset !== undefined ? options.offset : (page - 1) * limit
378
+ };
379
+ }
380
+
381
+ /**
382
+ * MongoDB ObjectId formatını doğrular
383
+ * @protected
384
+ * @param {string} id - Doğrulanacak ID
385
+ * @returns {boolean} Geçerli mi
386
+ */
387
+ _isValidObjectId(id) {
388
+ if (!id || typeof id !== 'string') {
389
+ return false;
390
+ }
391
+ return /^[a-fA-F0-9]{24}$/.test(id);
392
+ }
393
+
394
+ /**
395
+ * Gerekli parametreleri kontrol eder
396
+ * @protected
397
+ * @param {Object} params - Kontrol edilecek parametreler
398
+ * @param {string[]} required - Zorunlu parametre isimleri
399
+ * @throws {Error} Eksik parametre varsa
400
+ */
401
+ _validateRequired(params, required) {
402
+ const missing = [];
403
+ required.forEach(function(key) {
404
+ if (params[key] === undefined || params[key] === null) {
405
+ missing.push(key);
406
+ }
407
+ });
408
+
409
+ if (missing.length > 0) {
410
+ throw new Error('Missing required parameters: ' + missing.join(', '));
411
+ }
412
+ }
413
+
414
+ /**
415
+ * Tarih değerini ISO string'e çevirir
416
+ * @protected
417
+ * @param {Date|string|number} date - Tarih değeri
418
+ * @returns {string|null} ISO date string veya null
419
+ */
420
+ _toISODate(date) {
421
+ if (!date) {
422
+ return null;
423
+ }
424
+
425
+ if (date instanceof Date) {
426
+ return date.toISOString();
427
+ }
428
+
429
+ if (typeof date === 'number') {
430
+ return new Date(date).toISOString();
431
+ }
432
+
433
+ if (typeof date === 'string') {
434
+ return new Date(date).toISOString();
435
+ }
436
+
437
+ return null;
438
+ }
439
+
440
+ /**
441
+ * Objedeki undefined değerleri temizler
442
+ * @protected
443
+ * @param {Object} obj - Temizlenecek obje
444
+ * @returns {Object} Temizlenmiş obje
445
+ */
446
+ _cleanObject(obj) {
447
+ if (!obj || typeof obj !== 'object') {
448
+ return obj;
449
+ }
450
+
451
+ const cleaned = {};
452
+ Object.keys(obj).forEach(function(key) {
453
+ if (obj[key] !== undefined) {
454
+ cleaned[key] = obj[key];
455
+ }
456
+ });
457
+
458
+ return cleaned;
459
+ }
460
+ }
461
+
462
+ /**
463
+ * Chat (Conversation) modülü
464
+ * Canlı sohbet, WhatsApp, Instagram ve diğer kanal konuşmalarını yönetir
465
+ *
466
+ * @class Chat
467
+ * @extends BaseModule
468
+ * @example
469
+ * // Bir chat'i getir
470
+ * const chat = await supsis.chat.get('507f1f77bcf86cd799439011');
471
+ *
472
+ * // Chat listesini getir
473
+ * const chats = await supsis.chat.list({ status: 'active', limit: 10 });
474
+ *
475
+ * // Chat mesajlarını getir
476
+ * const messages = await supsis.chat.getMessages('507f1f77bcf86cd799439011');
477
+ */
478
+ class Chat extends BaseModule {
479
+ /**
480
+ * Bir chat/conversation bilgisini getirir
481
+ * @param {string} chatId - Chat ID'si (MongoDB ObjectId)
482
+ * @returns {Promise<ChatResponse>} Chat detayları
483
+ * @throws {SupsisAPIError} Chat bulunamadığında veya yetki hatası
484
+ * @example
485
+ * const chat = await supsis.chat.get('507f1f77bcf86cd799439011');
486
+ * console.log(chat.status); // "active", "destroyed", "lost", "new"
487
+ * console.log(chat.visitor); // Contact bilgisi
488
+ */
489
+ async get(chatId) {
490
+ this._validateRequired({ chatId: chatId }, ['chatId']);
491
+ return await this.http.get('/api/conversations/' + chatId);
492
+ }
493
+
494
+ /**
495
+ * Chat mesajlarını getirir
496
+ * @param {string} chatId - Chat ID'si
497
+ * @param {Object} [options] - Mesaj getirme seçenekleri
498
+ * @param {number} [options.limit=50] - Maksimum mesaj sayısı
499
+ * @param {string} [options.before] - Bu ID'den önceki mesajları getir
500
+ * @returns {Promise<MessageResponse[]>} Mesaj listesi
501
+ * @example
502
+ * const messages = await supsis.chat.getMessages('chatId', { limit: 100 });
503
+ */
504
+ async getMessages(chatId, options) {
505
+ this._validateRequired({ chatId: chatId }, ['chatId']);
506
+ options = options || {};
507
+ return await this.http.get('/api/conversations/' + chatId + '/messages', {
508
+ query: this._cleanObject({
509
+ limit: options.limit,
510
+ before: options.before
511
+ })
512
+ });
513
+ }
514
+
515
+ /**
516
+ * Chat mesaj geçmişini getirir (v2 - gelişmiş)
517
+ * @param {string} chatId - Chat ID'si
518
+ * @param {Object} [options] - Seçenekler
519
+ * @param {number} [options.page=1] - Sayfa numarası
520
+ * @param {number} [options.limit=50] - Sayfa başına mesaj sayısı
521
+ * @returns {Promise<{messages: MessageResponse[], total: number, page: number}>}
522
+ */
523
+ async getMessageHistory(chatId, options) {
524
+ this._validateRequired({ chatId: chatId }, ['chatId']);
525
+ options = options || {};
526
+ const pagination = this._normalizePagination(options);
527
+
528
+ return await this.http.get('/api/conversations/' + chatId + '/v2-message-history', {
529
+ query: {
530
+ page: pagination.page,
531
+ limit: pagination.limit
532
+ }
533
+ });
534
+ }
535
+
536
+ /**
537
+ * Chat geçmişini listeler (filtreleme destekli)
538
+ * @param {Object} [options] - Filtreleme seçenekleri
539
+ * @param {string} [options.status] - Chat durumu: 'active', 'destroyed', 'lost', 'new', 'chatbot'
540
+ * @param {string} [options.channel] - Kanal ID'si
541
+ * @param {string} [options.userId] - Temsilci ID'si
542
+ * @param {string} [options.visitorId] - Contact/Visitor ID'si
543
+ * @param {Date|string} [options.startDate] - Başlangıç tarihi
544
+ * @param {Date|string} [options.endDate] - Bitiş tarihi
545
+ * @param {number} [options.page=1] - Sayfa numarası
546
+ * @param {number} [options.limit=20] - Sayfa başına kayıt sayısı
547
+ * @returns {Promise<{data: ChatResponse[], total: number, page: number}>}
548
+ * @example
549
+ * // Aktif chatları listele
550
+ * const activeChats = await supsis.chat.list({ status: 'active' });
551
+ *
552
+ * // Belirli bir kanalın chatlarını getir
553
+ * const whatsappChats = await supsis.chat.list({
554
+ * channel: 'channelId',
555
+ * startDate: '2024-01-01',
556
+ * endDate: '2024-01-31'
557
+ * });
558
+ */
559
+ async list(options) {
560
+ options = options || {};
561
+ const pagination = this._normalizePagination(options);
562
+
563
+ return await this.http.get('/api/conversations/history', {
564
+ query: this._cleanObject({
565
+ status: options.status,
566
+ channel: options.channel,
567
+ userId: options.userId,
568
+ visitorId: options.visitorId,
569
+ startDate: this._toISODate(options.startDate),
570
+ endDate: this._toISODate(options.endDate),
571
+ page: pagination.page,
572
+ limit: pagination.limit
573
+ })
574
+ });
575
+ }
576
+
577
+ /**
578
+ * Realtime chat istatistiklerini getirir
579
+ * @returns {Promise<ChatStatistics>} Anlık chat istatistikleri
580
+ * @example
581
+ * const stats = await supsis.chat.getStats();
582
+ * console.log(stats.activeChats); // Aktif chat sayısı
583
+ * console.log(stats.waitingChats); // Bekleyen chat sayısı
584
+ */
585
+ async getStats() {
586
+ return await this.http.get('/api/conversations/conversation-stat-realtime');
587
+ }
588
+
589
+ /**
590
+ * Chat'e not ekler
591
+ * @param {string} chatId - Chat ID'si
592
+ * @param {string} note - Not içeriği
593
+ * @returns {Promise<ChatResponse>} Güncellenmiş chat
594
+ * @example
595
+ * await supsis.chat.addNote('chatId', 'Müşteri geri aranacak');
596
+ */
597
+ async addNote(chatId, note) {
598
+ this._validateRequired({ chatId: chatId, note: note }, ['chatId', 'note']);
599
+ return await this.http.post('/api/conversations/' + chatId + '/note', {
600
+ note: note
601
+ });
602
+ }
603
+
604
+ /**
605
+ * Chat etiketlerini günceller
606
+ * @param {string} chatId - Chat ID'si
607
+ * @param {string[]} tagIds - Etiket ID'leri
608
+ * @returns {Promise<ChatResponse>} Güncellenmiş chat
609
+ * @example
610
+ * await supsis.chat.updateTags('chatId', ['tagId1', 'tagId2']);
611
+ */
612
+ async updateTags(chatId, tagIds) {
613
+ this._validateRequired({ chatId: chatId }, ['chatId']);
614
+ return await this.http.post('/api/conversations/' + chatId + '/tags', {
615
+ tags: tagIds || []
616
+ });
617
+ }
618
+
619
+ /**
620
+ * Chat'i puanlar (müşteri değerlendirmesi)
621
+ * @param {string} chatId - Chat ID'si
622
+ * @param {number} rating - Puan (1-5)
623
+ * @param {string} [comment] - Yorum
624
+ * @returns {Promise<ChatResponse>} Güncellenmiş chat
625
+ * @example
626
+ * await supsis.chat.rate('chatId', 5, 'Harika hizmet!');
627
+ */
628
+ async rate(chatId, rating, comment) {
629
+ this._validateRequired({ chatId: chatId, rating: rating }, ['chatId', 'rating']);
630
+ return await this.http.post('/api/conversations/' + chatId + '/rate', {
631
+ point: rating,
632
+ description: comment
633
+ });
634
+ }
635
+
636
+ /**
637
+ * Chat transcript'ini email ile gönderir
638
+ * @param {string} chatId - Chat ID'si
639
+ * @param {string} email - Alıcı email adresi
640
+ * @returns {Promise<{success: boolean}>}
641
+ */
642
+ async sendTranscript(chatId, email) {
643
+ this._validateRequired({ chatId: chatId, email: email }, ['chatId', 'email']);
644
+ return await this.http.get('/api/conversations/' + chatId + '/sendTranscript', {
645
+ query: { email: email }
646
+ });
647
+ }
648
+
649
+ /**
650
+ * Chat'i sonlandırır (destroy)
651
+ * @param {string} chatId - Chat ID'si
652
+ * @returns {Promise<ChatResponse>} Sonlandırılmış chat
653
+ */
654
+ async destroy(chatId) {
655
+ this._validateRequired({ chatId: chatId }, ['chatId']);
656
+ return await this.http.post('/api/conversations/' + chatId + '/destroy');
657
+ }
658
+
659
+ /**
660
+ * Belirli bir kullanıcının chatlarını getirir
661
+ * @param {string} userId - Kullanıcı ID'si
662
+ * @param {Object} [options] - Filtreleme seçenekleri
663
+ * @returns {Promise<ChatResponse[]>} Chat listesi
664
+ */
665
+ async getByUser(userId, options) {
666
+ this._validateRequired({ userId: userId }, ['userId']);
667
+ options = options || {};
668
+ return await this.http.get('/api/conversations/user/' + userId, {
669
+ query: this._cleanObject(options)
670
+ });
671
+ }
672
+
673
+ /**
674
+ * WhatsApp contact listesini getirir
675
+ * @param {Object} [options] - Filtreleme seçenekleri
676
+ * @returns {Promise<ContactListResponse>} Contact listesi
677
+ */
678
+ async getWhatsAppContactList(options) {
679
+ options = options || {};
680
+ return await this.http.get('/api/conversations/contact-list/whatsapp', {
681
+ query: this._cleanObject(options)
682
+ });
683
+ }
684
+
685
+ /**
686
+ * Kanal bazlı contact listesini getirir
687
+ * @param {string} channelId - Kanal ID'si
688
+ * @param {Object} [options] - Pagination seçenekleri
689
+ * @returns {Promise<ContactListResponse>}
690
+ */
691
+ async getContactListByChannel(channelId, options) {
692
+ this._validateRequired({ channelId: channelId }, ['channelId']);
693
+ options = options || {};
694
+ return await this.http.get('/api/conversations/contact-list-by-channels', {
695
+ query: this._cleanObject({
696
+ channels: channelId,
697
+ page: options.page,
698
+ limit: options.limit
699
+ })
700
+ });
701
+ }
702
+
703
+ /**
704
+ * Son mesajları toplu getirir
705
+ * @param {string[]} chatIds - Chat ID'leri
706
+ * @returns {Promise<Object>} Chat ID -> Son mesaj mapping
707
+ */
708
+ async getLastMessages(chatIds) {
709
+ this._validateRequired({ chatIds: chatIds }, ['chatIds']);
710
+ return await this.http.post('/api/conversations/last-messages', {
711
+ conversationIds: chatIds
712
+ });
713
+ }
714
+
715
+ /**
716
+ * Tek bir alanı günceller
717
+ * @param {string} chatId - Chat ID'si
718
+ * @param {string} key - Alan adı
719
+ * @param {*} value - Yeni değer
720
+ * @returns {Promise<ChatResponse>}
721
+ */
722
+ async updateField(chatId, key, value) {
723
+ this._validateRequired({ chatId: chatId, key: key }, ['chatId', 'key']);
724
+ return await this.http.put('/api/conversations/' + chatId + '/update-single-key', {
725
+ key: key,
726
+ value: value
727
+ });
728
+ }
729
+ }
730
+
731
+ /**
732
+ * @typedef {Object} ChatResponse
733
+ * @property {string} _id - Chat ID
734
+ * @property {string} siteId - Site ID
735
+ * @property {string} status - Chat durumu: 'new', 'active', 'lost', 'destroyed', 'chatbot', 'private'
736
+ * @property {Object} visitor - Contact/Visitor bilgisi
737
+ * @property {string[]} users - Bağlı temsilci ID'leri
738
+ * @property {string} [channel] - Kanal ID
739
+ * @property {string} [ref] - Referans: 'whatsapp', 'instagram', 'telegram', 'web', 'messenger'
740
+ * @property {Date} createdDate - Oluşturulma tarihi
741
+ * @property {Date} [destroyedDate] - Sonlandırılma tarihi
742
+ * @property {number} [point] - Müşteri puanı (1-5)
743
+ * @property {string} [description] - Müşteri yorumu
744
+ * @property {Object} [note] - Temsilci notu
745
+ * @property {string[]} [tags] - Etiket ID'leri
746
+ * @property {string} [handledBy] - İşleme alan: 'chatbot', 'live', 'hybrid', 'none'
747
+ * @property {number} [avgResponseTime] - Ortalama yanıt süresi (ms)
748
+ * @property {number} [firstAgentResponseTime] - İlk temsilci yanıt süresi (ms)
749
+ */
750
+
751
+ /**
752
+ * @typedef {Object} ChatStatistics
753
+ * @property {number} activeChats - Aktif chat sayısı
754
+ * @property {number} waitingChats - Bekleyen chat sayısı
755
+ * @property {number} lostChats - Kayıp chat sayısı
756
+ * @property {number} totalChats - Toplam chat sayısı
757
+ */
758
+
759
+ /**
760
+ * Contact (Visitor) modülü
761
+ * Müşteri/ziyaretçi verilerini yönetir
762
+ *
763
+ * @class Contact
764
+ * @extends BaseModule
765
+ * @example
766
+ * // Bir contact'ı getir
767
+ * const contact = await supsis.contact.get('507f1f77bcf86cd799439011');
768
+ *
769
+ * // Contact ara
770
+ * const results = await supsis.contact.search({ email: 'user@example.com' });
771
+ *
772
+ * // Contact güncelle
773
+ * await supsis.contact.update('contactId', { fullname: 'John Doe' });
774
+ */
775
+ class Contact extends BaseModule {
776
+ /**
777
+ * Bir contact/visitor bilgisini getirir
778
+ * @param {string} contactId - Contact ID'si (MongoDB ObjectId)
779
+ * @returns {Promise<ContactResponse>} Contact detayları
780
+ * @throws {SupsisAPIError} Contact bulunamadığında
781
+ * @example
782
+ * const contact = await supsis.contact.get('507f1f77bcf86cd799439011');
783
+ * console.log(contact.fullname);
784
+ * console.log(contact.email);
785
+ * console.log(contact.phone);
786
+ */
787
+ async get(contactId) {
788
+ this._validateRequired({ contactId: contactId }, ['contactId']);
789
+ return await this.http.get('/api/visitors/' + contactId);
790
+ }
791
+
792
+ /**
793
+ * Contact listesini getirir
794
+ * @param {Object} [options] - Filtreleme ve pagination seçenekleri
795
+ * @param {number} [options.page=1] - Sayfa numarası
796
+ * @param {number} [options.limit=20] - Sayfa başına kayıt sayısı
797
+ * @param {string} [options.search] - Arama terimi
798
+ * @param {string} [options.owner] - Sahip (temsilci) ID'si
799
+ * @param {string[]} [options.tags] - Etiket ID'leri
800
+ * @param {string} [options.channel] - Kanal ID'si
801
+ * @returns {Promise<{data: ContactResponse[], total: number}>}
802
+ * @example
803
+ * const contacts = await supsis.contact.list({ limit: 50, owner: 'userId' });
804
+ */
805
+ async list(options) {
806
+ options = options || {};
807
+ const pagination = this._normalizePagination(options);
808
+
809
+ return await this.http.post('/api/visitors/visitor-list', {
810
+ page: pagination.page,
811
+ limit: pagination.limit,
812
+ search: options.search,
813
+ owner: options.owner,
814
+ tags: options.tags,
815
+ channel: options.channel
816
+ });
817
+ }
818
+
819
+ /**
820
+ * Contact arar
821
+ * @param {Object} filters - Arama filtreleri
822
+ * @param {string} [filters.email] - Email adresi
823
+ * @param {string} [filters.phone] - Telefon numarası
824
+ * @param {string} [filters.fullname] - İsim
825
+ * @param {string} [filters.query] - Genel arama terimi
826
+ * @param {Object} [options] - Pagination seçenekleri
827
+ * @returns {Promise<{data: ContactResponse[], total: number}>}
828
+ * @example
829
+ * // Email ile ara
830
+ * const results = await supsis.contact.search({ email: 'user@example.com' });
831
+ *
832
+ * // Telefon ile ara
833
+ * const results = await supsis.contact.search({ phone: '+905551234567' });
834
+ */
835
+ async search(filters, options) {
836
+ filters = filters || {};
837
+ options = options || {};
838
+ const pagination = this._normalizePagination(options);
839
+
840
+ return await this.http.get('/api/visitors/search', {
841
+ query: this._cleanObject({
842
+ email: filters.email,
843
+ phone: filters.phone,
844
+ fullname: filters.fullname,
845
+ query: filters.query,
846
+ page: pagination.page,
847
+ limit: pagination.limit
848
+ })
849
+ });
850
+ }
851
+
852
+ /**
853
+ * Gelişmiş filtre ile contact arar
854
+ * @param {FilterGroup[]} filterGroups - Filtre grupları
855
+ * @param {Object} [options] - Pagination seçenekleri
856
+ * @param {string[]} [projectionFields] - Döndürülecek alanlar
857
+ * @returns {Promise<{data: ContactResponse[], total: number}>}
858
+ * @example
859
+ * const results = await supsis.contact.advancedSearch([
860
+ * {
861
+ * filters: [
862
+ * { field: 'email', operator: 'contains', value: '@gmail.com' },
863
+ * { field: 'createdDate', operator: 'after', value: '2024-01-01' }
864
+ * ],
865
+ * logic: 'and'
866
+ * }
867
+ * ]);
868
+ */
869
+ async advancedSearch(filterGroups, options, projectionFields) {
870
+ options = options || {};
871
+ const pagination = this._normalizePagination(options);
872
+
873
+ return await this.http.post('/api/visitors/contacts-by-advanced-filter', {
874
+ filterGroups: filterGroups,
875
+ cursor: {
876
+ offset: pagination.offset,
877
+ limit: pagination.limit
878
+ },
879
+ projectionFields: projectionFields
880
+ });
881
+ }
882
+
883
+ /**
884
+ * Contact oluşturur
885
+ * @param {Object} data - Contact verileri
886
+ * @param {string} data.fullname - İsim
887
+ * @param {string} [data.email] - Email
888
+ * @param {string} [data.phone] - Telefon
889
+ * @param {string} [data.platform] - Platform: 'whatsapp', 'web', 'instagram', etc.
890
+ * @param {string[]} [data.channelIds] - Kanal ID'leri
891
+ * @param {Object} [data.contactProperties] - Özel alanlar
892
+ * @returns {Promise<ContactResponse>} Oluşturulan contact
893
+ * @example
894
+ * const contact = await supsis.contact.create({
895
+ * fullname: 'John Doe',
896
+ * email: 'john@example.com',
897
+ * phone: '+905551234567'
898
+ * });
899
+ */
900
+ async create(data) {
901
+ this._validateRequired(data, ['fullname']);
902
+ return await this.http.post('/api/visitors/contacts', data);
903
+ }
904
+
905
+ /**
906
+ * Contact günceller
907
+ * @param {string} contactId - Contact ID'si
908
+ * @param {Object} data - Güncellenecek veriler
909
+ * @param {string} [data.fullname] - İsim
910
+ * @param {string} [data.email] - Email
911
+ * @param {string} [data.phone] - Telefon
912
+ * @param {string} [data.owner] - Sahip (temsilci) ID'si
913
+ * @returns {Promise<ContactResponse>} Güncellenmiş contact
914
+ * @example
915
+ * await supsis.contact.update('contactId', {
916
+ * fullname: 'Jane Doe',
917
+ * email: 'jane@example.com'
918
+ * });
919
+ */
920
+ async update(contactId, data) {
921
+ this._validateRequired({ contactId: contactId }, ['contactId']);
922
+ return await this.http.post('/api/visitors/' + contactId + '/update', data);
923
+ }
924
+
925
+ /**
926
+ * Contact siler
927
+ * @param {string} contactId - Contact ID'si
928
+ * @returns {Promise<{success: boolean}>}
929
+ */
930
+ async delete(contactId) {
931
+ this._validateRequired({ contactId: contactId }, ['contactId']);
932
+ return await this.http.delete('/api/visitors/' + contactId);
933
+ }
934
+
935
+ /**
936
+ * Birden fazla contact siler
937
+ * @param {string[]} contactIds - Contact ID'leri
938
+ * @returns {Promise<{success: boolean, deletedCount: number}>}
939
+ */
940
+ async deleteMany(contactIds) {
941
+ this._validateRequired({ contactIds: contactIds }, ['contactIds']);
942
+ return await this.http.post('/api/visitors/delete-multi-visitor', {
943
+ visitorIds: contactIds
944
+ });
945
+ }
946
+
947
+ /**
948
+ * Contact'a etiket ekler
949
+ * @param {string} contactId - Contact ID'si
950
+ * @param {string} tagId - Etiket ID'si
951
+ * @returns {Promise<ContactResponse>}
952
+ * @example
953
+ * await supsis.contact.addTag('contactId', 'tagId');
954
+ */
955
+ async addTag(contactId, tagId) {
956
+ this._validateRequired({ contactId: contactId, tagId: tagId }, ['contactId', 'tagId']);
957
+ return await this.http.post('/api/visitors/updateTagVisitor/' + contactId, {
958
+ tagId: tagId,
959
+ action: 'add'
960
+ });
961
+ }
962
+
963
+ /**
964
+ * Contact'tan etiket kaldırır
965
+ * @param {string} contactId - Contact ID'si
966
+ * @param {string} tagId - Etiket ID'si
967
+ * @returns {Promise<ContactResponse>}
968
+ */
969
+ async removeTag(contactId, tagId) {
970
+ this._validateRequired({ contactId: contactId, tagId: tagId }, ['contactId', 'tagId']);
971
+ return await this.http.post('/api/visitors/updateTagVisitor/' + contactId, {
972
+ tagId: tagId,
973
+ action: 'remove'
974
+ });
975
+ }
976
+
977
+ /**
978
+ * Contact'ı engeller
979
+ * @param {string} contactId - Contact ID'si
980
+ * @param {string} [reason] - Engelleme nedeni
981
+ * @returns {Promise<ContactResponse>}
982
+ */
983
+ async block(contactId, reason) {
984
+ this._validateRequired({ contactId: contactId }, ['contactId']);
985
+ return await this.http.post('/api/visitors/' + contactId + '/block', {
986
+ reason: reason
987
+ });
988
+ }
989
+
990
+ /**
991
+ * Contact engelini kaldırır
992
+ * @param {string} contactId - Contact ID'si
993
+ * @returns {Promise<ContactResponse>}
994
+ */
995
+ async unblock(contactId) {
996
+ this._validateRequired({ contactId: contactId }, ['contactId']);
997
+ return await this.http.post('/api/visitors/' + contactId + '/unblock');
998
+ }
999
+
1000
+ /**
1001
+ * Contact'ın sohbet geçmişini getirir
1002
+ * @param {string} contactId - Contact ID'si
1003
+ * @param {Object} [options] - Pagination seçenekleri
1004
+ * @returns {Promise<ChatResponse[]>}
1005
+ */
1006
+ async getChatHistory(contactId, options) {
1007
+ this._validateRequired({ contactId: contactId }, ['contactId']);
1008
+ options = options || {};
1009
+ const pagination = this._normalizePagination(options);
1010
+
1011
+ return await this.http.get('/api/visitors/' + contactId + '/conversations-paged', {
1012
+ query: {
1013
+ page: pagination.page,
1014
+ limit: pagination.limit
1015
+ }
1016
+ });
1017
+ }
1018
+
1019
+ /**
1020
+ * Contact notlarını getirir
1021
+ * @param {string} contactId - Contact ID'si
1022
+ * @returns {Promise<NoteResponse[]>}
1023
+ */
1024
+ async getNotes(contactId) {
1025
+ this._validateRequired({ contactId: contactId }, ['contactId']);
1026
+ return await this.http.get('/api/visitors/' + contactId + '/notes-v2');
1027
+ }
1028
+
1029
+ /**
1030
+ * Contact'a not ekler
1031
+ * @param {string} contactId - Contact ID'si
1032
+ * @param {string} content - Not içeriği
1033
+ * @returns {Promise<NoteResponse>}
1034
+ */
1035
+ async addNote(contactId, content) {
1036
+ this._validateRequired({ contactId: contactId, content: content }, ['contactId', 'content']);
1037
+ return await this.http.post('/api/visitors/' + contactId + '/notes-v2', {
1038
+ content: content
1039
+ });
1040
+ }
1041
+
1042
+ /**
1043
+ * Contact notunu günceller
1044
+ * @param {string} contactId - Contact ID'si
1045
+ * @param {string} noteId - Not ID'si
1046
+ * @param {string} content - Yeni not içeriği
1047
+ * @returns {Promise<NoteResponse>}
1048
+ */
1049
+ async updateNote(contactId, noteId, content) {
1050
+ this._validateRequired({ contactId: contactId, noteId: noteId, content: content }, ['contactId', 'noteId', 'content']);
1051
+ return await this.http.post('/api/visitors/' + contactId + '/notes-v2/' + noteId, {
1052
+ content: content
1053
+ });
1054
+ }
1055
+
1056
+ /**
1057
+ * Contact notunu siler
1058
+ * @param {string} noteId - Not ID'si
1059
+ * @returns {Promise<{success: boolean}>}
1060
+ */
1061
+ async deleteNote(noteId) {
1062
+ this._validateRequired({ noteId: noteId }, ['noteId']);
1063
+ return await this.http.delete('/api/visitors/notes-v2/' + noteId);
1064
+ }
1065
+
1066
+ /**
1067
+ * Contact property günceller
1068
+ * @param {string} contactId - Contact ID'si
1069
+ * @param {string} propertyId - Property ID'si
1070
+ * @param {*} value - Yeni değer
1071
+ * @returns {Promise<ContactResponse>}
1072
+ */
1073
+ async updateProperty(contactId, propertyId, value) {
1074
+ this._validateRequired({ contactId: contactId, propertyId: propertyId }, ['contactId', 'propertyId']);
1075
+ return await this.http.put('/api/visitors/' + contactId + '/contact-property/' + propertyId, {
1076
+ value: value
1077
+ });
1078
+ }
1079
+
1080
+ /**
1081
+ * Contact sahipliğini değiştirir
1082
+ * @param {string} contactId - Contact ID'si
1083
+ * @param {string} ownerId - Yeni sahip (temsilci) ID'si
1084
+ * @returns {Promise<ContactResponse>}
1085
+ */
1086
+ async changeOwner(contactId, ownerId) {
1087
+ this._validateRequired({ contactId: contactId, ownerId: ownerId }, ['contactId', 'ownerId']);
1088
+ return await this.http.post('/api/visitors/' + contactId + '/update', {
1089
+ owner: ownerId
1090
+ });
1091
+ }
1092
+
1093
+ /**
1094
+ * Contact'ların tercih edilen temsilcilerini günceller
1095
+ * @param {string} contactId - Contact ID'si
1096
+ * @param {string[]} agentIds - Temsilci ID'leri
1097
+ * @returns {Promise<ContactResponse>}
1098
+ */
1099
+ async updatePreferredAgents(contactId, agentIds) {
1100
+ this._validateRequired({ contactId: contactId }, ['contactId']);
1101
+ return await this.http.post('/api/visitors/' + contactId + '/update-preferred-agents', {
1102
+ agents: agentIds || []
1103
+ });
1104
+ }
1105
+
1106
+ /**
1107
+ * Contact'ın medya dosyalarını getirir
1108
+ * @param {string} contactId - Contact ID'si
1109
+ * @param {Object} [options] - Filtreleme seçenekleri
1110
+ * @returns {Promise<AssetResponse[]>}
1111
+ */
1112
+ async getMedia(contactId, options) {
1113
+ this._validateRequired({ contactId: contactId }, ['contactId']);
1114
+ return await this.http.get('/api/visitors/' + contactId + '/media', {
1115
+ query: this._cleanObject(options)
1116
+ });
1117
+ }
1118
+
1119
+ /**
1120
+ * İki contact'ı birleştirir
1121
+ * @param {string} primaryContactId - Ana contact ID'si (korunacak)
1122
+ * @param {string} secondaryContactId - İkincil contact ID'si (birleştirilecek)
1123
+ * @returns {Promise<ContactResponse>} Birleştirilmiş contact
1124
+ */
1125
+ async merge(primaryContactId, secondaryContactId) {
1126
+ this._validateRequired({
1127
+ primaryContactId: primaryContactId,
1128
+ secondaryContactId: secondaryContactId
1129
+ }, ['primaryContactId', 'secondaryContactId']);
1130
+
1131
+ return await this.http.post('/api/visitors/merge-visitors', {
1132
+ primaryVisitorId: primaryContactId,
1133
+ secondaryVisitorId: secondaryContactId
1134
+ });
1135
+ }
1136
+
1137
+ /**
1138
+ * Contact listesini Excel olarak indirir
1139
+ * @param {Object} [filters] - Filtreleme seçenekleri
1140
+ * @returns {Promise<Blob>} Excel dosyası
1141
+ */
1142
+ async downloadExcel(filters) {
1143
+ return await this.http.post('/api/visitors/visitor-list/download', filters || {});
1144
+ }
1145
+ }
1146
+
1147
+ /**
1148
+ * @typedef {Object} ContactResponse
1149
+ * @property {string} _id - Contact ID
1150
+ * @property {string} siteId - Site ID
1151
+ * @property {string} [fullname] - İsim
1152
+ * @property {string} [email] - Email adresi
1153
+ * @property {string} [phone] - Telefon numarası
1154
+ * @property {string} [owner] - Sahip (temsilci) ID
1155
+ * @property {string[]} [tags] - Etiket ID'leri
1156
+ * @property {string} [platform] - Platform: 'whatsapp', 'web', 'instagram', etc.
1157
+ * @property {Object} [contactProperties] - Özel alanlar
1158
+ * @property {string} [status] - Durum: 'online', 'offline', 'blocked'
1159
+ * @property {Date} createdDate - Oluşturulma tarihi
1160
+ * @property {Date} [lastSeenDate] - Son görülme tarihi
1161
+ * @property {Object} [lastConversation] - Son sohbet bilgisi
1162
+ * @property {string} [whatsappNumber] - WhatsApp numarası
1163
+ * @property {string} [instagramUserId] - Instagram kullanıcı ID'si
1164
+ * @property {Object} [geoLocation] - Konum bilgisi
1165
+ */
1166
+
1167
+ /**
1168
+ * @typedef {Object} NoteResponse
1169
+ * @property {string} _id - Not ID
1170
+ * @property {string} content - Not içeriği
1171
+ * @property {string} createdBy - Oluşturan kullanıcı ID
1172
+ * @property {Date} createdAt - Oluşturulma tarihi
1173
+ * @property {Date} [updatedAt] - Güncellenme tarihi
1174
+ */
1175
+
1176
+ /**
1177
+ * @typedef {Object} FilterGroup
1178
+ * @property {Filter[]} filters - Filtreler
1179
+ * @property {'and'|'or'} logic - Mantıksal operatör
1180
+ */
1181
+
1182
+ /**
1183
+ * @typedef {Object} Filter
1184
+ * @property {string} field - Alan adı
1185
+ * @property {string} operator - Operatör: 'equals', 'contains', 'startsWith', 'after', 'before', etc.
1186
+ * @property {*} value - Değer
1187
+ */
1188
+
1189
+ /**
1190
+ * Message modülü
1191
+ * Sohbet mesajlarını yönetir
1192
+ *
1193
+ * @class Message
1194
+ * @extends BaseModule
1195
+ * @example
1196
+ * // Mesajları getir
1197
+ * const messages = await supsis.message.list('conversationId');
1198
+ *
1199
+ * // Mesaj ara
1200
+ * const results = await supsis.message.search({ query: 'sipariş' });
1201
+ */
1202
+ class Message extends BaseModule {
1203
+ /**
1204
+ * Bir mesajı ID'ye göre getirir
1205
+ * @param {string} messageId - Mesaj ID'si
1206
+ * @returns {Promise<MessageResponse>} Mesaj detayları
1207
+ * @example
1208
+ * const message = await supsis.message.get('messageId');
1209
+ * console.log(message.message); // Mesaj içeriği
1210
+ * console.log(message.senderType); // 'visitor' veya 'user'
1211
+ */
1212
+ async get(messageId) {
1213
+ this._validateRequired({ messageId: messageId }, ['messageId']);
1214
+ return await this.http.post('/api/messages/get-message', {
1215
+ messageId: messageId
1216
+ });
1217
+ }
1218
+
1219
+ /**
1220
+ * Bir sohbetteki mesajları listeler
1221
+ * @param {string} conversationId - Sohbet ID'si
1222
+ * @param {Object} [options] - Listeleme seçenekleri
1223
+ * @param {number} [options.limit=50] - Maksimum mesaj sayısı
1224
+ * @param {string} [options.before] - Bu ID'den önceki mesajları getir
1225
+ * @param {string} [options.after] - Bu ID'den sonraki mesajları getir
1226
+ * @returns {Promise<MessageResponse[]>} Mesaj listesi
1227
+ * @example
1228
+ * const messages = await supsis.message.list('conversationId', { limit: 100 });
1229
+ */
1230
+ async list(conversationId, options) {
1231
+ this._validateRequired({ conversationId: conversationId }, ['conversationId']);
1232
+ options = options || {};
1233
+
1234
+ return await this.http.get('/api/messages/' + conversationId, {
1235
+ query: this._cleanObject({
1236
+ limit: options.limit,
1237
+ before: options.before,
1238
+ after: options.after
1239
+ })
1240
+ });
1241
+ }
1242
+
1243
+ /**
1244
+ * Mesajlarda arama yapar
1245
+ * @param {Object} options - Arama seçenekleri
1246
+ * @param {string} options.query - Arama terimi
1247
+ * @param {string} [options.conversationId] - Belirli bir sohbette ara
1248
+ * @param {string} [options.visitorId] - Belirli bir contact'ın mesajlarında ara
1249
+ * @param {string} [options.userId] - Belirli bir temsilcinin mesajlarında ara
1250
+ * @param {Date|string} [options.startDate] - Başlangıç tarihi
1251
+ * @param {Date|string} [options.endDate] - Bitiş tarihi
1252
+ * @param {number} [options.page=1] - Sayfa numarası
1253
+ * @param {number} [options.limit=20] - Sayfa başına sonuç sayısı
1254
+ * @returns {Promise<{data: MessageResponse[], total: number}>}
1255
+ * @example
1256
+ * // Genel arama
1257
+ * const results = await supsis.message.search({ query: 'sipariş numarası' });
1258
+ *
1259
+ * // Belirli bir sohbette arama
1260
+ * const results = await supsis.message.search({
1261
+ * query: 'fatura',
1262
+ * conversationId: 'chatId',
1263
+ * startDate: '2024-01-01'
1264
+ * });
1265
+ */
1266
+ async search(options) {
1267
+ this._validateRequired(options, ['query']);
1268
+ const pagination = this._normalizePagination(options);
1269
+
1270
+ return await this.http.post('/api/messages/search-messages', {
1271
+ query: options.query,
1272
+ conversationId: options.conversationId,
1273
+ visitorId: options.visitorId,
1274
+ userId: options.userId,
1275
+ startDate: this._toISODate(options.startDate),
1276
+ endDate: this._toISODate(options.endDate),
1277
+ page: pagination.page,
1278
+ limit: pagination.limit
1279
+ });
1280
+ }
1281
+
1282
+ /**
1283
+ * Birden fazla mesajı ID'lere göre getirir
1284
+ * @param {string[]} messageIds - Mesaj ID'leri
1285
+ * @returns {Promise<MessageResponse[]>}
1286
+ */
1287
+ async getMany(messageIds) {
1288
+ this._validateRequired({ messageIds: messageIds }, ['messageIds']);
1289
+ return await this.http.post('/api/messages/get-message', {
1290
+ messageIds: messageIds
1291
+ });
1292
+ }
1293
+ }
1294
+
1295
+ /**
1296
+ * @typedef {Object} MessageResponse
1297
+ * @property {string} _id - Mesaj ID
1298
+ * @property {string} siteId - Site ID
1299
+ * @property {string} conversationId - Sohbet ID
1300
+ * @property {string} message - Mesaj içeriği
1301
+ * @property {string} senderType - Gönderen tipi: 'visitor', 'user', 'system', 'chatbot'
1302
+ * @property {string} [senderId] - Gönderen ID (user veya visitor)
1303
+ * @property {string} messageType - Mesaj tipi: 'text', 'image', 'file', 'audio', 'video', 'location', 'template'
1304
+ * @property {Date} createdDate - Gönderilme tarihi
1305
+ * @property {Object} [asset] - Dosya/medya bilgisi
1306
+ * @property {Object} [location] - Konum bilgisi (lat, lng)
1307
+ * @property {boolean} [isRead] - Okundu mu
1308
+ * @property {Date} [readDate] - Okunma tarihi
1309
+ * @property {string} [status] - Durum: 'sent', 'delivered', 'read', 'failed'
1310
+ * @property {Object} [replyTo] - Yanıtlanan mesaj bilgisi
1311
+ * @property {Object} [metadata] - Ek metadata
1312
+ * @property {string} [externalProviderId] - Harici sağlayıcı mesaj ID'si (WhatsApp, Instagram vb.)
1313
+ * @property {string} [gupshupMessageId] - Gupshup mesaj ID'si
1314
+ * @property {string} [metaMessageId] - Meta (WhatsApp/Instagram) mesaj ID'si
1315
+ */
1316
+
1317
+ /**
1318
+ * Task modülü
1319
+ * Görev ve iş akışı yönetimi
1320
+ *
1321
+ * @class Task
1322
+ * @extends BaseModule
1323
+ * @example
1324
+ * // Görev oluştur
1325
+ * const task = await supsis.task.create({
1326
+ * title: 'Müşteriyi ara',
1327
+ * workflowId: 'workflowId',
1328
+ * pipelineId: 'pipelineId'
1329
+ * });
1330
+ *
1331
+ * // Görevleri listele
1332
+ * const tasks = await supsis.task.list('workflowId');
1333
+ */
1334
+ class Task extends BaseModule {
1335
+ /**
1336
+ * Bir görevi ID'ye göre getirir
1337
+ * @param {string} taskId - Görev ID'si
1338
+ * @returns {Promise<TaskResponse>} Görev detayları
1339
+ * @example
1340
+ * const task = await supsis.task.get('taskId');
1341
+ * console.log(task.title);
1342
+ * console.log(task.status); // 'open', 'done', 'archived'
1343
+ */
1344
+ async get(taskId) {
1345
+ this._validateRequired({ taskId: taskId }, ['taskId']);
1346
+ return await this.http.get('/api/tasks/' + taskId + '/detail');
1347
+ }
1348
+
1349
+ /**
1350
+ * Bir iş akışındaki görevleri listeler
1351
+ * @param {string} workflowId - İş akışı ID'si
1352
+ * @param {Object} [options] - Filtreleme seçenekleri
1353
+ * @param {string} [options.pipelineId] - Pipeline/aşama ID'si
1354
+ * @param {string} [options.assignee] - Atanan kişi ID'si
1355
+ * @param {string} [options.status] - Durum filtresi
1356
+ * @returns {Promise<TaskResponse[]>}
1357
+ * @example
1358
+ * const tasks = await supsis.task.list('workflowId');
1359
+ * const pipelineTasks = await supsis.task.list('workflowId', { pipelineId: 'pipelineId' });
1360
+ */
1361
+ async list(workflowId, options) {
1362
+ this._validateRequired({ workflowId: workflowId }, ['workflowId']);
1363
+ options = options || {};
1364
+
1365
+ if (options.pipelineId) {
1366
+ return await this.http.get('/api/tasks/' + workflowId + '/' + options.pipelineId);
1367
+ }
1368
+ return await this.http.get('/api/tasks/' + workflowId);
1369
+ }
1370
+
1371
+ /**
1372
+ * Görev oluşturur
1373
+ * @param {Object} data - Görev verileri
1374
+ * @param {string} data.title - Görev başlığı
1375
+ * @param {string} data.workflowId - İş akışı ID'si
1376
+ * @param {string} data.pipelineId - Pipeline/aşama ID'si
1377
+ * @param {string} [data.description] - Açıklama
1378
+ * @param {string} [data.assignee] - Atanan kişi ID'si
1379
+ * @param {Date|string} [data.dueDate] - Bitiş tarihi
1380
+ * @param {string} [data.priority] - Öncelik: 'low', 'medium', 'high', 'urgent'
1381
+ * @param {string} [data.contactId] - İlişkili contact ID'si
1382
+ * @param {Object} [data.customFields] - Özel alanlar
1383
+ * @returns {Promise<TaskResponse>} Oluşturulan görev
1384
+ * @example
1385
+ * const task = await supsis.task.create({
1386
+ * title: 'Müşteriyi ara',
1387
+ * workflowId: 'workflowId',
1388
+ * pipelineId: 'pipelineId',
1389
+ * assignee: 'userId',
1390
+ * dueDate: '2024-12-31',
1391
+ * priority: 'high',
1392
+ * contactId: 'contactId'
1393
+ * });
1394
+ */
1395
+ async create(data) {
1396
+ this._validateRequired(data, ['title', 'workflowId', 'pipelineId']);
1397
+
1398
+ return await this.http.post('/api/tasks', {
1399
+ title: data.title,
1400
+ workflowId: data.workflowId,
1401
+ pipelineId: data.pipelineId,
1402
+ description: data.description,
1403
+ assignee: data.assignee,
1404
+ dueDate: this._toISODate(data.dueDate),
1405
+ priority: data.priority,
1406
+ contactId: data.contactId,
1407
+ customFields: data.customFields
1408
+ });
1409
+ }
1410
+
1411
+ /**
1412
+ * Basit görev oluşturur (minimal verilerle)
1413
+ * @param {Object} data - Görev verileri
1414
+ * @param {string} data.title - Görev başlığı
1415
+ * @param {string} data.workflowId - İş akışı ID'si
1416
+ * @param {string} data.pipelineId - Pipeline/aşama ID'si
1417
+ * @returns {Promise<TaskResponse>}
1418
+ */
1419
+ async createSimple(data) {
1420
+ this._validateRequired(data, ['title', 'workflowId', 'pipelineId']);
1421
+ return await this.http.post('/api/tasks/simple', data);
1422
+ }
1423
+
1424
+ /**
1425
+ * Görevi günceller
1426
+ * @param {string} taskId - Görev ID'si
1427
+ * @param {Object} data - Güncellenecek veriler
1428
+ * @returns {Promise<TaskResponse>}
1429
+ * @example
1430
+ * await supsis.task.update('taskId', {
1431
+ * title: 'Yeni başlık',
1432
+ * priority: 'urgent'
1433
+ * });
1434
+ */
1435
+ async update(taskId, data) {
1436
+ this._validateRequired({ taskId: taskId }, ['taskId']);
1437
+ return await this.http.patch('/api/tasks/' + taskId, data);
1438
+ }
1439
+
1440
+ /**
1441
+ * Görevi siler
1442
+ * @param {string} taskId - Görev ID'si
1443
+ * @returns {Promise<{success: boolean}>}
1444
+ */
1445
+ async delete(taskId) {
1446
+ this._validateRequired({ taskId: taskId }, ['taskId']);
1447
+ return await this.http.delete('/api/tasks/' + taskId);
1448
+ }
1449
+
1450
+ /**
1451
+ * Görevi başka bir aşamaya taşır
1452
+ * @param {string} taskId - Görev ID'si
1453
+ * @param {string} pipelineId - Hedef pipeline/aşama ID'si
1454
+ * @param {number} [position] - Yeni pozisyon (sıra)
1455
+ * @returns {Promise<TaskResponse>}
1456
+ * @example
1457
+ * await supsis.task.move('taskId', 'newPipelineId');
1458
+ */
1459
+ async move(taskId, pipelineId, position) {
1460
+ this._validateRequired({ taskId: taskId, pipelineId: pipelineId }, ['taskId', 'pipelineId']);
1461
+ return await this.http.patch('/api/tasks/' + taskId + '/position', {
1462
+ pipelineId: pipelineId,
1463
+ position: position
1464
+ });
1465
+ }
1466
+
1467
+ /**
1468
+ * Görevi tamamlandı olarak işaretler
1469
+ * @param {string} taskId - Görev ID'si
1470
+ * @returns {Promise<TaskResponse>}
1471
+ */
1472
+ async complete(taskId) {
1473
+ this._validateRequired({ taskId: taskId }, ['taskId']);
1474
+ return await this.http.patch('/api/tasks/' + taskId + '/done');
1475
+ }
1476
+
1477
+ /**
1478
+ * Görevi arşivler
1479
+ * @param {string} taskId - Görev ID'si
1480
+ * @returns {Promise<TaskResponse>}
1481
+ */
1482
+ async archive(taskId) {
1483
+ this._validateRequired({ taskId: taskId }, ['taskId']);
1484
+ return await this.http.patch('/api/tasks/' + taskId + '/archive');
1485
+ }
1486
+
1487
+ /**
1488
+ * Birden fazla görevi siler
1489
+ * @param {string[]} taskIds - Görev ID'leri
1490
+ * @returns {Promise<{success: boolean, deletedCount: number}>}
1491
+ */
1492
+ async deleteMany(taskIds) {
1493
+ this._validateRequired({ taskIds: taskIds }, ['taskIds']);
1494
+ return await this.http.post('/api/tasks/multiple/delete', {
1495
+ taskIds: taskIds
1496
+ });
1497
+ }
1498
+
1499
+ /**
1500
+ * Birden fazla görevi taşır
1501
+ * @param {string[]} taskIds - Görev ID'leri
1502
+ * @param {string} pipelineId - Hedef pipeline ID'si
1503
+ * @returns {Promise<{success: boolean}>}
1504
+ */
1505
+ async moveMany(taskIds, pipelineId) {
1506
+ this._validateRequired({ taskIds: taskIds, pipelineId: pipelineId }, ['taskIds', 'pipelineId']);
1507
+ return await this.http.post('/api/tasks/multiple/change-pipeline', {
1508
+ taskIds: taskIds,
1509
+ pipelineId: pipelineId
1510
+ });
1511
+ }
1512
+
1513
+ /**
1514
+ * Birden fazla görevi tamamlar
1515
+ * @param {string[]} taskIds - Görev ID'leri
1516
+ * @returns {Promise<{success: boolean}>}
1517
+ */
1518
+ async completeMany(taskIds) {
1519
+ this._validateRequired({ taskIds: taskIds }, ['taskIds']);
1520
+ return await this.http.post('/api/tasks/multiple/done', {
1521
+ taskIds: taskIds
1522
+ });
1523
+ }
1524
+
1525
+ /**
1526
+ * Görev aktivitelerini getirir
1527
+ * @param {string} taskId - Görev ID'si
1528
+ * @returns {Promise<ActivityResponse[]>}
1529
+ */
1530
+ async getActivities(taskId) {
1531
+ this._validateRequired({ taskId: taskId }, ['taskId']);
1532
+ return await this.http.get('/api/tasks/get-task-activity/' + taskId);
1533
+ }
1534
+
1535
+ /**
1536
+ * Tamamlanmış görevleri listeler
1537
+ * @param {Object} [options] - Filtreleme seçenekleri
1538
+ * @returns {Promise<TaskResponse[]>}
1539
+ */
1540
+ async listCompleted(options) {
1541
+ return await this.http.get('/api/tasks/done-tasks', {
1542
+ query: this._cleanObject(options)
1543
+ });
1544
+ }
1545
+
1546
+ /**
1547
+ * Arşivlenmiş görevleri listeler
1548
+ * @param {Object} [options] - Filtreleme seçenekleri
1549
+ * @returns {Promise<TaskResponse[]>}
1550
+ */
1551
+ async listArchived(options) {
1552
+ return await this.http.get('/api/tasks/archive-tasks', {
1553
+ query: this._cleanObject(options)
1554
+ });
1555
+ }
1556
+
1557
+ /**
1558
+ * Tarihe göre görev listesi getirir (takvim görünümü için)
1559
+ * @param {Date|string} date - Tarih
1560
+ * @returns {Promise<TaskResponse[]>}
1561
+ */
1562
+ async listByDate(date) {
1563
+ this._validateRequired({ date: date }, ['date']);
1564
+ return await this.http.get('/api/tasks/get-event-list-by-date', {
1565
+ query: {
1566
+ date: this._toISODate(date)
1567
+ }
1568
+ });
1569
+ }
1570
+
1571
+ /**
1572
+ * Belirli bir contact'ın görevlerini listeler
1573
+ * @param {string} contactId - Contact ID'si
1574
+ * @returns {Promise<TaskResponse[]>}
1575
+ */
1576
+ async listByContact(contactId) {
1577
+ this._validateRequired({ contactId: contactId }, ['contactId']);
1578
+ return await this.http.get('/api/tasks/visitor-tasks', {
1579
+ query: { visitorId: contactId }
1580
+ });
1581
+ }
1582
+
1583
+ // ==================== WORKFLOW METHODS ====================
1584
+
1585
+ /**
1586
+ * Tüm iş akışlarını listeler
1587
+ * @returns {Promise<WorkflowResponse[]>}
1588
+ * @example
1589
+ * const workflows = await supsis.task.listWorkflows();
1590
+ */
1591
+ async listWorkflows() {
1592
+ return await this.http.get('/api/tasks/workflows');
1593
+ }
1594
+
1595
+ /**
1596
+ * Bir iş akışını getirir
1597
+ * @param {string} workflowId - İş akışı ID'si
1598
+ * @returns {Promise<WorkflowResponse>}
1599
+ */
1600
+ async getWorkflow(workflowId) {
1601
+ this._validateRequired({ workflowId: workflowId }, ['workflowId']);
1602
+ return await this.http.get('/api/tasks/workflows/' + workflowId);
1603
+ }
1604
+
1605
+ /**
1606
+ * İş akışı oluşturur
1607
+ * @param {Object} data - İş akışı verileri
1608
+ * @param {string} data.name - İş akışı adı
1609
+ * @param {string} [data.description] - Açıklama
1610
+ * @param {string} [data.color] - Renk kodu
1611
+ * @returns {Promise<WorkflowResponse>}
1612
+ */
1613
+ async createWorkflow(data) {
1614
+ this._validateRequired(data, ['name']);
1615
+ return await this.http.post('/api/tasks/workflows', data);
1616
+ }
1617
+
1618
+ /**
1619
+ * İş akışını günceller
1620
+ * @param {string} workflowId - İş akışı ID'si
1621
+ * @param {Object} data - Güncellenecek veriler
1622
+ * @returns {Promise<WorkflowResponse>}
1623
+ */
1624
+ async updateWorkflow(workflowId, data) {
1625
+ this._validateRequired({ workflowId: workflowId }, ['workflowId']);
1626
+ return await this.http.patch('/api/tasks/workflows/' + workflowId, data);
1627
+ }
1628
+
1629
+ /**
1630
+ * İş akışını siler
1631
+ * @param {string} workflowId - İş akışı ID'si
1632
+ * @returns {Promise<{success: boolean}>}
1633
+ */
1634
+ async deleteWorkflow(workflowId) {
1635
+ this._validateRequired({ workflowId: workflowId }, ['workflowId']);
1636
+ return await this.http.delete('/api/tasks/workflows/' + workflowId);
1637
+ }
1638
+
1639
+ /**
1640
+ * İş akışı ile birlikte tüm pipeline ve görevleri getirir
1641
+ * @param {string} workflowId - İş akışı ID'si
1642
+ * @returns {Promise<WorkflowFullResponse>}
1643
+ */
1644
+ async getWorkflowFull(workflowId) {
1645
+ this._validateRequired({ workflowId: workflowId }, ['workflowId']);
1646
+ return await this.http.get('/api/tasks/workflows/' + workflowId + '/full');
1647
+ }
1648
+
1649
+ /**
1650
+ * İş akışı raporlarını getirir
1651
+ * @param {string} workflowId - İş akışı ID'si
1652
+ * @returns {Promise<WorkflowReportResponse>}
1653
+ */
1654
+ async getWorkflowReports(workflowId) {
1655
+ this._validateRequired({ workflowId: workflowId }, ['workflowId']);
1656
+ return await this.http.get('/api/tasks/workflows/' + workflowId + '/reports');
1657
+ }
1658
+
1659
+ // ==================== PIPELINE METHODS ====================
1660
+
1661
+ /**
1662
+ * Bir iş akışının pipeline'larını listeler
1663
+ * @param {string} workflowId - İş akışı ID'si
1664
+ * @returns {Promise<PipelineResponse[]>}
1665
+ */
1666
+ async listPipelines(workflowId) {
1667
+ this._validateRequired({ workflowId: workflowId }, ['workflowId']);
1668
+ return await this.http.get('/api/tasks/workflows/' + workflowId + '/pipelines');
1669
+ }
1670
+
1671
+ /**
1672
+ * Pipeline/aşama oluşturur
1673
+ * @param {string} workflowId - İş akışı ID'si
1674
+ * @param {Object} data - Pipeline verileri
1675
+ * @param {string} data.name - Pipeline adı
1676
+ * @param {string} [data.color] - Renk kodu
1677
+ * @param {number} [data.position] - Sıra
1678
+ * @returns {Promise<PipelineResponse>}
1679
+ */
1680
+ async createPipeline(workflowId, data) {
1681
+ this._validateRequired({ workflowId: workflowId }, ['workflowId']);
1682
+ this._validateRequired(data, ['name']);
1683
+ return await this.http.post('/api/tasks/workflows/' + workflowId + '/pipelines', data);
1684
+ }
1685
+
1686
+ /**
1687
+ * Pipeline günceller
1688
+ * @param {string} pipelineId - Pipeline ID'si
1689
+ * @param {Object} data - Güncellenecek veriler
1690
+ * @returns {Promise<PipelineResponse>}
1691
+ */
1692
+ async updatePipeline(pipelineId, data) {
1693
+ this._validateRequired({ pipelineId: pipelineId }, ['pipelineId']);
1694
+ return await this.http.patch('/api/tasks/pipelines/' + pipelineId, data);
1695
+ }
1696
+
1697
+ /**
1698
+ * Pipeline siler
1699
+ * @param {string} pipelineId - Pipeline ID'si
1700
+ * @returns {Promise<{success: boolean}>}
1701
+ */
1702
+ async deletePipeline(pipelineId) {
1703
+ this._validateRequired({ pipelineId: pipelineId }, ['pipelineId']);
1704
+ return await this.http.delete('/api/tasks/pipelines/' + pipelineId);
1705
+ }
1706
+
1707
+ /**
1708
+ * Pipeline pozisyonunu günceller
1709
+ * @param {string} workflowId - İş akışı ID'si
1710
+ * @param {string} pipelineId - Pipeline ID'si
1711
+ * @param {number} position - Yeni pozisyon
1712
+ * @returns {Promise<PipelineResponse>}
1713
+ */
1714
+ async updatePipelinePosition(workflowId, pipelineId, position) {
1715
+ this._validateRequired({ workflowId: workflowId, pipelineId: pipelineId }, ['workflowId', 'pipelineId']);
1716
+ return await this.http.patch('/api/tasks/' + workflowId + '/' + pipelineId + '/position', {
1717
+ position: position
1718
+ });
1719
+ }
1720
+ }
1721
+
1722
+ /**
1723
+ * @typedef {Object} TaskResponse
1724
+ * @property {string} _id - Görev ID
1725
+ * @property {string} siteId - Site ID
1726
+ * @property {string} title - Başlık
1727
+ * @property {string} [description] - Açıklama
1728
+ * @property {string} workflowId - İş akışı ID
1729
+ * @property {string} pipelineId - Pipeline/aşama ID
1730
+ * @property {string} [assignee] - Atanan kişi ID
1731
+ * @property {string} [contactId] - İlişkili contact ID
1732
+ * @property {string} status - Durum: 'open', 'done', 'archived'
1733
+ * @property {string} [priority] - Öncelik: 'low', 'medium', 'high', 'urgent'
1734
+ * @property {Date} [dueDate] - Bitiş tarihi
1735
+ * @property {Date} createdAt - Oluşturulma tarihi
1736
+ * @property {Date} [completedAt] - Tamamlanma tarihi
1737
+ * @property {Object} [customFields] - Özel alanlar
1738
+ * @property {number} [position] - Sıra
1739
+ */
1740
+
1741
+ /**
1742
+ * @typedef {Object} WorkflowResponse
1743
+ * @property {string} _id - İş akışı ID
1744
+ * @property {string} siteId - Site ID
1745
+ * @property {string} name - İş akışı adı
1746
+ * @property {string} [description] - Açıklama
1747
+ * @property {string} [color] - Renk kodu
1748
+ * @property {Date} createdAt - Oluşturulma tarihi
1749
+ */
1750
+
1751
+ /**
1752
+ * @typedef {Object} PipelineResponse
1753
+ * @property {string} _id - Pipeline ID
1754
+ * @property {string} name - Pipeline adı
1755
+ * @property {string} [color] - Renk kodu
1756
+ * @property {number} position - Sıra
1757
+ * @property {string} workflowId - İş akışı ID
1758
+ */
1759
+
1760
+ /**
1761
+ * @typedef {Object} WorkflowFullResponse
1762
+ * @property {WorkflowResponse} workflow - İş akışı bilgisi
1763
+ * @property {PipelineResponse[]} pipelines - Pipeline listesi
1764
+ * @property {Object} tasksByPipeline - Pipeline ID -> Task[] mapping
1765
+ */
1766
+
1767
+ /**
1768
+ * AICall modülü
1769
+ * Yapay zeka destekli sesli arama (Voice Agent) işlemleri
1770
+ *
1771
+ * @class AICall
1772
+ * @extends BaseModule
1773
+ * @example
1774
+ * // Arama başlat
1775
+ * const call = await supsis.aicall.makeCall({
1776
+ * agentId: 'agentId',
1777
+ * toNumber: '+905551234567',
1778
+ * fromNumber: '+908501234567'
1779
+ * });
1780
+ *
1781
+ * // Arama detayını getir
1782
+ * const callDetails = await supsis.aicall.getCall('callId');
1783
+ */
1784
+ class AICall extends BaseModule {
1785
+ /**
1786
+ * Telefon araması başlatır
1787
+ * @param {Object} options - Arama seçenekleri
1788
+ * @param {string} options.agentId - AI Agent ID'si
1789
+ * @param {string} options.toNumber - Aranacak telefon numarası
1790
+ * @param {string} options.fromNumber - Arayan telefon numarası
1791
+ * @param {Object} [options.variables] - Dinamik değişkenler (LLM için)
1792
+ * @param {Object} [options.metadata] - Ek metadata
1793
+ * @returns {Promise<CallResponse>} Arama bilgisi
1794
+ * @example
1795
+ * const call = await supsis.aicall.makeCall({
1796
+ * agentId: 'agentId',
1797
+ * toNumber: '+905551234567',
1798
+ * fromNumber: '+908501234567',
1799
+ * variables: {
1800
+ * customerName: 'John Doe',
1801
+ * orderNumber: '12345'
1802
+ * }
1803
+ * });
1804
+ */
1805
+ async makeCall(options) {
1806
+ this._validateRequired(options, ['agentId', 'toNumber', 'fromNumber']);
1807
+
1808
+ return await this.http.post('/api/voice-agent/calls/phone', {
1809
+ overrideAgentId: options.agentId,
1810
+ toNumber: options.toNumber,
1811
+ fromNumber: options.fromNumber,
1812
+ retellLlmDynamicVariables: options.variables || {},
1813
+ metadata: options.metadata
1814
+ });
1815
+ }
1816
+
1817
+ /**
1818
+ * Web araması başlatır (tarayıcıdan)
1819
+ * @param {Object} options - Arama seçenekleri
1820
+ * @param {string} options.agentId - AI Agent ID'si
1821
+ * @param {Object} [options.variables] - Dinamik değişkenler
1822
+ * @returns {Promise<WebCallResponse>} Web arama bilgisi
1823
+ */
1824
+ async makeWebCall(options) {
1825
+ this._validateRequired(options, ['agentId']);
1826
+
1827
+ return await this.http.post('/api/voice-agent/calls/web', {
1828
+ agentId: options.agentId,
1829
+ retellLlmDynamicVariables: options.variables || {}
1830
+ });
1831
+ }
1832
+
1833
+ /**
1834
+ * Toplu arama başlatır (batch call)
1835
+ * @param {Object} options - Toplu arama seçenekleri
1836
+ * @param {string} options.agentId - AI Agent ID'si
1837
+ * @param {string} options.fromNumber - Arayan telefon numarası
1838
+ * @param {Array<{toNumber: string, variables?: Object}>} options.calls - Aranacak numaralar
1839
+ * @returns {Promise<BatchCallResponse>}
1840
+ */
1841
+ async makeBatchCall(options) {
1842
+ this._validateRequired(options, ['agentId', 'fromNumber', 'calls']);
1843
+ return await this.http.post('/api/voice-agent/calls/batch', options);
1844
+ }
1845
+
1846
+ /**
1847
+ * Bir arama kaydını getirir
1848
+ * @param {string} callId - Arama ID'si
1849
+ * @returns {Promise<CallResponse>} Arama detayları
1850
+ * @example
1851
+ * const call = await supsis.aicall.getCall('callId');
1852
+ * console.log(call.status); // 'completed', 'failed', 'in_progress'
1853
+ * console.log(call.duration); // Süre (saniye)
1854
+ * console.log(call.transcript); // Konuşma metni
1855
+ */
1856
+ async getCall(callId) {
1857
+ this._validateRequired({ callId: callId }, ['callId']);
1858
+ return await this.http.get('/api/voice-agent/calls/' + callId);
1859
+ }
1860
+
1861
+ /**
1862
+ * Arama listesini getirir
1863
+ * @param {Object} [options] - Filtreleme seçenekleri
1864
+ * @param {string} [options.agentId] - Agent ID filtresi
1865
+ * @param {string} [options.status] - Durum filtresi
1866
+ * @param {Date|string} [options.startDate] - Başlangıç tarihi
1867
+ * @param {Date|string} [options.endDate] - Bitiş tarihi
1868
+ * @param {number} [options.page=1] - Sayfa numarası
1869
+ * @param {number} [options.limit=20] - Sayfa başına kayıt sayısı
1870
+ * @returns {Promise<{data: CallResponse[], total: number}>}
1871
+ */
1872
+ async listCalls(options) {
1873
+ options = options || {};
1874
+ const pagination = this._normalizePagination(options);
1875
+
1876
+ return await this.http.post('/api/voice-agent/calls/list', {
1877
+ agentId: options.agentId,
1878
+ status: options.status,
1879
+ startDate: this._toISODate(options.startDate),
1880
+ endDate: this._toISODate(options.endDate),
1881
+ page: pagination.page,
1882
+ limit: pagination.limit
1883
+ });
1884
+ }
1885
+
1886
+ /**
1887
+ * Toplu arama listesini getirir
1888
+ * @returns {Promise<BatchCallResponse[]>}
1889
+ */
1890
+ async listBatchCalls() {
1891
+ return await this.http.get('/api/voice-agent/calls/batch');
1892
+ }
1893
+
1894
+ // ==================== AGENT METHODS ====================
1895
+
1896
+ /**
1897
+ * AI Agent listesini getirir
1898
+ * @returns {Promise<AgentResponse[]>}
1899
+ */
1900
+ async listAgents() {
1901
+ return await this.http.get('/api/voice-agent/agents');
1902
+ }
1903
+
1904
+ /**
1905
+ * Bir AI Agent'ı getirir
1906
+ * @param {string} agentId - Agent ID'si
1907
+ * @returns {Promise<AgentResponse>}
1908
+ */
1909
+ async getAgent(agentId) {
1910
+ this._validateRequired({ agentId: agentId }, ['agentId']);
1911
+ return await this.http.get('/api/voice-agent/agents/' + agentId);
1912
+ }
1913
+
1914
+ /**
1915
+ * AI Agent oluşturur
1916
+ * @param {Object} data - Agent verileri
1917
+ * @param {string} data.name - Agent adı
1918
+ * @param {string} data.voiceId - Ses ID'si
1919
+ * @param {string} data.llmId - LLM ID'si
1920
+ * @param {Object} [data.settings] - Agent ayarları
1921
+ * @returns {Promise<AgentResponse>}
1922
+ */
1923
+ async createAgent(data) {
1924
+ this._validateRequired(data, ['name']);
1925
+ return await this.http.post('/api/voice-agent/agents', data);
1926
+ }
1927
+
1928
+ /**
1929
+ * AI Agent günceller
1930
+ * @param {string} agentId - Agent ID'si
1931
+ * @param {Object} data - Güncellenecek veriler
1932
+ * @returns {Promise<AgentResponse>}
1933
+ */
1934
+ async updateAgent(agentId, data) {
1935
+ this._validateRequired({ agentId: agentId }, ['agentId']);
1936
+ return await this.http.patch('/api/voice-agent/agents/' + agentId, data);
1937
+ }
1938
+
1939
+ /**
1940
+ * AI Agent siler
1941
+ * @param {string} agentId - Agent ID'si
1942
+ * @returns {Promise<{success: boolean}>}
1943
+ */
1944
+ async deleteAgent(agentId) {
1945
+ this._validateRequired({ agentId: agentId }, ['agentId']);
1946
+ return await this.http.delete('/api/voice-agent/agents/' + agentId);
1947
+ }
1948
+
1949
+ // ==================== PHONE NUMBER METHODS ====================
1950
+
1951
+ /**
1952
+ * Telefon numarası listesini getirir
1953
+ * @returns {Promise<PhoneNumberResponse[]>}
1954
+ */
1955
+ async listNumbers() {
1956
+ return await this.http.get('/api/voice-agent/numbers');
1957
+ }
1958
+
1959
+ /**
1960
+ * Telefon numarası bilgisini getirir
1961
+ * @param {string} phoneNumber - Telefon numarası
1962
+ * @returns {Promise<PhoneNumberResponse>}
1963
+ */
1964
+ async getNumber(phoneNumber) {
1965
+ this._validateRequired({ phoneNumber: phoneNumber }, ['phoneNumber']);
1966
+ return await this.http.get('/api/voice-agent/numbers/' + encodeURIComponent(phoneNumber));
1967
+ }
1968
+
1969
+ // ==================== VOICE METHODS ====================
1970
+
1971
+ /**
1972
+ * Kullanılabilir ses listesini getirir
1973
+ * @returns {Promise<VoiceResponse[]>}
1974
+ */
1975
+ async listVoices() {
1976
+ return await this.http.get('/api/voice-agent/voices');
1977
+ }
1978
+
1979
+ /**
1980
+ * Bir ses bilgisini getirir
1981
+ * @param {string} voiceId - Ses ID'si
1982
+ * @returns {Promise<VoiceResponse>}
1983
+ */
1984
+ async getVoice(voiceId) {
1985
+ this._validateRequired({ voiceId: voiceId }, ['voiceId']);
1986
+ return await this.http.get('/api/voice-agent/voices/' + voiceId);
1987
+ }
1988
+
1989
+ // ==================== KNOWLEDGE BASE METHODS ====================
1990
+
1991
+ /**
1992
+ * Bilgi tabanı listesini getirir
1993
+ * @returns {Promise<KnowledgeBaseResponse[]>}
1994
+ */
1995
+ async listKnowledgeBases() {
1996
+ return await this.http.get('/api/voice-agent/knowledgebases');
1997
+ }
1998
+
1999
+ /**
2000
+ * Bir bilgi tabanını getirir
2001
+ * @param {string} knowledgeBaseId - Bilgi tabanı ID'si
2002
+ * @returns {Promise<KnowledgeBaseResponse>}
2003
+ */
2004
+ async getKnowledgeBase(knowledgeBaseId) {
2005
+ this._validateRequired({ knowledgeBaseId: knowledgeBaseId }, ['knowledgeBaseId']);
2006
+ return await this.http.get('/api/voice-agent/knowledgebases/' + knowledgeBaseId);
2007
+ }
2008
+
2009
+ /**
2010
+ * Bilgi tabanı siler
2011
+ * @param {string} knowledgeBaseId - Bilgi tabanı ID'si
2012
+ * @returns {Promise<{success: boolean}>}
2013
+ */
2014
+ async deleteKnowledgeBase(knowledgeBaseId) {
2015
+ this._validateRequired({ knowledgeBaseId: knowledgeBaseId }, ['knowledgeBaseId']);
2016
+ return await this.http.delete('/api/voice-agent/knowledgebases/' + knowledgeBaseId);
2017
+ }
2018
+
2019
+ // ==================== LLM METHODS ====================
2020
+
2021
+ /**
2022
+ * LLM listesini getirir
2023
+ * @returns {Promise<LLMResponse[]>}
2024
+ */
2025
+ async listLLMs() {
2026
+ return await this.http.get('/api/voice-agent/llms');
2027
+ }
2028
+
2029
+ /**
2030
+ * Bir LLM'i getirir
2031
+ * @param {string} llmId - LLM ID'si
2032
+ * @returns {Promise<LLMResponse>}
2033
+ */
2034
+ async getLLM(llmId) {
2035
+ this._validateRequired({ llmId: llmId }, ['llmId']);
2036
+ return await this.http.get('/api/voice-agent/llms/' + llmId);
2037
+ }
2038
+
2039
+ /**
2040
+ * LLM oluşturur
2041
+ * @param {Object} data - LLM verileri
2042
+ * @returns {Promise<LLMResponse>}
2043
+ */
2044
+ async createLLM(data) {
2045
+ return await this.http.post('/api/voice-agent/llms', data);
2046
+ }
2047
+
2048
+ /**
2049
+ * LLM günceller
2050
+ * @param {string} llmId - LLM ID'si
2051
+ * @param {Object} data - Güncellenecek veriler
2052
+ * @returns {Promise<LLMResponse>}
2053
+ */
2054
+ async updateLLM(llmId, data) {
2055
+ this._validateRequired({ llmId: llmId }, ['llmId']);
2056
+ return await this.http.patch('/api/voice-agent/llms/' + llmId, data);
2057
+ }
2058
+
2059
+ /**
2060
+ * LLM siler
2061
+ * @param {string} llmId - LLM ID'si
2062
+ * @returns {Promise<{success: boolean}>}
2063
+ */
2064
+ async deleteLLM(llmId) {
2065
+ this._validateRequired({ llmId: llmId }, ['llmId']);
2066
+ return await this.http.delete('/api/voice-agent/llms/' + llmId);
2067
+ }
2068
+ }
2069
+
2070
+ /**
2071
+ * @typedef {Object} CallResponse
2072
+ * @property {string} call_id - Arama ID
2073
+ * @property {string} agent_id - Agent ID
2074
+ * @property {string} call_status - Durum: 'registered', 'ongoing', 'ended', 'error'
2075
+ * @property {string} [from_number] - Arayan numara
2076
+ * @property {string} [to_number] - Aranan numara
2077
+ * @property {number} [start_timestamp] - Başlangıç zamanı (ms)
2078
+ * @property {number} [end_timestamp] - Bitiş zamanı (ms)
2079
+ * @property {number} [duration_ms] - Süre (ms)
2080
+ * @property {string} [transcript] - Konuşma metni
2081
+ * @property {Object} [call_analysis] - Arama analizi
2082
+ * @property {string} [recording_url] - Kayıt URL'si
2083
+ * @property {Object} [metadata] - Ek metadata
2084
+ */
2085
+
2086
+ /**
2087
+ * @typedef {Object} AgentResponse
2088
+ * @property {string} agent_id - Agent ID
2089
+ * @property {string} agent_name - Agent adı
2090
+ * @property {string} voice_id - Ses ID
2091
+ * @property {string} llm_websocket_url - LLM WebSocket URL
2092
+ * @property {Object} [settings] - Agent ayarları
2093
+ */
2094
+
2095
+ /**
2096
+ * @typedef {Object} VoiceResponse
2097
+ * @property {string} voice_id - Ses ID
2098
+ * @property {string} voice_name - Ses adı
2099
+ * @property {string} [sample_audio_url] - Örnek ses URL'si
2100
+ * @property {string} [gender] - Cinsiyet
2101
+ * @property {string} [language] - Dil
2102
+ */
2103
+
2104
+ /**
2105
+ * @typedef {Object} KnowledgeBaseResponse
2106
+ * @property {string} knowledge_base_id - Bilgi tabanı ID
2107
+ * @property {string} name - Ad
2108
+ * @property {Object[]} [sources] - Kaynaklar
2109
+ */
2110
+
2111
+ /**
2112
+ * @typedef {Object} LLMResponse
2113
+ * @property {string} llm_id - LLM ID
2114
+ * @property {string} [model] - Model adı
2115
+ * @property {Object} [settings] - LLM ayarları
2116
+ */
2117
+
2118
+ /**
2119
+ * @typedef {Object} PhoneNumberResponse
2120
+ * @property {string} phone_number - Telefon numarası
2121
+ * @property {string} [agent_id] - Bağlı agent ID
2122
+ * @property {string} [status] - Durum
2123
+ */
2124
+
2125
+ /**
2126
+ * @typedef {Object} BatchCallResponse
2127
+ * @property {string} batch_id - Batch ID
2128
+ * @property {string} status - Durum
2129
+ * @property {number} total_calls - Toplam arama sayısı
2130
+ * @property {number} completed_calls - Tamamlanan arama sayısı
2131
+ */
2132
+
2133
+ /**
2134
+ * Asset modülü
2135
+ * Dosya ve medya yönetimi
2136
+ *
2137
+ * @class Asset
2138
+ * @extends BaseModule
2139
+ * @example
2140
+ * // Asset bilgisi getir
2141
+ * const asset = await supsis.asset.get('assetId');
2142
+ * console.log(asset.path); // S3 path
2143
+ * console.log(asset.mime); // MIME type
2144
+ */
2145
+ class Asset extends BaseModule {
2146
+ /**
2147
+ * Bir asset bilgisini getirir
2148
+ * @param {string} assetId - Asset ID'si
2149
+ * @returns {Promise<AssetResponse>} Asset detayları
2150
+ * @example
2151
+ * const asset = await supsis.asset.get('assetId');
2152
+ * console.log(asset.path); // 'siteId/whatsapp/uuid.jpg'
2153
+ * console.log(asset.mime); // 'image/jpeg'
2154
+ * console.log(asset.size); // Dosya boyutu (bytes)
2155
+ */
2156
+ async get(assetId) {
2157
+ this._validateRequired({ assetId: assetId }, ['assetId']);
2158
+ return await this.http.get('/api/assets/id/' + assetId);
2159
+ }
2160
+
2161
+ /**
2162
+ * Asset URL'sini oluşturur
2163
+ * @param {string} path - Asset path'i
2164
+ * @returns {string} Tam URL
2165
+ */
2166
+ getUrl(path) {
2167
+ if (!path) return null;
2168
+ // S3 bucket URL'si
2169
+ return 'https://supsis-storage.s3.amazonaws.com/' + path;
2170
+ }
2171
+ }
2172
+
2173
+ /**
2174
+ * @typedef {Object} AssetResponse
2175
+ * @property {string} _id - Asset ID
2176
+ * @property {string} siteId - Site ID
2177
+ * @property {string} path - S3 path
2178
+ * @property {string} mime - MIME type
2179
+ * @property {string} ext - Dosya uzantısı
2180
+ * @property {number} size - Dosya boyutu (bytes)
2181
+ * @property {string} [platform] - Platform: 'whatsapp', 'web', 'instagram', etc.
2182
+ * @property {string} [externalUrl] - Harici URL
2183
+ * @property {Date} createdAt - Oluşturulma tarihi
2184
+ * @property {Date} updatedAt - Güncellenme tarihi
2185
+ */
2186
+
2187
+ /**
2188
+ * Table modülü
2189
+ * Müşteri tabloları (CustomerTable) yönetimi - Airtable benzeri tablo sistemi
2190
+ *
2191
+ * @class Table
2192
+ * @extends BaseModule
2193
+ * @example
2194
+ * // Tablo listele
2195
+ * const tables = await supsis.table.list();
2196
+ *
2197
+ * // Tablo kayıtlarını getir
2198
+ * const records = await supsis.table.listRecords('tableId');
2199
+ */
2200
+ class Table extends BaseModule {
2201
+ /**
2202
+ * Tüm tabloları listeler
2203
+ * @returns {Promise<TableResponse[]>}
2204
+ */
2205
+ async list() {
2206
+ return await this.http.get('/api/tables');
2207
+ }
2208
+
2209
+ /**
2210
+ * Bir tabloyu getirir
2211
+ * @param {string} tableId - Tablo ID'si
2212
+ * @returns {Promise<TableResponse>}
2213
+ */
2214
+ async get(tableId) {
2215
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2216
+ return await this.http.get('/api/tables/' + tableId);
2217
+ }
2218
+
2219
+ /**
2220
+ * Tablo oluşturur
2221
+ * @param {Object} data - Tablo verileri
2222
+ * @param {string} data.name - Tablo adı
2223
+ * @param {string} [data.description] - Açıklama
2224
+ * @param {string} [data.icon] - İkon
2225
+ * @returns {Promise<TableResponse>}
2226
+ */
2227
+ async create(data) {
2228
+ this._validateRequired(data, ['name']);
2229
+ return await this.http.put('/api/tables', data);
2230
+ }
2231
+
2232
+ /**
2233
+ * Tabloyu günceller
2234
+ * @param {string} tableId - Tablo ID'si
2235
+ * @param {Object} data - Güncellenecek veriler
2236
+ * @returns {Promise<TableResponse>}
2237
+ */
2238
+ async update(tableId, data) {
2239
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2240
+ return await this.http.post('/api/tables/' + tableId, data);
2241
+ }
2242
+
2243
+ /**
2244
+ * Tabloyu siler
2245
+ * @param {string} tableId - Tablo ID'si
2246
+ * @returns {Promise<{success: boolean}>}
2247
+ */
2248
+ async delete(tableId) {
2249
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2250
+ return await this.http.delete('/api/tables/' + tableId);
2251
+ }
2252
+
2253
+ /**
2254
+ * Tabloyu kopyalar
2255
+ * @param {string} tableId - Tablo ID'si
2256
+ * @returns {Promise<TableResponse>}
2257
+ */
2258
+ async duplicate(tableId) {
2259
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2260
+ return await this.http.post('/api/tables/' + tableId + '/duplicate');
2261
+ }
2262
+
2263
+ /**
2264
+ * Tabloyu JSON olarak export eder
2265
+ * @param {string} tableId - Tablo ID'si
2266
+ * @returns {Promise<Object>} Export edilmiş tablo
2267
+ */
2268
+ async export(tableId) {
2269
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2270
+ return await this.http.get('/api/tables/' + tableId + '/export');
2271
+ }
2272
+
2273
+ /**
2274
+ * JSON'dan tablo import eder
2275
+ * @param {Object} data - Import edilecek tablo verisi
2276
+ * @returns {Promise<TableResponse>}
2277
+ */
2278
+ async import(data) {
2279
+ return await this.http.post('/api/tables/import', data);
2280
+ }
2281
+
2282
+ // ==================== FIELD METHODS ====================
2283
+
2284
+ /**
2285
+ * Tablo alanlarını listeler
2286
+ * @param {string} tableId - Tablo ID'si
2287
+ * @returns {Promise<FieldResponse[]>}
2288
+ */
2289
+ async listFields(tableId) {
2290
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2291
+ return await this.http.get('/api/tables/' + tableId + '/fields');
2292
+ }
2293
+
2294
+ /**
2295
+ * Tablo alanı oluşturur
2296
+ * @param {string} tableId - Tablo ID'si
2297
+ * @param {Object} data - Alan verileri
2298
+ * @param {string} data.name - Alan adı
2299
+ * @param {string} data.type - Alan tipi: 'text', 'number', 'date', 'select', 'multiselect', 'checkbox', 'url', 'email', 'phone', 'user', 'contact', 'relation', 'formula', 'rollup', 'lookup', 'attachment', 'rating', 'currency', 'percent', 'duration', 'barcode'
2300
+ * @param {Object} [data.options] - Alan seçenekleri
2301
+ * @returns {Promise<FieldResponse>}
2302
+ */
2303
+ async createField(tableId, data) {
2304
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2305
+ this._validateRequired(data, ['name', 'type']);
2306
+ return await this.http.put('/api/tables/' + tableId + '/fields', data);
2307
+ }
2308
+
2309
+ /**
2310
+ * Tablo alanını günceller
2311
+ * @param {string} tableId - Tablo ID'si
2312
+ * @param {string} fieldId - Alan ID'si
2313
+ * @param {Object} data - Güncellenecek veriler
2314
+ * @returns {Promise<FieldResponse>}
2315
+ */
2316
+ async updateField(tableId, fieldId, data) {
2317
+ this._validateRequired({ tableId: tableId, fieldId: fieldId }, ['tableId', 'fieldId']);
2318
+ return await this.http.post('/api/tables/' + tableId + '/fields/' + fieldId, data);
2319
+ }
2320
+
2321
+ /**
2322
+ * Tablo alanını siler
2323
+ * @param {string} tableId - Tablo ID'si
2324
+ * @param {string} fieldId - Alan ID'si
2325
+ * @returns {Promise<{success: boolean}>}
2326
+ */
2327
+ async deleteField(tableId, fieldId) {
2328
+ this._validateRequired({ tableId: tableId, fieldId: fieldId }, ['tableId', 'fieldId']);
2329
+ return await this.http.delete('/api/tables/' + tableId + '/fields/' + fieldId);
2330
+ }
2331
+
2332
+ // ==================== RECORD METHODS ====================
2333
+
2334
+ /**
2335
+ * Tablo kayıtlarını listeler
2336
+ * @param {string} tableId - Tablo ID'si
2337
+ * @param {Object} [options] - Filtreleme seçenekleri
2338
+ * @param {Object} [options.filters] - Filtreler
2339
+ * @param {Object} [options.sort] - Sıralama
2340
+ * @param {number} [options.page=1] - Sayfa numarası
2341
+ * @param {number} [options.limit=20] - Sayfa başına kayıt
2342
+ * @param {string} [options.viewId] - View ID'si
2343
+ * @returns {Promise<{data: RecordResponse[], total: number}>}
2344
+ */
2345
+ async listRecords(tableId, options) {
2346
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2347
+ options = options || {};
2348
+ const pagination = this._normalizePagination(options);
2349
+
2350
+ return await this.http.post('/api/tables/' + tableId + '/records', {
2351
+ filters: options.filters,
2352
+ sort: options.sort,
2353
+ page: pagination.page,
2354
+ limit: pagination.limit,
2355
+ viewId: options.viewId
2356
+ });
2357
+ }
2358
+
2359
+ /**
2360
+ * Bir kaydı getirir
2361
+ * @param {string} tableId - Tablo ID'si
2362
+ * @param {string} recordId - Kayıt ID'si
2363
+ * @returns {Promise<RecordResponse>}
2364
+ */
2365
+ async getRecord(tableId, recordId) {
2366
+ this._validateRequired({ tableId: tableId, recordId: recordId }, ['tableId', 'recordId']);
2367
+ return await this.http.get('/api/tables/' + tableId + '/records/' + recordId);
2368
+ }
2369
+
2370
+ /**
2371
+ * Kayıt oluşturur
2372
+ * @param {string} tableId - Tablo ID'si
2373
+ * @param {Object} data - Kayıt verileri (field slug -> value)
2374
+ * @returns {Promise<RecordResponse>}
2375
+ * @example
2376
+ * const record = await supsis.table.createRecord('tableId', {
2377
+ * name: 'John Doe',
2378
+ * email: 'john@example.com',
2379
+ * status: 'active'
2380
+ * });
2381
+ */
2382
+ async createRecord(tableId, data) {
2383
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2384
+ return await this.http.put('/api/tables/' + tableId + '/records', data);
2385
+ }
2386
+
2387
+ /**
2388
+ * Boş kayıt oluşturur
2389
+ * @param {string} tableId - Tablo ID'si
2390
+ * @returns {Promise<RecordResponse>}
2391
+ */
2392
+ async createEmptyRecord(tableId) {
2393
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2394
+ return await this.http.put('/api/tables/' + tableId + '/records/empty');
2395
+ }
2396
+
2397
+ /**
2398
+ * Birden fazla kayıt oluşturur
2399
+ * @param {string} tableId - Tablo ID'si
2400
+ * @param {Object[]} records - Kayıt verileri dizisi
2401
+ * @returns {Promise<RecordResponse[]>}
2402
+ */
2403
+ async createManyRecords(tableId, records) {
2404
+ this._validateRequired({ tableId: tableId, records: records }, ['tableId', 'records']);
2405
+ return await this.http.put('/api/tables/' + tableId + '/records/multi', {
2406
+ records: records
2407
+ });
2408
+ }
2409
+
2410
+ /**
2411
+ * Kaydı günceller
2412
+ * @param {string} tableId - Tablo ID'si
2413
+ * @param {string} recordId - Kayıt ID'si
2414
+ * @param {Object} data - Güncellenecek veriler
2415
+ * @returns {Promise<RecordResponse>}
2416
+ */
2417
+ async updateRecord(tableId, recordId, data) {
2418
+ this._validateRequired({ tableId: tableId, recordId: recordId }, ['tableId', 'recordId']);
2419
+ return await this.http.post('/api/tables/' + tableId + '/records/' + recordId + '/update', data);
2420
+ }
2421
+
2422
+ /**
2423
+ * Birden fazla kaydın aynı alanını günceller
2424
+ * @param {string} tableId - Tablo ID'si
2425
+ * @param {string} fieldId - Alan ID'si
2426
+ * @param {string[]} recordIds - Kayıt ID'leri
2427
+ * @param {*} value - Yeni değer
2428
+ * @returns {Promise<{success: boolean}>}
2429
+ */
2430
+ async updateManyRecords(tableId, fieldId, recordIds, value) {
2431
+ this._validateRequired({ tableId: tableId, fieldId: fieldId, recordIds: recordIds }, ['tableId', 'fieldId', 'recordIds']);
2432
+ return await this.http.put('/api/tables/' + tableId + '/fields/' + fieldId + '/records', {
2433
+ recordIds: recordIds,
2434
+ value: value
2435
+ });
2436
+ }
2437
+
2438
+ /**
2439
+ * Kaydı siler
2440
+ * @param {string} tableId - Tablo ID'si
2441
+ * @param {string} recordId - Kayıt ID'si
2442
+ * @returns {Promise<{success: boolean}>}
2443
+ */
2444
+ async deleteRecord(tableId, recordId) {
2445
+ this._validateRequired({ tableId: tableId, recordId: recordId }, ['tableId', 'recordId']);
2446
+ return await this.http.delete('/api/tables/' + tableId + '/records/' + recordId);
2447
+ }
2448
+
2449
+ /**
2450
+ * Birden fazla kaydı siler
2451
+ * @param {string} tableId - Tablo ID'si
2452
+ * @param {string[]} recordIds - Kayıt ID'leri
2453
+ * @returns {Promise<{success: boolean, deletedCount: number}>}
2454
+ */
2455
+ async deleteManyRecords(tableId, recordIds) {
2456
+ this._validateRequired({ tableId: tableId, recordIds: recordIds }, ['tableId', 'recordIds']);
2457
+ return await this.http.post('/api/tables/' + tableId + '/records/delete', {
2458
+ recordIds: recordIds
2459
+ });
2460
+ }
2461
+
2462
+ /**
2463
+ * Kayıtları kopyalar
2464
+ * @param {string} tableId - Tablo ID'si
2465
+ * @param {string[]} recordIds - Kopyalanacak kayıt ID'leri
2466
+ * @returns {Promise<RecordResponse[]>}
2467
+ */
2468
+ async duplicateRecords(tableId, recordIds) {
2469
+ this._validateRequired({ tableId: tableId, recordIds: recordIds }, ['tableId', 'recordIds']);
2470
+ return await this.http.post('/api/tables/' + tableId + '/records/duplicate', {
2471
+ recordIds: recordIds
2472
+ });
2473
+ }
2474
+
2475
+ /**
2476
+ * Alan değerlerinde arama yapar
2477
+ * @param {string} tableId - Tablo ID'si
2478
+ * @param {string} fieldId - Alan ID'si
2479
+ * @param {string} query - Arama terimi
2480
+ * @returns {Promise<*[]>} Eşleşen değerler
2481
+ */
2482
+ async searchFieldValues(tableId, fieldId, query) {
2483
+ this._validateRequired({ tableId: tableId, fieldId: fieldId }, ['tableId', 'fieldId']);
2484
+ return await this.http.get('/api/tables/' + tableId + '/' + fieldId + '/search', {
2485
+ query: { q: query }
2486
+ });
2487
+ }
2488
+
2489
+ // ==================== VIEW METHODS ====================
2490
+
2491
+ /**
2492
+ * Tablo görünümlerini listeler
2493
+ * @param {string} tableId - Tablo ID'si
2494
+ * @returns {Promise<ViewResponse[]>}
2495
+ */
2496
+ async listViews(tableId) {
2497
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2498
+ return await this.http.get('/api/tables/' + tableId + '/views');
2499
+ }
2500
+
2501
+ /**
2502
+ * Görünüm oluşturur
2503
+ * @param {string} tableId - Tablo ID'si
2504
+ * @param {Object} data - Görünüm verileri
2505
+ * @param {string} data.name - Görünüm adı
2506
+ * @param {string} [data.type] - Tip: 'grid', 'kanban', 'calendar', 'gallery'
2507
+ * @param {Object} [data.filters] - Filtreler
2508
+ * @param {Object} [data.sort] - Sıralama
2509
+ * @returns {Promise<ViewResponse>}
2510
+ */
2511
+ async createView(tableId, data) {
2512
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2513
+ this._validateRequired(data, ['name']);
2514
+ return await this.http.put('/api/tables/' + tableId + '/views', data);
2515
+ }
2516
+
2517
+ /**
2518
+ * Görünümü günceller
2519
+ * @param {string} tableId - Tablo ID'si
2520
+ * @param {string} viewId - Görünüm ID'si
2521
+ * @param {Object} data - Güncellenecek veriler
2522
+ * @returns {Promise<ViewResponse>}
2523
+ */
2524
+ async updateView(tableId, viewId, data) {
2525
+ this._validateRequired({ tableId: tableId, viewId: viewId }, ['tableId', 'viewId']);
2526
+ return await this.http.post('/api/tables/' + tableId + '/views/' + viewId, data);
2527
+ }
2528
+
2529
+ /**
2530
+ * Görünümü siler
2531
+ * @param {string} tableId - Tablo ID'si
2532
+ * @param {string} viewId - Görünüm ID'si
2533
+ * @returns {Promise<{success: boolean}>}
2534
+ */
2535
+ async deleteView(tableId, viewId) {
2536
+ this._validateRequired({ tableId: tableId, viewId: viewId }, ['tableId', 'viewId']);
2537
+ return await this.http.delete('/api/tables/' + tableId + '/views/' + viewId);
2538
+ }
2539
+
2540
+ // ==================== PAGE & WIDGET METHODS ====================
2541
+
2542
+ /**
2543
+ * Tablo sayfalarını listeler
2544
+ * @param {string} tableId - Tablo ID'si
2545
+ * @returns {Promise<PageResponse[]>}
2546
+ */
2547
+ async listPages(tableId) {
2548
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2549
+ return await this.http.get('/api/tables/' + tableId + '/pages');
2550
+ }
2551
+
2552
+ /**
2553
+ * Bir sayfayı getirir
2554
+ * @param {string} tableId - Tablo ID'si
2555
+ * @param {string} pageId - Sayfa ID'si
2556
+ * @returns {Promise<PageResponse>}
2557
+ */
2558
+ async getPage(tableId, pageId) {
2559
+ this._validateRequired({ tableId: tableId, pageId: pageId }, ['tableId', 'pageId']);
2560
+ return await this.http.get('/api/tables/' + tableId + '/pages/' + pageId);
2561
+ }
2562
+
2563
+ /**
2564
+ * Sayfa oluşturur
2565
+ * @param {string} tableId - Tablo ID'si
2566
+ * @param {Object} data - Sayfa verileri
2567
+ * @returns {Promise<PageResponse>}
2568
+ */
2569
+ async createPage(tableId, data) {
2570
+ this._validateRequired({ tableId: tableId }, ['tableId']);
2571
+ return await this.http.put('/api/tables/' + tableId + '/pages', data);
2572
+ }
2573
+
2574
+ /**
2575
+ * Widget listesini getirir
2576
+ * @param {string} tableId - Tablo ID'si
2577
+ * @param {string} pageId - Sayfa ID'si
2578
+ * @returns {Promise<WidgetResponse[]>}
2579
+ */
2580
+ async listWidgets(tableId, pageId) {
2581
+ this._validateRequired({ tableId: tableId, pageId: pageId }, ['tableId', 'pageId']);
2582
+ return await this.http.get('/api/tables/' + tableId + '/pages/' + pageId + '/widgets');
2583
+ }
2584
+
2585
+ /**
2586
+ * Widget chart verisini getirir
2587
+ * @param {string} tableId - Tablo ID'si
2588
+ * @param {string} widgetId - Widget ID'si
2589
+ * @param {Object} [options] - Seçenekler
2590
+ * @returns {Promise<Object>} Chart verisi
2591
+ */
2592
+ async getWidgetChartData(tableId, widgetId, options) {
2593
+ this._validateRequired({ tableId: tableId, widgetId: widgetId }, ['tableId', 'widgetId']);
2594
+ return await this.http.post('/api/tables/' + tableId + '/widgets/' + widgetId + '/chart-data', options || {});
2595
+ }
2596
+ }
2597
+
2598
+ /**
2599
+ * @typedef {Object} TableResponse
2600
+ * @property {string} _id - Tablo ID
2601
+ * @property {string} siteId - Site ID
2602
+ * @property {string} name - Tablo adı
2603
+ * @property {string} [description] - Açıklama
2604
+ * @property {string} [icon] - İkon
2605
+ * @property {Date} createdAt - Oluşturulma tarihi
2606
+ */
2607
+
2608
+ /**
2609
+ * @typedef {Object} FieldResponse
2610
+ * @property {string} _id - Alan ID
2611
+ * @property {string} name - Alan adı
2612
+ * @property {string} slug - URL-friendly isim
2613
+ * @property {string} type - Alan tipi
2614
+ * @property {Object} [options] - Alan seçenekleri
2615
+ * @property {number} [position] - Sıra
2616
+ * @property {boolean} [required] - Zorunlu mu
2617
+ */
2618
+
2619
+ /**
2620
+ * @typedef {Object} RecordResponse
2621
+ * @property {string} _id - Kayıt ID
2622
+ * @property {string} tableId - Tablo ID
2623
+ * @property {Object} data - Alan değerleri (slug -> value)
2624
+ * @property {Date} createdAt - Oluşturulma tarihi
2625
+ * @property {Date} updatedAt - Güncellenme tarihi
2626
+ * @property {string} [createdBy] - Oluşturan kullanıcı ID
2627
+ */
2628
+
2629
+ /**
2630
+ * @typedef {Object} ViewResponse
2631
+ * @property {string} _id - Görünüm ID
2632
+ * @property {string} name - Görünüm adı
2633
+ * @property {string} type - Tip: 'grid', 'kanban', 'calendar', 'gallery'
2634
+ * @property {Object} [filters] - Filtreler
2635
+ * @property {Object} [sort] - Sıralama
2636
+ */
2637
+
2638
+ /**
2639
+ * @typedef {Object} PageResponse
2640
+ * @property {string} _id - Sayfa ID
2641
+ * @property {string} name - Sayfa adı
2642
+ * @property {string} tableId - Tablo ID
2643
+ */
2644
+
2645
+ /**
2646
+ * @typedef {Object} WidgetResponse
2647
+ * @property {string} _id - Widget ID
2648
+ * @property {string} type - Widget tipi
2649
+ * @property {Object} config - Widget konfigürasyonu
2650
+ */
2651
+
2652
+ /**
2653
+ * Module modülü
2654
+ * Dinamik modüller (müşteri özelinde CRM modülleri) yönetimi
2655
+ *
2656
+ * @class Module
2657
+ * @extends BaseModule
2658
+ * @example
2659
+ * // Modül listele
2660
+ * const modules = await supsis.module.list();
2661
+ *
2662
+ * // Modül kayıtlarını getir
2663
+ * const records = await supsis.module.listRecords('Leads');
2664
+ *
2665
+ * // Kayıt oluştur
2666
+ * const lead = await supsis.module.createRecord('Leads', {
2667
+ * name: 'John Doe',
2668
+ * email: 'john@example.com'
2669
+ * });
2670
+ */
2671
+ class Module extends BaseModule {
2672
+ /**
2673
+ * Tüm modülleri listeler
2674
+ * @returns {Promise<ModuleDefinitionResponse[]>}
2675
+ */
2676
+ async list() {
2677
+ return await this.http.get('/api/module');
2678
+ }
2679
+
2680
+ /**
2681
+ * Modül oluşturur
2682
+ * @param {Object} data - Modül verileri
2683
+ * @param {string} data.name - Modül adı (API name)
2684
+ * @param {string} data.displayName - Görünen ad
2685
+ * @param {Object[]} [data.fields] - Alan tanımları
2686
+ * @returns {Promise<ModuleDefinitionResponse>}
2687
+ */
2688
+ async create(data) {
2689
+ this._validateRequired(data, ['name', 'displayName']);
2690
+ return await this.http.post('/api/module', data);
2691
+ }
2692
+
2693
+ /**
2694
+ * Modülü günceller
2695
+ * @param {string} moduleName - Modül adı
2696
+ * @param {Object} data - Güncellenecek veriler
2697
+ * @returns {Promise<ModuleDefinitionResponse>}
2698
+ */
2699
+ async update(moduleName, data) {
2700
+ this._validateRequired({ moduleName: moduleName }, ['moduleName']);
2701
+ return await this.http.post('/api/module/' + moduleName, data);
2702
+ }
2703
+
2704
+ /**
2705
+ * Modülü siler
2706
+ * @param {string} moduleId - Modül ID'si
2707
+ * @returns {Promise<{success: boolean}>}
2708
+ */
2709
+ async delete(moduleId) {
2710
+ this._validateRequired({ moduleId: moduleId }, ['moduleId']);
2711
+ return await this.http.delete('/api/module/' + moduleId);
2712
+ }
2713
+
2714
+ // ==================== RECORD METHODS ====================
2715
+
2716
+ /**
2717
+ * Modül kayıtlarını listeler
2718
+ * @param {string} moduleName - Modül adı
2719
+ * @param {Object} [options] - Filtreleme seçenekleri
2720
+ * @param {Object} [options.filters] - Filtreler
2721
+ * @param {Object} [options.sort] - Sıralama
2722
+ * @param {number} [options.page=1] - Sayfa numarası
2723
+ * @param {number} [options.limit=20] - Sayfa başına kayıt
2724
+ * @returns {Promise<{data: ModuleRecordResponse[], total: number}>}
2725
+ * @example
2726
+ * const leads = await supsis.module.listRecords('Leads', {
2727
+ * filters: { status: 'new' },
2728
+ * limit: 50
2729
+ * });
2730
+ */
2731
+ async listRecords(moduleName, options) {
2732
+ this._validateRequired({ moduleName: moduleName }, ['moduleName']);
2733
+ options = options || {};
2734
+ const pagination = this._normalizePagination(options);
2735
+
2736
+ return await this.http.post('/api/module/' + moduleName + '/records', {
2737
+ filters: options.filters,
2738
+ sort: options.sort,
2739
+ page: pagination.page,
2740
+ limit: pagination.limit
2741
+ });
2742
+ }
2743
+
2744
+ /**
2745
+ * Modül kayıtlarını filtre olmadan listeler
2746
+ * @param {string} moduleName - Modül adı
2747
+ * @returns {Promise<ModuleRecordResponse[]>}
2748
+ */
2749
+ async listAllRecords(moduleName) {
2750
+ this._validateRequired({ moduleName: moduleName }, ['moduleName']);
2751
+ return await this.http.get('/api/module/' + moduleName + '/records');
2752
+ }
2753
+
2754
+ /**
2755
+ * Kayıtlarda arama yapar
2756
+ * @param {string} moduleName - Modül adı
2757
+ * @param {string} query - Arama terimi
2758
+ * @returns {Promise<ModuleRecordResponse[]>}
2759
+ */
2760
+ async searchRecords(moduleName, query) {
2761
+ this._validateRequired({ moduleName: moduleName, query: query }, ['moduleName', 'query']);
2762
+ return await this.http.get('/api/module/' + moduleName + '/records/search', {
2763
+ query: { q: query }
2764
+ });
2765
+ }
2766
+
2767
+ /**
2768
+ * Bir kaydı getirir
2769
+ * @param {string} moduleName - Modül adı
2770
+ * @param {string} recordId - Kayıt ID'si
2771
+ * @returns {Promise<ModuleRecordResponse>}
2772
+ */
2773
+ async getRecord(moduleName, recordId) {
2774
+ this._validateRequired({ moduleName: moduleName, recordId: recordId }, ['moduleName', 'recordId']);
2775
+ return await this.http.get('/api/module/' + moduleName + '/records/' + recordId);
2776
+ }
2777
+
2778
+ /**
2779
+ * Kayıt oluşturur
2780
+ * @param {string} moduleName - Modül adı
2781
+ * @param {Object} data - Kayıt verileri
2782
+ * @returns {Promise<ModuleRecordResponse>}
2783
+ * @example
2784
+ * const lead = await supsis.module.createRecord('Leads', {
2785
+ * name: 'John Doe',
2786
+ * email: 'john@example.com',
2787
+ * phone: '+905551234567',
2788
+ * status: 'new'
2789
+ * });
2790
+ */
2791
+ async createRecord(moduleName, data) {
2792
+ this._validateRequired({ moduleName: moduleName }, ['moduleName']);
2793
+ return await this.http.put('/api/module/' + moduleName + '/records', data);
2794
+ }
2795
+
2796
+ /**
2797
+ * Birden fazla kayıt oluşturur
2798
+ * @param {string} moduleName - Modül adı
2799
+ * @param {Object[]} records - Kayıt verileri dizisi
2800
+ * @returns {Promise<ModuleRecordResponse[]>}
2801
+ */
2802
+ async createManyRecords(moduleName, records) {
2803
+ this._validateRequired({ moduleName: moduleName, records: records }, ['moduleName', 'records']);
2804
+ return await this.http.put('/api/module/' + moduleName + '/records/multi', {
2805
+ records: records
2806
+ });
2807
+ }
2808
+
2809
+ /**
2810
+ * Kaydı günceller
2811
+ * @param {string} moduleName - Modül adı
2812
+ * @param {string} recordId - Kayıt ID'si
2813
+ * @param {Object} data - Güncellenecek veriler
2814
+ * @returns {Promise<ModuleRecordResponse>}
2815
+ */
2816
+ async updateRecord(moduleName, recordId, data) {
2817
+ this._validateRequired({ moduleName: moduleName, recordId: recordId }, ['moduleName', 'recordId']);
2818
+ return await this.http.put('/api/module/' + moduleName + '/records/' + recordId, data);
2819
+ }
2820
+
2821
+ /**
2822
+ * Kaydı siler
2823
+ * @param {string} moduleName - Modül adı
2824
+ * @param {string} recordId - Kayıt ID'si
2825
+ * @returns {Promise<{success: boolean}>}
2826
+ */
2827
+ async deleteRecord(moduleName, recordId) {
2828
+ this._validateRequired({ moduleName: moduleName, recordId: recordId }, ['moduleName', 'recordId']);
2829
+ return await this.http.delete('/api/module/' + moduleName + '/records/' + recordId);
2830
+ }
2831
+
2832
+ /**
2833
+ * Contact ile ilişkili kayıtları listeler
2834
+ * @param {string} contactId - Contact ID'si
2835
+ * @returns {Promise<Object>} Modül adı -> Kayıtlar mapping
2836
+ */
2837
+ async listContactRelatedRecords(contactId) {
2838
+ this._validateRequired({ contactId: contactId }, ['contactId']);
2839
+ return await this.http.get('/api/module/records/contact-related-list', {
2840
+ query: { contactId: contactId }
2841
+ });
2842
+ }
2843
+
2844
+ /**
2845
+ * Modül ile ilişkili kayıtları listeler
2846
+ * @param {string} moduleName - Modül adı
2847
+ * @param {string} recordId - Kayıt ID'si
2848
+ * @returns {Promise<Object>} İlişkili kayıtlar
2849
+ */
2850
+ async listModuleRelatedRecords(moduleName, recordId) {
2851
+ this._validateRequired({ moduleName: moduleName, recordId: recordId }, ['moduleName', 'recordId']);
2852
+ return await this.http.get('/api/module/records/module-related-list', {
2853
+ query: {
2854
+ moduleName: moduleName,
2855
+ recordId: recordId
2856
+ }
2857
+ });
2858
+ }
2859
+ }
2860
+
2861
+ /**
2862
+ * @typedef {Object} ModuleDefinitionResponse
2863
+ * @property {string} _id - Modül ID
2864
+ * @property {string} siteId - Site ID
2865
+ * @property {string} name - Modül adı (API name)
2866
+ * @property {string} displayName - Görünen ad
2867
+ * @property {string} [description] - Açıklama
2868
+ * @property {string} [icon] - İkon
2869
+ * @property {ModuleFieldDefinition[]} fields - Alan tanımları
2870
+ * @property {Date} createdAt - Oluşturulma tarihi
2871
+ */
2872
+
2873
+ /**
2874
+ * @typedef {Object} ModuleFieldDefinition
2875
+ * @property {string} name - Alan adı
2876
+ * @property {string} displayName - Görünen ad
2877
+ * @property {string} type - Alan tipi
2878
+ * @property {boolean} [required] - Zorunlu mu
2879
+ * @property {*} [defaultValue] - Varsayılan değer
2880
+ * @property {Object} [options] - Alan seçenekleri
2881
+ */
2882
+
2883
+ /**
2884
+ * @typedef {Object} ModuleRecordResponse
2885
+ * @property {string} _id - Kayıt ID
2886
+ * @property {string} moduleId - Modül ID
2887
+ * @property {Object} data - Alan değerleri
2888
+ * @property {Date} createdAt - Oluşturulma tarihi
2889
+ * @property {Date} updatedAt - Güncellenme tarihi
2890
+ * @property {string} [createdBy] - Oluşturan kullanıcı ID
2891
+ */
2892
+
2893
+ /**
2894
+ * User modülü
2895
+ * Kullanıcı (temsilci) yönetimi
2896
+ *
2897
+ * @class User
2898
+ * @extends BaseModule
2899
+ * @example
2900
+ * // Mevcut kullanıcı bilgisi
2901
+ * const me = await supsis.user.me();
2902
+ *
2903
+ * // Kullanıcı listesi
2904
+ * const users = await supsis.user.list();
2905
+ */
2906
+ class User extends BaseModule {
2907
+ /**
2908
+ * Mevcut kullanıcının bilgisini getirir
2909
+ * @returns {Promise<UserResponse>}
2910
+ * @example
2911
+ * const me = await supsis.user.me();
2912
+ * console.log(me.fullname);
2913
+ * console.log(me.email);
2914
+ * console.log(me.role);
2915
+ */
2916
+ async me() {
2917
+ return await this.http.get('/api/users/me');
2918
+ }
2919
+
2920
+ /**
2921
+ * Mevcut kullanıcıyı günceller
2922
+ * @param {Object} data - Güncellenecek veriler
2923
+ * @returns {Promise<UserResponse>}
2924
+ */
2925
+ async updateMe(data) {
2926
+ return await this.http.put('/api/users/me', data);
2927
+ }
2928
+
2929
+ /**
2930
+ * Bir kullanıcıyı getirir
2931
+ * @param {string} userId - Kullanıcı ID'si
2932
+ * @returns {Promise<UserResponse>}
2933
+ */
2934
+ async get(userId) {
2935
+ this._validateRequired({ userId: userId }, ['userId']);
2936
+ return await this.http.get('/api/users/user/' + userId);
2937
+ }
2938
+
2939
+ /**
2940
+ * Kullanıcı listesini getirir
2941
+ * @param {Object} [options] - Filtreleme seçenekleri
2942
+ * @param {number} [options.page=1] - Sayfa numarası
2943
+ * @param {number} [options.limit=20] - Sayfa başına kayıt
2944
+ * @param {string} [options.status] - Durum filtresi
2945
+ * @returns {Promise<{data: UserResponse[], total: number}>}
2946
+ */
2947
+ async list(options) {
2948
+ options = options || {};
2949
+ const pagination = this._normalizePagination(options);
2950
+
2951
+ return await this.http.get('/api/users/pagination', {
2952
+ query: this._cleanObject({
2953
+ page: pagination.page,
2954
+ limit: pagination.limit,
2955
+ status: options.status
2956
+ })
2957
+ });
2958
+ }
2959
+
2960
+ /**
2961
+ * Online kullanıcıları listeler
2962
+ * @returns {Promise<UserResponse[]>}
2963
+ */
2964
+ async listOnline() {
2965
+ return await this.http.get('/api/users/list-online-users');
2966
+ }
2967
+
2968
+ /**
2969
+ * Kullanıcı oluşturur
2970
+ * @param {Object} data - Kullanıcı verileri
2971
+ * @param {string} data.fullname - İsim
2972
+ * @param {string} data.email - Email
2973
+ * @param {string} data.password - Şifre
2974
+ * @param {string} [data.role] - Rol ID'si
2975
+ * @param {string[]} [data.subjects] - Departman ID'leri
2976
+ * @returns {Promise<UserResponse>}
2977
+ */
2978
+ async create(data) {
2979
+ this._validateRequired(data, ['fullname', 'email', 'password']);
2980
+ return await this.http.post('/api/users', data);
2981
+ }
2982
+
2983
+ /**
2984
+ * Kullanıcıyı günceller
2985
+ * @param {string} userId - Kullanıcı ID'si
2986
+ * @param {Object} data - Güncellenecek veriler
2987
+ * @returns {Promise<UserResponse>}
2988
+ */
2989
+ async update(userId, data) {
2990
+ this._validateRequired({ userId: userId }, ['userId']);
2991
+ return await this.http.put('/api/users/' + userId, data);
2992
+ }
2993
+
2994
+ /**
2995
+ * Kullanıcıyı siler
2996
+ * @param {string} userId - Kullanıcı ID'si
2997
+ * @returns {Promise<{success: boolean}>}
2998
+ */
2999
+ async delete(userId) {
3000
+ this._validateRequired({ userId: userId }, ['userId']);
3001
+ return await this.http.delete('/api/users/' + userId);
3002
+ }
3003
+
3004
+ /**
3005
+ * Kullanıcı şifresini günceller
3006
+ * @param {string} userId - Kullanıcı ID'si
3007
+ * @param {string} newPassword - Yeni şifre
3008
+ * @returns {Promise<{success: boolean}>}
3009
+ */
3010
+ async updatePassword(userId, newPassword) {
3011
+ this._validateRequired({ userId: userId, newPassword: newPassword }, ['userId', 'newPassword']);
3012
+ return await this.http.put('/api/users/' + userId + '/updatePassword', {
3013
+ password: newPassword
3014
+ });
3015
+ }
3016
+
3017
+ /**
3018
+ * Kullanıcının online durumunu günceller
3019
+ * @param {string} userId - Kullanıcı ID'si
3020
+ * @param {boolean} isOnline - Online mi
3021
+ * @returns {Promise<UserResponse>}
3022
+ */
3023
+ async updateOnlineStatus(userId, isOnline) {
3024
+ this._validateRequired({ userId: userId }, ['userId']);
3025
+ return await this.http.put('/api/users/' + userId + '/onlineStatus', {
3026
+ isOnline: isOnline
3027
+ });
3028
+ }
3029
+
3030
+ /**
3031
+ * Kullanıcının durumunu günceller
3032
+ * @param {string} userId - Kullanıcı ID'si
3033
+ * @param {string} status - Durum: 'Online', 'Offline', 'Away', 'Busy'
3034
+ * @returns {Promise<UserResponse>}
3035
+ */
3036
+ async updateStatus(userId, status) {
3037
+ this._validateRequired({ userId: userId, status: status }, ['userId', 'status']);
3038
+ return await this.http.put('/api/users/' + userId + '/status', {
3039
+ status: status
3040
+ });
3041
+ }
3042
+
3043
+ /**
3044
+ * Aktif kullanıcı sayısını getirir
3045
+ * @returns {Promise<{count: number}>}
3046
+ */
3047
+ async getActiveCount() {
3048
+ return await this.http.get('/api/users/active-user-count');
3049
+ }
3050
+
3051
+ /**
3052
+ * Mevcut kullanıcının bildirim ayarlarını getirir
3053
+ * @returns {Promise<NotificationSettingsResponse>}
3054
+ */
3055
+ async getNotificationSettings() {
3056
+ return await this.http.get('/api/users/me/notification-settings');
3057
+ }
3058
+
3059
+ /**
3060
+ * Tutorial'ı tamamlandı olarak işaretler
3061
+ * @param {string} tutorialKey - Tutorial anahtarı
3062
+ * @returns {Promise<{success: boolean}>}
3063
+ */
3064
+ async completeTutorial(tutorialKey) {
3065
+ this._validateRequired({ tutorialKey: tutorialKey }, ['tutorialKey']);
3066
+ return await this.http.post('/api/users/me/setup-guide/' + tutorialKey);
3067
+ }
3068
+
3069
+ /**
3070
+ * Oturumu kapatır
3071
+ * @returns {Promise<{success: boolean}>}
3072
+ */
3073
+ async logout() {
3074
+ return await this.http.get('/api/users/logout');
3075
+ }
3076
+ }
3077
+
3078
+ /**
3079
+ * @typedef {Object} UserResponse
3080
+ * @property {string} _id - Kullanıcı ID
3081
+ * @property {string} siteId - Site ID
3082
+ * @property {string} fullname - İsim
3083
+ * @property {string} email - Email
3084
+ * @property {string} [role] - Rol ID
3085
+ * @property {string[]} [subjects] - Departman ID'leri
3086
+ * @property {string} status - Durum: 'Online', 'Offline', 'Away', 'Busy'
3087
+ * @property {boolean} isOnline - Online mi
3088
+ * @property {string} [profilePicture] - Profil fotoğrafı URL
3089
+ * @property {Date} createdDate - Oluşturulma tarihi
3090
+ * @property {Date} [lastLoginDate] - Son giriş tarihi
3091
+ * @property {Object} [permissions] - İzinler
3092
+ */
3093
+
3094
+ /**
3095
+ * @typedef {Object} NotificationSettingsResponse
3096
+ * @property {boolean} emailNotifications - Email bildirimleri
3097
+ * @property {boolean} pushNotifications - Push bildirimleri
3098
+ * @property {boolean} soundEnabled - Ses açık mı
3099
+ * @property {Object} [channels] - Kanal bazlı ayarlar
3100
+ */
3101
+
3102
+ /**
3103
+ * Tag modülü
3104
+ * Etiket yönetimi
3105
+ *
3106
+ * @class Tag
3107
+ * @extends BaseModule
3108
+ * @example
3109
+ * // Etiket listele
3110
+ * const tags = await supsis.tag.list();
3111
+ *
3112
+ * // Etiket oluştur
3113
+ * const tag = await supsis.tag.create({ name: 'VIP', color: '#FF0000' });
3114
+ */
3115
+ class Tag extends BaseModule {
3116
+ /**
3117
+ * Etiketleri listeler
3118
+ * @param {string} [type] - Etiket tipi: 'visitor', 'conversation', 'ticket'
3119
+ * @returns {Promise<TagResponse[]>}
3120
+ * @example
3121
+ * // Tüm etiketler
3122
+ * const allTags = await supsis.tag.list();
3123
+ *
3124
+ * // Contact etiketleri
3125
+ * const visitorTags = await supsis.tag.list('visitor');
3126
+ */
3127
+ async list(type) {
3128
+ const endpoint = type ? '/api/tags/' + type : '/api/tags';
3129
+ return await this.http.get(endpoint);
3130
+ }
3131
+
3132
+ /**
3133
+ * Etiket oluşturur
3134
+ * @param {Object} data - Etiket verileri
3135
+ * @param {string} data.name - Etiket adı
3136
+ * @param {string} [data.color] - Renk kodu (#RRGGBB)
3137
+ * @param {string} [data.type] - Etiket tipi: 'visitor', 'conversation', 'ticket'
3138
+ * @returns {Promise<TagResponse>}
3139
+ * @example
3140
+ * const tag = await supsis.tag.create({
3141
+ * name: 'VIP Müşteri',
3142
+ * color: '#FF0000',
3143
+ * type: 'visitor'
3144
+ * });
3145
+ */
3146
+ async create(data) {
3147
+ this._validateRequired(data, ['name']);
3148
+ return await this.http.post('/api/tags', data);
3149
+ }
3150
+
3151
+ /**
3152
+ * Etiketi günceller
3153
+ * @param {Object} data - Güncellenecek veriler
3154
+ * @param {string} data._id - Etiket ID'si
3155
+ * @param {string} [data.name] - Yeni ad
3156
+ * @param {string} [data.color] - Yeni renk
3157
+ * @returns {Promise<TagResponse>}
3158
+ */
3159
+ async update(data) {
3160
+ this._validateRequired(data, ['_id']);
3161
+ return await this.http.patch('/api/tags', data);
3162
+ }
3163
+
3164
+ /**
3165
+ * Etiketi siler
3166
+ * @param {string} tagId - Etiket ID'si
3167
+ * @returns {Promise<{success: boolean}>}
3168
+ */
3169
+ async delete(tagId) {
3170
+ this._validateRequired({ tagId: tagId }, ['tagId']);
3171
+ return await this.http.delete('/api/tags/' + tagId);
3172
+ }
3173
+ }
3174
+
3175
+ /**
3176
+ * @typedef {Object} TagResponse
3177
+ * @property {string} _id - Etiket ID
3178
+ * @property {string} siteId - Site ID
3179
+ * @property {string} name - Etiket adı
3180
+ * @property {string} [color] - Renk kodu
3181
+ * @property {string} [type] - Etiket tipi: 'visitor', 'conversation', 'ticket'
3182
+ * @property {Date} createdAt - Oluşturulma tarihi
3183
+ */
3184
+
3185
+ /**
3186
+ * Site modülü
3187
+ * Site bilgileri ve ayarları
3188
+ *
3189
+ * @class Site
3190
+ * @extends BaseModule
3191
+ * @example
3192
+ * // Site özellikleri
3193
+ * const features = await supsis.site.getFeatures();
3194
+ *
3195
+ * // Cüzdan bilgisi
3196
+ * const wallet = await supsis.site.getWallet();
3197
+ */
3198
+ class Site extends BaseModule {
3199
+ /**
3200
+ * Mevcut planı getirir
3201
+ * @returns {Promise<PlanResponse>}
3202
+ * @example
3203
+ * const plan = await supsis.site.getCurrentPlan();
3204
+ * console.log(plan.name); // 'Professional'
3205
+ * console.log(plan.features);
3206
+ */
3207
+ async getCurrentPlan() {
3208
+ return await this.http.get('/api/sites/current-plan');
3209
+ }
3210
+
3211
+ /**
3212
+ * Site özelliklerini getirir
3213
+ * @returns {Promise<FeaturesResponse>}
3214
+ * @example
3215
+ * const features = await supsis.site.getFeatures();
3216
+ * console.log(features.whatsapp); // true/false
3217
+ * console.log(features.voiceAgent); // true/false
3218
+ */
3219
+ async getFeatures() {
3220
+ return await this.http.get('/api/sites/features');
3221
+ }
3222
+
3223
+ /**
3224
+ * Cüzdan bilgisini getirir
3225
+ * @returns {Promise<WalletResponse[]>}
3226
+ */
3227
+ async getWallet() {
3228
+ return await this.http.get('/api/sites/wallet');
3229
+ }
3230
+
3231
+ /**
3232
+ * Cüzdan aktivitelerini getirir
3233
+ * @param {Object} [options] - Filtreleme seçenekleri
3234
+ * @param {string} [options.walletType] - Cüzdan tipi
3235
+ * @param {Date|string} [options.startDate] - Başlangıç tarihi
3236
+ * @param {Date|string} [options.endDate] - Bitiş tarihi
3237
+ * @returns {Promise<WalletActivityResponse[]>}
3238
+ */
3239
+ async getWalletActivities(options) {
3240
+ options = options || {};
3241
+ return await this.http.get('/api/sites/wallet/activities', {
3242
+ query: this._cleanObject({
3243
+ walletType: options.walletType,
3244
+ startDate: this._toISODate(options.startDate),
3245
+ endDate: this._toISODate(options.endDate)
3246
+ })
3247
+ });
3248
+ }
3249
+
3250
+ /**
3251
+ * Cüzdana bakiye yükler
3252
+ * @param {string} walletType - Cüzdan tipi (örn: 'whatsapp')
3253
+ * @param {number} amount - Miktar
3254
+ * @returns {Promise<WalletResponse>}
3255
+ */
3256
+ async depositWallet(walletType, amount) {
3257
+ this._validateRequired({ walletType: walletType, amount: amount }, ['walletType', 'amount']);
3258
+ return await this.http.post('/api/sites/wallet/' + walletType, {
3259
+ amount: amount
3260
+ });
3261
+ }
3262
+
3263
+ /**
3264
+ * Otomatik bakiye yükleme ayarlarını getirir
3265
+ * @param {string} walletType - Cüzdan tipi
3266
+ * @returns {Promise<AutoRebalanceResponse>}
3267
+ */
3268
+ async getAutoRebalanceSettings(walletType) {
3269
+ this._validateRequired({ walletType: walletType }, ['walletType']);
3270
+ return await this.http.get('/api/sites/wallet/' + walletType + '/auto-rebalance');
3271
+ }
3272
+
3273
+ /**
3274
+ * Otomatik bakiye yükleme ayarlarını günceller
3275
+ * @param {string} walletType - Cüzdan tipi
3276
+ * @param {Object} settings - Ayarlar
3277
+ * @returns {Promise<AutoRebalanceResponse>}
3278
+ */
3279
+ async updateAutoRebalanceSettings(walletType, settings) {
3280
+ this._validateRequired({ walletType: walletType }, ['walletType']);
3281
+ return await this.http.put('/api/sites/wallet/' + walletType + '/auto-rebalance', settings);
3282
+ }
3283
+
3284
+ /**
3285
+ * Konuşma istatistiklerini getirir
3286
+ * @returns {Promise<ConversationUsageResponse>}
3287
+ */
3288
+ async getConversationUsage() {
3289
+ return await this.http.get('/api/sites/conversation-usages');
3290
+ }
3291
+
3292
+ /**
3293
+ * Depolama kullanımını getirir
3294
+ * @param {Object} [options] - Seçenekler
3295
+ * @returns {Promise<StorageUsageResponse>}
3296
+ */
3297
+ async getStorageUsage(options) {
3298
+ return await this.http.post('/api/sites/storage-usages', options || {});
3299
+ }
3300
+
3301
+ /**
3302
+ * Entegrasyon durumunu kontrol eder
3303
+ * @param {Object} options - Kontrol seçenekleri
3304
+ * @returns {Promise<IntegrationStatusResponse>}
3305
+ */
3306
+ async checkIntegrationStatus(options) {
3307
+ return await this.http.post('/api/public/sites/check-integration-status', options || {});
3308
+ }
3309
+ }
3310
+
3311
+ /**
3312
+ * @typedef {Object} PlanResponse
3313
+ * @property {string} _id - Plan ID
3314
+ * @property {string} name - Plan adı
3315
+ * @property {string} [description] - Açıklama
3316
+ * @property {Object} features - Özellikler
3317
+ * @property {Object} limits - Limitler
3318
+ * @property {Date} [expiresAt] - Bitiş tarihi
3319
+ */
3320
+
3321
+ /**
3322
+ * @typedef {Object} FeaturesResponse
3323
+ * @property {boolean} whatsapp - WhatsApp aktif mi
3324
+ * @property {boolean} instagram - Instagram aktif mi
3325
+ * @property {boolean} voiceAgent - Voice Agent aktif mi
3326
+ * @property {boolean} automation - Otomasyon aktif mi
3327
+ * @property {boolean} chatbot - Chatbot aktif mi
3328
+ * @property {boolean} crm - CRM aktif mi
3329
+ * @property {Object} [limits] - Özellik limitleri
3330
+ */
3331
+
3332
+ /**
3333
+ * @typedef {Object} WalletResponse
3334
+ * @property {string} _id - Cüzdan ID
3335
+ * @property {string} type - Cüzdan tipi
3336
+ * @property {number} amount - Bakiye
3337
+ * @property {string} currency - Para birimi
3338
+ */
3339
+
3340
+ /**
3341
+ * @typedef {Object} WalletActivityResponse
3342
+ * @property {string} _id - Aktivite ID
3343
+ * @property {string} type - Aktivite tipi
3344
+ * @property {number} amount - Miktar
3345
+ * @property {string} description - Açıklama
3346
+ * @property {Date} createdAt - Tarih
3347
+ */
3348
+
3349
+ /**
3350
+ * @typedef {Object} AutoRebalanceResponse
3351
+ * @property {boolean} enabled - Aktif mi
3352
+ * @property {number} threshold - Eşik değer
3353
+ * @property {number} rechargeAmount - Yüklenecek miktar
3354
+ */
3355
+
3356
+ /**
3357
+ * @typedef {Object} ConversationUsageResponse
3358
+ * @property {number} total - Toplam konuşma
3359
+ * @property {number} thisMonth - Bu ay
3360
+ * @property {number} limit - Limit
3361
+ */
3362
+
3363
+ /**
3364
+ * @typedef {Object} StorageUsageResponse
3365
+ * @property {number} used - Kullanılan (bytes)
3366
+ * @property {number} limit - Limit (bytes)
3367
+ * @property {number} percentage - Kullanım yüzdesi
3368
+ */
3369
+
3370
+ /**
3371
+ * @typedef {Object} IntegrationStatusResponse
3372
+ * @property {boolean} integrated - Entegre mi
3373
+ * @property {string} [status] - Durum
3374
+ */
3375
+
3376
+ /**
3377
+ * Cache modülü
3378
+ * Anahtar-değer cache yönetimi (Otomasyon ve Chatbot için)
3379
+ *
3380
+ * @class Cache
3381
+ * @extends BaseModule
3382
+ * @example
3383
+ * // Cache yaz
3384
+ * await supsis.cache.write('user:123', { name: 'John' }, { expiresIn: { value: 1, unit: 'hours' } });
3385
+ *
3386
+ * // Cache oku
3387
+ * const data = await supsis.cache.read('user:123');
3388
+ */
3389
+ class Cache extends BaseModule {
3390
+ /**
3391
+ * Cache listesini getirir
3392
+ * @param {Object} [options] - Filtreleme seçenekleri
3393
+ * @param {string} [options.pattern] - Anahtar pattern'i
3394
+ * @param {string} [options.type] - Tip: 'public', 'private'
3395
+ * @param {string} [options.actorType] - Oluşturan: 'chatbot', 'automation', 'api', 'user'
3396
+ * @param {number} [options.page=1] - Sayfa numarası
3397
+ * @param {number} [options.limit=20] - Sayfa başına kayıt
3398
+ * @returns {Promise<{data: CacheResponse[], total: number}>}
3399
+ */
3400
+ async list(options) {
3401
+ options = options || {};
3402
+ const pagination = this._normalizePagination(options);
3403
+
3404
+ return await this.http.post('/api/cache/list', {
3405
+ pattern: options.pattern,
3406
+ type: options.type,
3407
+ actorType: options.actorType,
3408
+ page: pagination.page,
3409
+ limit: pagination.limit
3410
+ });
3411
+ }
3412
+
3413
+ /**
3414
+ * Cache yazar
3415
+ * @param {string} key - Anahtar
3416
+ * @param {*} value - Değer (herhangi bir JSON-serializable değer)
3417
+ * @param {Object} [options] - Seçenekler
3418
+ * @param {string} [options.type='public'] - Tip: 'public', 'private'
3419
+ * @param {string} [options.dataType='mixed'] - Veri tipi: 'string', 'number', 'boolean', 'date', 'json', 'array', 'mixed'
3420
+ * @param {Object} [options.expiresIn] - Geçerlilik süresi
3421
+ * @param {number} options.expiresIn.value - Süre değeri
3422
+ * @param {string} options.expiresIn.unit - Birim: 'seconds', 'minutes', 'hours', 'days', 'weeks', 'months'
3423
+ * @param {Date|string} [options.expiresAt] - Kesin bitiş tarihi
3424
+ * @returns {Promise<CacheResponse>}
3425
+ * @example
3426
+ * // 1 saat geçerli cache
3427
+ * await supsis.cache.write('session:abc', { userId: '123' }, {
3428
+ * expiresIn: { value: 1, unit: 'hours' }
3429
+ * });
3430
+ *
3431
+ * // Belirli bir tarihe kadar geçerli
3432
+ * await supsis.cache.write('promo:summer', { discount: 20 }, {
3433
+ * expiresAt: '2024-08-31T23:59:59Z'
3434
+ * });
3435
+ */
3436
+ async write(key, value, options) {
3437
+ this._validateRequired({ key: key }, ['key']);
3438
+ options = options || {};
3439
+
3440
+ const body = {
3441
+ key: key,
3442
+ value: value,
3443
+ type: options.type || 'public',
3444
+ dataType: options.dataType || 'mixed'
3445
+ };
3446
+
3447
+ // expiresIn varsa expiresAt'e çevir
3448
+ if (options.expiresIn) {
3449
+ const now = new Date();
3450
+ const multipliers = {
3451
+ seconds: 1000,
3452
+ minutes: 60 * 1000,
3453
+ hours: 60 * 60 * 1000,
3454
+ days: 24 * 60 * 60 * 1000,
3455
+ weeks: 7 * 24 * 60 * 60 * 1000,
3456
+ months: 30 * 24 * 60 * 60 * 1000
3457
+ };
3458
+ const ms = options.expiresIn.value * (multipliers[options.expiresIn.unit] || multipliers.hours);
3459
+ body.expiresAt = new Date(now.getTime() + ms).toISOString();
3460
+ } else if (options.expiresAt) {
3461
+ body.expiresAt = this._toISODate(options.expiresAt);
3462
+ }
3463
+
3464
+ return await this.http.post('/api/cache/write', body);
3465
+ }
3466
+
3467
+ /**
3468
+ * Cache okur
3469
+ * @param {string} key - Anahtar
3470
+ * @param {*} [defaultValue=null] - Bulunamazsa dönecek değer
3471
+ * @returns {Promise<*>} Cache değeri veya defaultValue
3472
+ * @example
3473
+ * const session = await supsis.cache.read('session:abc');
3474
+ * const count = await supsis.cache.read('counter', 0);
3475
+ */
3476
+ async read(key, defaultValue) {
3477
+ this._validateRequired({ key: key }, ['key']);
3478
+
3479
+ try {
3480
+ const result = await this.http.post('/api/cache/list', {
3481
+ pattern: key,
3482
+ limit: 1
3483
+ });
3484
+
3485
+ if (result && result.data && result.data.length > 0) {
3486
+ return result.data[0].value;
3487
+ }
3488
+ return defaultValue !== undefined ? defaultValue : null;
3489
+ } catch (e) {
3490
+ return defaultValue !== undefined ? defaultValue : null;
3491
+ }
3492
+ }
3493
+
3494
+ /**
3495
+ * Cache değerini günceller
3496
+ * @param {string} cacheId - Cache ID'si
3497
+ * @param {*} value - Yeni değer
3498
+ * @returns {Promise<CacheResponse>}
3499
+ */
3500
+ async update(cacheId, value) {
3501
+ this._validateRequired({ cacheId: cacheId }, ['cacheId']);
3502
+ return await this.http.post('/api/cache/' + cacheId + '/update', {
3503
+ value: value
3504
+ });
3505
+ }
3506
+
3507
+ /**
3508
+ * Cache süresini uzatır
3509
+ * @param {string} cacheId - Cache ID'si
3510
+ * @param {Object} expiresIn - Uzatma süresi
3511
+ * @param {number} expiresIn.value - Süre değeri
3512
+ * @param {string} expiresIn.unit - Birim
3513
+ * @returns {Promise<CacheResponse>}
3514
+ * @example
3515
+ * await supsis.cache.extend('cacheId', { value: 1, unit: 'hours' });
3516
+ */
3517
+ async extend(cacheId, expiresIn) {
3518
+ this._validateRequired({ cacheId: cacheId, expiresIn: expiresIn }, ['cacheId', 'expiresIn']);
3519
+
3520
+ const multipliers = {
3521
+ seconds: 1000,
3522
+ minutes: 60 * 1000,
3523
+ hours: 60 * 60 * 1000,
3524
+ days: 24 * 60 * 60 * 1000,
3525
+ weeks: 7 * 24 * 60 * 60 * 1000,
3526
+ months: 30 * 24 * 60 * 60 * 1000
3527
+ };
3528
+
3529
+ const now = new Date();
3530
+ const ms = expiresIn.value * (multipliers[expiresIn.unit] || multipliers.hours);
3531
+ const newExpiresAt = new Date(now.getTime() + ms);
3532
+
3533
+ return await this.http.post('/api/cache/' + cacheId + '/extend', {
3534
+ expiresAt: newExpiresAt.toISOString()
3535
+ });
3536
+ }
3537
+
3538
+ /**
3539
+ * Cache'i sonsuz yapar (süresiz)
3540
+ * @param {string} cacheId - Cache ID'si
3541
+ * @returns {Promise<CacheResponse>}
3542
+ */
3543
+ async makeNeverExpire(cacheId) {
3544
+ this._validateRequired({ cacheId: cacheId }, ['cacheId']);
3545
+ return await this.http.post('/api/cache/' + cacheId + '/never-expire');
3546
+ }
3547
+
3548
+ /**
3549
+ * Cache siler
3550
+ * @param {string} cacheId - Cache ID'si
3551
+ * @returns {Promise<{success: boolean}>}
3552
+ */
3553
+ async delete(cacheId) {
3554
+ this._validateRequired({ cacheId: cacheId }, ['cacheId']);
3555
+ return await this.http.delete('/api/cache/' + cacheId);
3556
+ }
3557
+
3558
+ /**
3559
+ * Birden fazla cache siler
3560
+ * @param {string[]} cacheIds - Cache ID'leri
3561
+ * @returns {Promise<{success: boolean, deletedCount: number}>}
3562
+ */
3563
+ async deleteMany(cacheIds) {
3564
+ this._validateRequired({ cacheIds: cacheIds }, ['cacheIds']);
3565
+ return await this.http.post('/api/cache/bulk-delete', {
3566
+ cacheIds: cacheIds
3567
+ });
3568
+ }
3569
+
3570
+ /**
3571
+ * Belirli bir actor'ün cache'lerini siler
3572
+ * @param {string} actorType - Actor tipi: 'chatbot', 'automation'
3573
+ * @param {string} actorId - Actor ID'si
3574
+ * @returns {Promise<{success: boolean, deletedCount: number}>}
3575
+ */
3576
+ async deleteByActor(actorType, actorId) {
3577
+ this._validateRequired({ actorType: actorType, actorId: actorId }, ['actorType', 'actorId']);
3578
+ return await this.http.post('/api/cache/delete-by-actor', {
3579
+ actorType: actorType,
3580
+ actorId: actorId
3581
+ });
3582
+ }
3583
+
3584
+ /**
3585
+ * Pattern'e göre cache siler
3586
+ * @param {string} pattern - Anahtar pattern'i
3587
+ * @returns {Promise<{success: boolean, deletedCount: number}>}
3588
+ */
3589
+ async deleteByPattern(pattern) {
3590
+ this._validateRequired({ pattern: pattern }, ['pattern']);
3591
+ return await this.http.post('/api/cache/delete-by-pattern', {
3592
+ pattern: pattern
3593
+ });
3594
+ }
3595
+ }
3596
+
3597
+ /**
3598
+ * @typedef {Object} CacheResponse
3599
+ * @property {string} _id - Cache ID
3600
+ * @property {string} siteId - Site ID
3601
+ * @property {string} key - Anahtar
3602
+ * @property {*} value - Değer
3603
+ * @property {string} type - Tip: 'public', 'private'
3604
+ * @property {string} dataType - Veri tipi
3605
+ * @property {string} createdByActorType - Oluşturan actor tipi
3606
+ * @property {string} [createdByAutomation] - Oluşturan otomasyon ID
3607
+ * @property {string} [createdByChatbot] - Oluşturan chatbot ID
3608
+ * @property {string} [createdByUser] - Oluşturan kullanıcı ID
3609
+ * @property {Date} [expiresAt] - Bitiş tarihi
3610
+ * @property {Date} createdAt - Oluşturulma tarihi
3611
+ * @property {Date} updatedAt - Güncellenme tarihi
3612
+ */
3613
+
3614
+ /**
3615
+ * Supsis API SDK Ana Sınıfı
3616
+ *
3617
+ * Browser ve Node.js ortamlarında çalışan, Supsis API'sine erişim sağlayan SDK.
3618
+ * Email/password ile authentication yaparak tüm API'lere erişim sağlar.
3619
+ *
3620
+ * @class SupsisJS
3621
+ * @example
3622
+ * // Temel kullanım
3623
+ * const supsis = new SupsisJS({
3624
+ * email: 'user@example.com',
3625
+ * password: 'secret',
3626
+ * siteId: 'site123'
3627
+ * });
3628
+ *
3629
+ * await supsis.connect();
3630
+ *
3631
+ * const chat = await supsis.chat.get('chatId');
3632
+ * const contacts = await supsis.contact.list({ limit: 10 });
3633
+ *
3634
+ * @example
3635
+ * // Stage ortamında kullanım
3636
+ * const supsis = new SupsisJS({
3637
+ * email: 'dev@example.com',
3638
+ * password: 'secret',
3639
+ * siteId: 'site123',
3640
+ * env: 'stage'
3641
+ * });
3642
+ *
3643
+ * @example
3644
+ * // OnPrem kurulum
3645
+ * const supsis = new SupsisJS({
3646
+ * email: 'user@company.com',
3647
+ * password: 'secret',
3648
+ * siteId: 'site123',
3649
+ * baseApiAddress: 'https://api.company-supsis.com'
3650
+ * });
3651
+ */
3652
+ class SupsisJS {
3653
+ /**
3654
+ * SupsisJS instance oluşturur
3655
+ * @param {SupsisConfig} config - SDK konfigürasyonu
3656
+ */
3657
+ constructor(config) {
3658
+ if (!config) {
3659
+ throw new Error('Config is required');
3660
+ }
3661
+
3662
+ this._validateConfig(config);
3663
+
3664
+ /** @private */
3665
+ this._config = config;
3666
+
3667
+ /** @private */
3668
+ this._http = new HttpClient({
3669
+ env: config.env || 'production',
3670
+ baseApiAddress: config.baseApiAddress,
3671
+ siteId: config.siteId,
3672
+ timeout: config.timeout,
3673
+ retryCount: config.retryCount
3674
+ });
3675
+
3676
+ /** @private */
3677
+ this._connected = false;
3678
+
3679
+ /** @private */
3680
+ this._token = null;
3681
+
3682
+ /** @private */
3683
+ this._user = null;
3684
+
3685
+ // Modülleri oluştur
3686
+ this._initModules();
3687
+ }
3688
+
3689
+ /**
3690
+ * Config validasyonu
3691
+ * @private
3692
+ */
3693
+ _validateConfig(config) {
3694
+ if (!config.email) {
3695
+ throw new Error('email is required');
3696
+ }
3697
+ if (!config.password) {
3698
+ throw new Error('password is required');
3699
+ }
3700
+ if (!config.siteId) {
3701
+ throw new Error('siteId is required');
3702
+ }
3703
+ }
3704
+
3705
+ /**
3706
+ * Modülleri initialize eder
3707
+ * @private
3708
+ */
3709
+ _initModules() {
3710
+ /**
3711
+ * Chat (Conversation) modülü
3712
+ * @type {Chat}
3713
+ */
3714
+ this.chat = new Chat(this._http);
3715
+
3716
+ /**
3717
+ * Contact (Visitor) modülü
3718
+ * @type {Contact}
3719
+ */
3720
+ this.contact = new Contact(this._http);
3721
+
3722
+ /**
3723
+ * Message modülü
3724
+ * @type {Message}
3725
+ */
3726
+ this.message = new Message(this._http);
3727
+
3728
+ /**
3729
+ * Task modülü
3730
+ * @type {Task}
3731
+ */
3732
+ this.task = new Task(this._http);
3733
+
3734
+ /**
3735
+ * AI Call (Voice Agent) modülü
3736
+ * @type {AICall}
3737
+ */
3738
+ this.aicall = new AICall(this._http);
3739
+
3740
+ /**
3741
+ * Asset modülü
3742
+ * @type {Asset}
3743
+ */
3744
+ this.asset = new Asset(this._http);
3745
+
3746
+ /**
3747
+ * Table (CustomerTable) modülü
3748
+ * @type {Table}
3749
+ */
3750
+ this.table = new Table(this._http);
3751
+
3752
+ /**
3753
+ * Module (Dynamic Modules) modülü
3754
+ * @type {Module}
3755
+ */
3756
+ this.module = new Module(this._http);
3757
+
3758
+ /**
3759
+ * User modülü
3760
+ * @type {User}
3761
+ */
3762
+ this.user = new User(this._http);
3763
+
3764
+ /**
3765
+ * Tag modülü
3766
+ * @type {Tag}
3767
+ */
3768
+ this.tag = new Tag(this._http);
3769
+
3770
+ /**
3771
+ * Site modülü
3772
+ * @type {Site}
3773
+ */
3774
+ this.site = new Site(this._http);
3775
+
3776
+ /**
3777
+ * Cache modülü
3778
+ * @type {Cache}
3779
+ */
3780
+ this.cache = new Cache(this._http);
3781
+ }
3782
+
3783
+ /**
3784
+ * API'ye bağlanır (login yapar)
3785
+ * @returns {Promise<UserResponse>} Giriş yapan kullanıcı bilgisi
3786
+ * @throws {SupsisAPIError} Login başarısız olduğunda
3787
+ * @example
3788
+ * await supsis.connect();
3789
+ * console.log('Connected as:', supsis.currentUser.fullname);
3790
+ */
3791
+ async connect() {
3792
+ if (this._connected) {
3793
+ return this._user;
3794
+ }
3795
+
3796
+ const response = await this._http.post('/api/users/login', {
3797
+ email: this._config.email,
3798
+ password: this._config.password
3799
+ }, { skipAuth: true });
3800
+
3801
+ if (!response || !response.token) {
3802
+ throw new SupsisAPIError('Login failed: No token received', 401);
3803
+ }
3804
+
3805
+ this._token = response.token;
3806
+ this._user = response.user || response;
3807
+ this._http.setToken(this._token);
3808
+ this._connected = true;
3809
+
3810
+ return this._user;
3811
+ }
3812
+
3813
+ /**
3814
+ * Bağlantıyı kapatır (logout yapar)
3815
+ * @returns {Promise<void>}
3816
+ */
3817
+ async disconnect() {
3818
+ if (!this._connected) {
3819
+ return;
3820
+ }
3821
+
3822
+ try {
3823
+ await this._http.get('/api/users/logout');
3824
+ } catch (e) {
3825
+ // Logout hatası ignore edilebilir
3826
+ }
3827
+
3828
+ this._token = null;
3829
+ this._user = null;
3830
+ this._http.setToken(null);
3831
+ this._connected = false;
3832
+ }
3833
+
3834
+ /**
3835
+ * Bağlı mı kontrol eder
3836
+ * @returns {boolean}
3837
+ */
3838
+ get isConnected() {
3839
+ return this._connected;
3840
+ }
3841
+
3842
+ /**
3843
+ * Mevcut kullanıcı bilgisi
3844
+ * @returns {UserResponse|null}
3845
+ */
3846
+ get currentUser() {
3847
+ return this._user;
3848
+ }
3849
+
3850
+ /**
3851
+ * Mevcut token
3852
+ * @returns {string|null}
3853
+ */
3854
+ get token() {
3855
+ return this._token;
3856
+ }
3857
+
3858
+ /**
3859
+ * SDK versiyonu
3860
+ * @returns {string}
3861
+ */
3862
+ get version() {
3863
+ return SDK_VERSION;
3864
+ }
3865
+
3866
+ /**
3867
+ * HttpClient'a direkt erişim (gelişmiş kullanım için)
3868
+ * @returns {HttpClient}
3869
+ */
3870
+ get http() {
3871
+ return this._http;
3872
+ }
3873
+
3874
+ /**
3875
+ * Mevcut token'ı manuel olarak set eder (örn: önceden alınmış token ile)
3876
+ * @param {string} token - JWT token
3877
+ */
3878
+ setToken(token) {
3879
+ this._token = token;
3880
+ this._http.setToken(token);
3881
+ this._connected = true;
3882
+ }
3883
+ }
3884
+
3885
+ /**
3886
+ * @typedef {Object} SupsisConfig
3887
+ * @property {string} email - Kullanıcı email adresi
3888
+ * @property {string} password - Kullanıcı şifresi
3889
+ * @property {string} siteId - Site ID (multi-tenant)
3890
+ * @property {string} [env='production'] - Ortam: 'production', 'stage', 'local'
3891
+ * @property {string} [baseApiAddress] - Custom API adresi (OnPrem için)
3892
+ * @property {number} [timeout=30000] - HTTP istek timeout süresi (ms)
3893
+ * @property {number} [retryCount=3] - Başarısız isteklerde retry sayısı
3894
+ */
3895
+
3896
+ /**
3897
+ * @typedef {Object} UserResponse
3898
+ * @property {string} _id - Kullanıcı ID
3899
+ * @property {string} fullname - İsim
3900
+ * @property {string} email - Email
3901
+ * @property {string} [role] - Rol
3902
+ * @property {Object} [permissions] - İzinler
3903
+ */
3904
+
3905
+ /**
3906
+ * Supsis Module API Sınıfı
3907
+ *
3908
+ * Developer access token ile çalışan kısıtlı API erişimi.
3909
+ * Panelden alınan access token ile direkt kullanılabilir.
3910
+ *
3911
+ * @class SupsisModuleAPI
3912
+ * @example
3913
+ * const api = new SupsisModuleAPI({
3914
+ * accessToken: 'dev_token_xxx',
3915
+ * siteId: 'site123'
3916
+ * });
3917
+ *
3918
+ * const records = await api.module.listRecords('Leads');
3919
+ * const tables = await api.table.list();
3920
+ */
3921
+ class SupsisModuleAPI {
3922
+ /**
3923
+ * SupsisModuleAPI instance oluşturur
3924
+ * @param {ModuleAPIConfig} config - API konfigürasyonu
3925
+ */
3926
+ constructor(config) {
3927
+ if (!config) {
3928
+ throw new Error('Config is required');
3929
+ }
3930
+
3931
+ if (!config.accessToken) {
3932
+ throw new Error('accessToken is required');
3933
+ }
3934
+
3935
+ if (!config.siteId) {
3936
+ throw new Error('siteId is required');
3937
+ }
3938
+
3939
+ /** @private */
3940
+ this._config = config;
3941
+
3942
+ /** @private */
3943
+ this._http = new HttpClient({
3944
+ env: config.env || 'production',
3945
+ baseApiAddress: config.baseApiAddress,
3946
+ siteId: config.siteId,
3947
+ timeout: config.timeout,
3948
+ retryCount: config.retryCount
3949
+ });
3950
+
3951
+ // Token'ı set et
3952
+ this._http.setToken(config.accessToken);
3953
+
3954
+ // Modülleri oluştur
3955
+ this._initModules();
3956
+ }
3957
+
3958
+ /**
3959
+ * Modülleri initialize eder
3960
+ * @private
3961
+ */
3962
+ _initModules() {
3963
+ /**
3964
+ * Table (CustomerTable) modülü
3965
+ * @type {Table}
3966
+ */
3967
+ this.table = new Table(this._http);
3968
+
3969
+ /**
3970
+ * Module (Dynamic Modules) modülü
3971
+ * @type {Module}
3972
+ */
3973
+ this.module = new Module(this._http);
3974
+
3975
+ /**
3976
+ * Cache modülü
3977
+ * @type {Cache}
3978
+ */
3979
+ this.cache = new Cache(this._http);
3980
+ }
3981
+
3982
+ /**
3983
+ * SDK versiyonu
3984
+ * @returns {string}
3985
+ */
3986
+ get version() {
3987
+ return SDK_VERSION;
3988
+ }
3989
+
3990
+ /**
3991
+ * HttpClient'a direkt erişim (gelişmiş kullanım için)
3992
+ * @returns {HttpClient}
3993
+ */
3994
+ get http() {
3995
+ return this._http;
3996
+ }
3997
+
3998
+ /**
3999
+ * Access token'ı günceller
4000
+ * @param {string} token - Yeni access token
4001
+ */
4002
+ setAccessToken(token) {
4003
+ this._http.setToken(token);
4004
+ }
4005
+ }
4006
+
4007
+ /**
4008
+ * @typedef {Object} ModuleAPIConfig
4009
+ * @property {string} accessToken - Developer access token (panelden alınır)
4010
+ * @property {string} siteId - Site ID (multi-tenant)
4011
+ * @property {string} [env='production'] - Ortam: 'production', 'stage', 'local'
4012
+ * @property {string} [baseApiAddress] - Custom API adresi (OnPrem için)
4013
+ * @property {number} [timeout=30000] - HTTP istek timeout süresi (ms)
4014
+ * @property {number} [retryCount=3] - Başarısız isteklerde retry sayısı
4015
+ */
4016
+
4017
+ /**
4018
+ * Supsis JS SDK
4019
+ *
4020
+ * Browser ve Node.js ortamlarında çalışan, Supsis API'sine erişim sağlayan SDK.
4021
+ *
4022
+ * @module @supsis/supsis-js
4023
+ * @version 1.0.0
4024
+ * @author Supsis <info@supsis.com>
4025
+ * @license MIT
4026
+ *
4027
+ * @example
4028
+ * // Browser (UMD)
4029
+ * const supsis = new SupsisJS({
4030
+ * email: 'user@example.com',
4031
+ * password: 'secret',
4032
+ * siteId: 'site123'
4033
+ * });
4034
+ * await supsis.connect();
4035
+ *
4036
+ * @example
4037
+ * // Node.js (CommonJS)
4038
+ * const { SupsisJS, SupsisModuleAPI } = require('@supsis/supsis-js');
4039
+ *
4040
+ * @example
4041
+ * // Node.js (ESM)
4042
+ * import { SupsisJS, SupsisModuleAPI } from '@supsis/supsis-js';
4043
+ */
4044
+
4045
+ export { AICall, Asset, BaseModule, Cache, Chat, Contact, DEFAULT_CONFIG, ENVIRONMENTS, HttpClient, Message, Module, SDK_VERSION, Site, SupsisAPIError, SupsisJS, SupsisModuleAPI, Table, Tag, Task, User, SupsisJS as default };