@supsis/supsis-js 1.0.0

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