vantuz 3.2.4 → 3.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/channels.js CHANGED
@@ -1,44 +1,129 @@
1
1
  /**
2
- * 📱 CHANNEL MANAGER (OpenClaw)
3
- * OpenClaw Gateway entegrasyonu
2
+ * 📱 CHANNEL MANAGER v3.2
3
+ * OpenClaw Gateway üzerinden kanal yönetimi
4
4
  *
5
- * NOT: WhatsApp bağlantısı için OpenClaw Gateway CLI kullanılmalıdır:
6
- * > openclaw channels login
5
+ * Desteklenen kanallar:
6
+ * - WhatsApp (Meta Business API / Gateway)
7
+ * - Telegram (Bot API / Gateway)
7
8
  */
8
9
 
9
10
  import fs from 'fs';
10
11
  import path from 'path';
11
12
  import os from 'os';
12
13
  import { log } from './ai-provider.js';
14
+ import { getGateway } from './gateway.js';
13
15
 
14
16
  const VANTUZ_HOME = path.join(os.homedir(), '.vantuz');
15
17
  const CONFIG_PATH = path.join(VANTUZ_HOME, '.env');
16
18
 
17
19
  export class ChannelManager {
18
20
  constructor() {
21
+ this.gateway = null;
19
22
  this.status = {
20
- whatsapp: { connected: false, mode: 'gateway' },
21
- telegram: { connected: false, mode: 'gateway' }
23
+ whatsapp: { connected: false, mode: 'gateway', info: '' },
24
+ telegram: { connected: false, mode: 'gateway', info: '' }
22
25
  };
23
26
  }
24
27
 
28
+ /**
29
+ * Tüm kanalları başlat
30
+ */
25
31
  async initAll() {
26
- // OpenClaw Gateway durumunu kontrol et (varsayım)
27
- // Gerçekte Gateway ayrı bir process olarak çalışır
28
-
29
32
  const env = this._loadEnv();
30
33
 
34
+ // OpenClaw Gateway üzerinden kanal durumu kontrol et
35
+ try {
36
+ this.gateway = await getGateway();
37
+
38
+ if (this.gateway.isConnected()) {
39
+ const channelResult = await this.gateway.getChannels();
40
+ if (channelResult.success && channelResult.data) {
41
+ this._syncGatewayChannels(channelResult.data);
42
+ log('INFO', 'Kanal durumları gateway üzerinden alındı');
43
+ return this.status;
44
+ }
45
+ }
46
+ } catch (e) {
47
+ log('WARN', 'Gateway kanal kontrolü başarısız, lokal mod', { error: e.message });
48
+ }
49
+
50
+ // Fallback: Lokal env kontrolü
31
51
  if (env.TELEGRAM_BOT_TOKEN) {
32
52
  this.status.telegram.connected = true;
33
- this.status.telegram.info = 'Bot Token Configured';
53
+ this.status.telegram.info = 'Bot Token Configured (local)';
54
+ } else {
55
+ this.status.telegram.info = 'Token yapılandırılmamış';
34
56
  }
35
57
 
36
- // WhatsApp için kullanıcı manuel login olmalı
37
- this.status.whatsapp.info = 'Run "openclaw channels login" to connect';
58
+ if (env.WHATSAPP_ACCESS_TOKEN) {
59
+ this.status.whatsapp.connected = true;
60
+ this.status.whatsapp.info = 'Access Token Configured (local)';
61
+ } else {
62
+ this.status.whatsapp.info = 'Bağlanmak için: vantuz channels login';
63
+ }
38
64
 
39
65
  return this.status;
40
66
  }
41
67
 
68
+ /**
69
+ * Gateway'den gelen kanal verilerini senkronize et
70
+ */
71
+ _syncGatewayChannels(gatewayData) {
72
+ if (Array.isArray(gatewayData)) {
73
+ for (const ch of gatewayData) {
74
+ const name = ch.name?.toLowerCase();
75
+ if (name === 'whatsapp' || name === 'telegram') {
76
+ this.status[name] = {
77
+ connected: ch.connected || ch.status === 'connected',
78
+ mode: 'gateway',
79
+ info: ch.info || ch.status || 'Gateway üzerinden bağlı',
80
+ capabilities: ch.capabilities || []
81
+ };
82
+ }
83
+ }
84
+ } else if (typeof gatewayData === 'object') {
85
+ // Object format: { whatsapp: {...}, telegram: {...} }
86
+ for (const [name, data] of Object.entries(gatewayData)) {
87
+ const key = name.toLowerCase();
88
+ if (this.status[key]) {
89
+ this.status[key] = {
90
+ connected: data.connected || data.status === 'connected',
91
+ mode: 'gateway',
92
+ info: data.info || data.status || 'Gateway üzerinden bağlı',
93
+ capabilities: data.capabilities || []
94
+ };
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Mesaj gönder (gateway üzerinden)
102
+ */
103
+ async sendMessage(channel, to, message) {
104
+ if (!this.gateway?.isConnected()) {
105
+ return { success: false, error: 'Gateway bağlı değil' };
106
+ }
107
+
108
+ const result = await this.gateway.sendMessage(channel, to, message);
109
+ if (result.success) {
110
+ log('INFO', `Mesaj gönderildi: ${channel} → ${to}`);
111
+ } else {
112
+ log('ERROR', `Mesaj gönderilemedi: ${channel}`, { error: result.error });
113
+ }
114
+ return result;
115
+ }
116
+
117
+ /**
118
+ * Kanal durumunu yenile
119
+ */
120
+ async refresh() {
121
+ return await this.initAll();
122
+ }
123
+
124
+ /**
125
+ * Env dosyasını yükle
126
+ */
42
127
  _loadEnv() {
43
128
  const env = {};
44
129
  try {
@@ -55,9 +140,19 @@ export class ChannelManager {
55
140
  return env;
56
141
  }
57
142
 
143
+ /**
144
+ * Kanal durumları
145
+ */
58
146
  getStatus() {
59
147
  return this.status;
60
148
  }
149
+
150
+ /**
151
+ * Gateway bağlı mı?
152
+ */
153
+ isGatewayMode() {
154
+ return this.gateway?.isConnected() || false;
155
+ }
61
156
  }
62
157
 
63
158
  // Singleton
package/core/database.js CHANGED
@@ -1,14 +1,19 @@
1
- const { Sequelize, DataTypes } = require('sequelize');
2
- const path = require('path');
3
- const fs = require('fs');
1
+ /**
2
+ * 💾 VANTUZ DATABASE v3.2
3
+ * SQLite veritabanı - ESM modülü
4
+ */
4
5
 
5
- // Veritabanı dosyasının yolu (Kullanıcının home dizininde veya proje klasöründe)
6
- const dbPath = path.join(process.cwd(), 'vantuz.sqlite');
6
+ import { Sequelize, DataTypes } from 'sequelize';
7
+ import path from 'path';
8
+ import os from 'os';
9
+
10
+ const VANTUZ_HOME = path.join(os.homedir(), '.vantuz');
11
+ const dbPath = path.join(VANTUZ_HOME, 'vantuz.sqlite');
7
12
 
8
13
  const sequelize = new Sequelize({
9
14
  dialect: 'sqlite',
10
15
  storage: dbPath,
11
- logging: false // Konsolu kirletmesin
16
+ logging: false
12
17
  });
13
18
 
14
19
  // --- MODELLER ---
@@ -16,8 +21,8 @@ const sequelize = new Sequelize({
16
21
  // Mağaza Ayarları (API Keyler vb.)
17
22
  const Store = sequelize.define('Store', {
18
23
  name: { type: DataTypes.STRING, allowNull: false },
19
- platform: { type: DataTypes.STRING, allowNull: false }, // trendyol, amazon, etc.
20
- credentials: { type: DataTypes.JSON, allowNull: false }, // { apiKey: '...', apiSecret: '...' }
24
+ platform: { type: DataTypes.STRING, allowNull: false },
25
+ credentials: { type: DataTypes.JSON, allowNull: false },
21
26
  isActive: { type: DataTypes.BOOLEAN, defaultValue: true }
22
27
  });
23
28
 
@@ -28,9 +33,9 @@ const Product = sequelize.define('Product', {
28
33
  sku: { type: DataTypes.STRING },
29
34
  description: { type: DataTypes.TEXT },
30
35
  brand: { type: DataTypes.STRING },
31
- images: { type: DataTypes.JSON }, // Resim URL'leri listesi
32
- marketData: { type: DataTypes.JSON }, // { trendyol: { price: 100, stock: 10 }, amazon: { ... } }
33
- aiAnalysis: { type: DataTypes.TEXT } // AI tarafından üretilen satış önerileri
36
+ images: { type: DataTypes.JSON },
37
+ marketData: { type: DataTypes.JSON },
38
+ aiAnalysis: { type: DataTypes.TEXT }
34
39
  });
35
40
 
36
41
  // Siparişler
@@ -42,21 +47,21 @@ const Order = sequelize.define('Order', {
42
47
  currency: { type: DataTypes.STRING, defaultValue: 'TRY' },
43
48
  status: { type: DataTypes.STRING },
44
49
  orderDate: { type: DataTypes.DATE },
45
- items: { type: DataTypes.JSON } // Sipariş içeriği
50
+ items: { type: DataTypes.JSON }
46
51
  });
47
52
 
48
- // Loglar ve AI Önerileri
53
+ // AI Önerileri
49
54
  const Insight = sequelize.define('Insight', {
50
- type: { type: DataTypes.STRING }, // 'pricing', 'stock', 'trend'
55
+ type: { type: DataTypes.STRING },
51
56
  message: { type: DataTypes.TEXT },
52
- priority: { type: DataTypes.INTEGER }, // 1: Düşük, 5: Kritik
57
+ priority: { type: DataTypes.INTEGER },
53
58
  isRead: { type: DataTypes.BOOLEAN, defaultValue: false }
54
59
  });
55
60
 
56
61
  // Veritabanını Başlat
57
- async function initDB() {
62
+ export async function initDB() {
58
63
  try {
59
- await sequelize.sync({ alter: true }); // Tabloları güncelle
64
+ await sequelize.sync({ alter: true });
60
65
  return true;
61
66
  } catch (error) {
62
67
  console.error('Veritabanı hatası:', error);
@@ -64,11 +69,5 @@ async function initDB() {
64
69
  }
65
70
  }
66
71
 
67
- module.exports = {
68
- sequelize,
69
- Store,
70
- Product,
71
- Order,
72
- Insight,
73
- initDB
74
- };
72
+ export { sequelize, Store, Product, Order, Insight };
73
+ export default { sequelize, Store, Product, Order, Insight, initDB };
package/core/engine.js CHANGED
@@ -1,8 +1,9 @@
1
1
  /**
2
- * 🐙 VANTUZ ENGINE v3.1
2
+ * 🐙 VANTUZ ENGINE v3.2
3
3
  * Merkezi motor - Tüm sistemleri yönetir
4
4
  *
5
- * OpenClaw altyapısı üzerine kurulu, Vantuz olarak özelleştirilmiş
5
+ * Vantuz Gateway üzerinden güçlendirilmiş altyapı
6
+ * Entegre Tool Sistemi
6
7
  */
7
8
 
8
9
  import fs from 'fs';
@@ -10,14 +11,21 @@ import path from 'path';
10
11
  import os from 'os';
11
12
 
12
13
  // Platform Hub
13
- import platformHub, {
14
- trendyolApi,
15
- hepsiburadaApi,
16
- n11Api
17
- } from '../plugins/vantuz/platforms/index.js';
18
-
19
- // AI Provider
20
- import { chat as aiChat, log, getLogs } from './ai-provider.js';
14
+ import platformHub from '../plugins/vantuz/platforms/index.js';
15
+
16
+ // AI Provider & Gateway
17
+ import { getChannelManager } from './channels.js';
18
+ import { chat as aiChat, log } from './ai-provider.js';
19
+ import { getGateway } from './gateway.js';
20
+
21
+ // Tools
22
+ import { repricerTool } from '../plugins/vantuz/tools/repricer.js';
23
+ import { visionTool } from '../plugins/vantuz/tools/vision.js';
24
+ import { sentimentTool } from '../plugins/vantuz/tools/sentiment.js';
25
+ import { crossborderTool } from '../plugins/vantuz/tools/crossborder.js';
26
+ import { productTool } from '../plugins/vantuz/tools/product.js';
27
+ import { analyticsTool } from '../plugins/vantuz/tools/analytics.js';
28
+ import { quickReportTool } from '../plugins/vantuz/tools/quick-report.js';
21
29
 
22
30
  // ═══════════════════════════════════════════════════════════════════════════
23
31
  // CONFIG
@@ -26,7 +34,6 @@ import { chat as aiChat, log, getLogs } from './ai-provider.js';
26
34
  const VANTUZ_HOME = path.join(os.homedir(), '.vantuz');
27
35
  const CONFIG_PATH = path.join(VANTUZ_HOME, '.env');
28
36
  const CONFIG_JSON = path.join(VANTUZ_HOME, 'config.json');
29
- const DB_PATH = path.join(VANTUZ_HOME, 'vantuz.db');
30
37
 
31
38
  // ═══════════════════════════════════════════════════════════════════════════
32
39
  // ENGINE CLASS
@@ -38,24 +45,48 @@ export class VantuzEngine {
38
45
  this.config = {};
39
46
  this.env = {};
40
47
  this.platforms = {};
41
- this.channels = {};
48
+ this.channels = null;
49
+ this.gateway = null;
42
50
  this.context = {
43
51
  products: [],
44
- orders: [],
45
52
  connectedPlatforms: []
46
53
  };
54
+
55
+ // Tool Registry
56
+ this.tools = {
57
+ repricer: repricerTool,
58
+ vision: visionTool,
59
+ sentiment: sentimentTool,
60
+ crossborder: crossborderTool,
61
+ product: productTool,
62
+ analytics: analyticsTool,
63
+ quickReport: quickReportTool
64
+ };
47
65
  }
48
66
 
49
67
  /**
50
68
  * Engine'i başlat
51
69
  */
52
70
  async initialize() {
53
- log('INFO', 'Vantuz Engine başlatılıyor...');
71
+ log('INFO', 'Vantuz Engine v3.2 başlatılıyor...');
54
72
 
55
73
  // Config ve env yükle
56
74
  this._loadConfig();
57
75
  this._loadEnv();
58
76
 
77
+ // Vantuz Gateway bağlantısı
78
+ try {
79
+ this.gateway = await getGateway();
80
+ if (this.gateway.isConnected()) {
81
+ log('INFO', 'Vantuz Gateway bağlı', this.gateway.getInfo());
82
+ }
83
+ } catch (e) {
84
+ log('WARN', 'Gateway bağlantısı başarısız, direkt mod', { error: e.message });
85
+ }
86
+
87
+ // Channel Manager'ı başlat
88
+ this.channels = await getChannelManager();
89
+
59
90
  // Platform Hub'ı başlat
60
91
  await this._initPlatforms();
61
92
 
@@ -64,7 +95,8 @@ export class VantuzEngine {
64
95
 
65
96
  this.initialized = true;
66
97
  log('INFO', 'Vantuz Engine hazır', {
67
- platforms: this.context.connectedPlatforms.length
98
+ platforms: this.context.connectedPlatforms.length,
99
+ gateway: this.gateway?.isConnected() || false
68
100
  });
69
101
 
70
102
  return this;
@@ -108,36 +140,27 @@ export class VantuzEngine {
108
140
  async _initPlatforms() {
109
141
  const platformConfig = {};
110
142
 
111
- // Trendyol
112
- if (this.env.TRENDYOL_API_KEY && this.env.TRENDYOL_SUPPLIER_ID) {
143
+ // Otomatik config eşleme
144
+ if (this.env.TRENDYOL_API_KEY) {
113
145
  platformConfig.trendyol = {
114
146
  supplierId: this.env.TRENDYOL_SUPPLIER_ID,
115
147
  apiKey: this.env.TRENDYOL_API_KEY,
116
148
  apiSecret: this.env.TRENDYOL_API_SECRET
117
149
  };
118
- log('INFO', 'Trendyol config hazır');
119
150
  }
120
-
121
- // Hepsiburada
122
151
  if (this.env.HEPSIBURADA_MERCHANT_ID) {
123
152
  platformConfig.hepsiburada = {
124
153
  merchantId: this.env.HEPSIBURADA_MERCHANT_ID,
125
154
  username: this.env.HEPSIBURADA_USERNAME,
126
155
  password: this.env.HEPSIBURADA_PASSWORD
127
156
  };
128
- log('INFO', 'Hepsiburada config hazır');
129
157
  }
130
-
131
- // N11
132
158
  if (this.env.N11_API_KEY) {
133
159
  platformConfig.n11 = {
134
160
  apiKey: this.env.N11_API_KEY,
135
161
  apiSecret: this.env.N11_API_SECRET
136
162
  };
137
- log('INFO', 'N11 config hazır');
138
163
  }
139
-
140
- // Amazon
141
164
  if (this.env.AMAZON_SELLER_ID) {
142
165
  platformConfig.amazon = {
143
166
  eu: {
@@ -148,29 +171,6 @@ export class VantuzEngine {
148
171
  };
149
172
  }
150
173
 
151
- // Çiçeksepeti
152
- if (this.env.CICEKSEPETI_API_KEY) {
153
- platformConfig.ciceksepeti = {
154
- apiKey: this.env.CICEKSEPETI_API_KEY
155
- };
156
- }
157
-
158
- // PTTavm
159
- if (this.env.PTTAVM_API_KEY) {
160
- platformConfig.pttavm = {
161
- apiKey: this.env.PTTAVM_API_KEY,
162
- token: this.env.PTTAVM_TOKEN
163
- };
164
- }
165
-
166
- // Pazarama
167
- if (this.env.PAZARAMA_CLIENT_ID) {
168
- platformConfig.pazarama = {
169
- clientId: this.env.PAZARAMA_CLIENT_ID,
170
- clientSecret: this.env.PAZARAMA_CLIENT_SECRET
171
- };
172
- }
173
-
174
174
  // Platform Hub'ı başlat
175
175
  if (Object.keys(platformConfig).length > 0) {
176
176
  this.platforms = await platformHub.initAll(platformConfig);
@@ -186,7 +186,6 @@ export class VantuzEngine {
186
186
  async _buildContext() {
187
187
  this.context.connectedPlatforms = platformHub.getConnected();
188
188
 
189
- // Her bağlı platformdan temel veri çek
190
189
  for (const platform of this.context.connectedPlatforms) {
191
190
  try {
192
191
  const api = platformHub.resolve(platform);
@@ -198,7 +197,6 @@ export class VantuzEngine {
198
197
  ...p,
199
198
  _platform: platform
200
199
  })));
201
- log('INFO', `${platform} ürünleri çekildi`, { count: products.length });
202
200
  }
203
201
  }
204
202
  } catch (e) {
@@ -208,52 +206,52 @@ export class VantuzEngine {
208
206
  }
209
207
 
210
208
  /**
211
- * Güncel context al
209
+ * AI ile sohbet - Tool destekli
212
210
  */
213
- getContext() {
214
- return {
215
- connectedPlatforms: this.context.connectedPlatforms,
216
- productCount: this.context.products.length,
217
- platforms: platformHub.getStatus(),
218
- aiProvider: this.config.aiProvider || 'gemini'
219
- };
220
- }
211
+ async chat(message) {
212
+ if (!this.initialized) await this.initialize();
221
213
 
222
- /**
223
- * Platform durumu
224
- */
225
- getStatus() {
226
- const status = platformHub.getStatus();
227
- const connected = this.context.connectedPlatforms;
214
+ // 1. Basit komut kontrolü (Tool çağırma)
215
+ const toolResult = await this._tryExecuteToolFromMessage(message);
216
+ if (toolResult) return toolResult;
228
217
 
229
- return {
230
- engine: this.initialized ? 'active' : 'inactive',
231
- aiProvider: this.config.aiProvider,
232
- platforms: status,
233
- connectedCount: connected.length,
234
- totalPlatforms: 7,
235
- productCount: this.context.products.length
218
+ // 2. Gateway üzerinden AI (Eğer varsa)
219
+ if (this.gateway?.isConnected()) {
220
+ try {
221
+ const gatewayResult = await this.gateway.chat(message, {
222
+ systemPrompt: this._buildContextInfo()
223
+ });
224
+ if (gatewayResult.success) return gatewayResult.response;
225
+ } catch (e) { }
226
+ }
227
+
228
+ // 3. Direkt API (Fallback)
229
+ const enrichedConfig = {
230
+ ...this.config,
231
+ systemContext: this._buildContextInfo()
236
232
  };
233
+
234
+ return await aiChat(message, enrichedConfig, this.env);
237
235
  }
238
236
 
239
237
  /**
240
- * AI ile sohbet - context ile zenginleştirilmiş
238
+ * Mesajdan Tool tespiti (Basit NLP)
241
239
  */
242
- async chat(message) {
243
- if (!this.initialized) {
244
- await this.initialize();
245
- }
240
+ async _tryExecuteToolFromMessage(message) {
241
+ const lower = message.toLowerCase();
246
242
 
247
- // Context bilgisi oluştur
248
- const contextInfo = this._buildContextInfo();
243
+ // Repricer
244
+ if (lower.includes('fiyat analizi') || lower.includes('rakip analizi')) {
245
+ return "Repricer aracı çalıştırılıyor... (Detaylı parametreler için /rakip komutunu kullanın)";
246
+ }
249
247
 
250
- // AI'ya gönder
251
- const enrichedConfig = {
252
- ...this.config,
253
- systemContext: contextInfo
254
- };
248
+ // Stok
249
+ if (lower.includes('stok durumu')) {
250
+ const stocks = await this.getStock();
251
+ return JSON.stringify(stocks.map(s => ({ platform: s.platform, items: s.products.length })), null, 2);
252
+ }
255
253
 
256
- return await aiChat(message, enrichedConfig, this.env);
254
+ return null;
257
255
  }
258
256
 
259
257
  /**
@@ -261,25 +259,22 @@ export class VantuzEngine {
261
259
  */
262
260
  _buildContextInfo() {
263
261
  const connected = this.context.connectedPlatforms;
264
- const status = platformHub.getStatus();
265
-
266
- let info = `\n\n--- MEVCUT DURUM ---\n`;
262
+ let info = `\n\n--- MEVCUT SİSTEM DURUMU ---\n`;
267
263
  info += `Bağlı Platformlar: ${connected.length > 0 ? connected.join(', ') : 'Hiçbiri'}\n`;
268
- info += `Toplam Ürün: ${this.context.products.length}\n`;
264
+ info += `Gateway: ${this.gateway?.isConnected() ? 'BAĞLI' : 'KOPUK'}\n`;
265
+ info += `Mevcut Toollar: Repricer, Vision, Sentiment, Analytics, CrossBorder\n`;
269
266
 
270
267
  if (this.context.products.length > 0) {
271
268
  info += `\nÖrnek Ürünler:\n`;
272
- this.context.products.slice(0, 5).forEach(p => {
273
- info += `- ${p.title || p.name || p.barcode} (${p._platform}): ${p.salePrice || p.price} TL, Stok: ${p.quantity || p.stock || 'N/A'}\n`;
269
+ this.context.products.slice(0, 3).forEach(p => {
270
+ info += `- ${p.title} (${p._platform}): ${p.salePrice} TL\n`;
274
271
  });
275
272
  }
276
-
277
273
  return info;
278
274
  }
279
275
 
280
- /**
281
- * Stok bilgisi al
282
- */
276
+ // --- Helper Methods ---
277
+
283
278
  async getStock(platform = 'all') {
284
279
  const results = [];
285
280
  const targets = platform === 'all'
@@ -309,53 +304,48 @@ export class VantuzEngine {
309
304
  log('ERROR', `Stok çekme hatası: ${p}`, { error: e.message });
310
305
  }
311
306
  }
312
-
313
307
  return results;
314
308
  }
315
309
 
316
- /**
317
- * Sipariş bilgisi al
318
- */
319
310
  async getOrders(params = {}) {
320
311
  return await platformHub.getAllOrders(params);
321
312
  }
322
313
 
323
- /**
324
- * Fiyat güncelle
325
- */
326
- async updatePrice(barcode, price, platforms = 'all') {
327
- log('INFO', 'Fiyat güncelleme', { barcode, price, platforms });
328
- return await platformHub.updatePriceMulti(barcode, price, platforms);
329
- }
314
+ getStatus() {
315
+ const status = platformHub.getStatus();
316
+ const connected = this.context.connectedPlatforms;
317
+ const channelStatus = this.channels ? this.channels.getStatus() : {};
318
+ const gatewayInfo = this.gateway ? this.gateway.getInfo() : { connected: false };
330
319
 
331
- /**
332
- * Stok güncelle
333
- */
334
- async updateStock(barcode, quantity, platforms = 'all') {
335
- log('INFO', 'Stok güncelleme', { barcode, quantity, platforms });
336
- return await platformHub.updateStockMulti(barcode, quantity, platforms);
320
+ return {
321
+ engine: this.initialized ? 'active' : 'inactive',
322
+ version: '3.2',
323
+ aiProvider: this.config.aiProvider || 'gemini',
324
+ gateway: gatewayInfo,
325
+ platforms: status,
326
+ channels: channelStatus,
327
+ connectedCount: connected.length,
328
+ totalPlatforms: 7,
329
+ productCount: this.context.products.length
330
+ };
337
331
  }
338
332
 
339
- /**
340
- * Platform bağlantı testi
341
- */
342
- async testConnections() {
343
- const results = {};
344
-
345
- for (const [name, api] of Object.entries(this.platforms)) {
346
- try {
347
- if (api?.testConnection) {
348
- results[name] = await api.testConnection();
349
- } else {
350
- results[name] = api?.isConnected?.() || false;
351
- }
352
- } catch (e) {
353
- results[name] = false;
354
- log('ERROR', `Bağlantı testi başarısız: ${name}`, { error: e.message });
355
- }
356
- }
357
-
358
- return results;
333
+ async doctor() {
334
+ const status = this.getStatus();
335
+ return {
336
+ engine: this.initialized,
337
+ gateway: {
338
+ status: status.gateway.connected ? 'healthy' : 'unreachable',
339
+ ...status.gateway
340
+ },
341
+ platforms: status.platforms,
342
+ ai: {
343
+ provider: status.aiProvider,
344
+ keyConfigured: true,
345
+ gatewayFallback: status.gateway.connected
346
+ },
347
+ channels: status.channels
348
+ };
359
349
  }
360
350
  }
361
351