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