vantuz 4.0.0 → 4.0.3

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.
Files changed (88) hide show
  1. package/cli.js +9 -9
  2. package/config.js +6 -6
  3. package/core/agent-loop.js +6 -6
  4. package/core/agent.js +6 -6
  5. package/core/ai-copilot.js +461 -0
  6. package/core/ai-provider.js +60 -10
  7. package/core/automation.js +8 -8
  8. package/core/cache-manager.js +232 -0
  9. package/core/channels.js +8 -8
  10. package/core/dashboard.js +5 -5
  11. package/core/database-manager.js +331 -0
  12. package/core/database.js +124 -83
  13. package/core/eia-brain.js +2 -2
  14. package/core/eia-monitor.js +7 -7
  15. package/core/engine.js +24 -24
  16. package/core/error-handler.js +203 -0
  17. package/core/gateway.js +9 -9
  18. package/core/learning.js +7 -7
  19. package/core/license-manager.js +1 -1
  20. package/core/license.js +6 -6
  21. package/core/logger.js +228 -0
  22. package/core/marketplace-adapter.js +5 -5
  23. package/core/memory.js +6 -6
  24. package/core/multi-agent.js +180 -0
  25. package/core/openclaw-bridge.js +6 -6
  26. package/core/queue.js +3 -3
  27. package/core/scheduler.js +6 -6
  28. package/core/scrapers/Scraper.js +1 -1
  29. package/core/scrapers/TrendyolScraper.js +1 -1
  30. package/core/self-healer.js +8 -6
  31. package/core/unified-product.js +8 -8
  32. package/core/vector-db.js +5 -5
  33. package/core/vision-service.js +5 -5
  34. package/desktop/index.html +2804 -0
  35. package/desktop/main.js +97 -0
  36. package/desktop/preload.js +30 -0
  37. package/dev.sh +5 -0
  38. package/index.js +483 -115
  39. package/modules/crm/sentiment-crm.js +4 -4
  40. package/modules/healer/listing-healer.js +2 -2
  41. package/modules/oracle/predictor.js +5 -5
  42. package/modules/researcher/agent.js +4 -4
  43. package/modules/war-room/competitor-tracker.js +5 -5
  44. package/modules/war-room/pricing-engine.js +5 -5
  45. package/nodes/warehouse.js +5 -5
  46. package/onboard.js +1 -1
  47. package/package.json +11 -3
  48. package/pkg.json +26 -0
  49. package/plugins/vantuz/index.js +16 -17
  50. package/plugins/vantuz/memory/hippocampus.js +3 -3
  51. package/plugins/vantuz/platforms/_request.js +1 -1
  52. package/plugins/vantuz/platforms/_template.js +2 -2
  53. package/plugins/vantuz/platforms/amazon.js +3 -3
  54. package/plugins/vantuz/platforms/ciceksepeti.js +2 -2
  55. package/plugins/vantuz/platforms/hepsiburada.js +2 -2
  56. package/plugins/vantuz/platforms/index.js +9 -24
  57. package/plugins/vantuz/platforms/n11.js +3 -3
  58. package/plugins/vantuz/platforms/pazarama.js +2 -2
  59. package/plugins/vantuz/platforms/pttavm.js +2 -2
  60. package/plugins/vantuz/platforms/trendyol.js +3 -3
  61. package/plugins/vantuz/services/alerts.js +1 -1
  62. package/plugins/vantuz/services/scheduler.js +1 -1
  63. package/plugins/vantuz/tools/nl-parser.js +1 -1
  64. package/plugins/vantuz/tools/quick-report.js +2 -2
  65. package/plugins/vantuz/tools/repricer.js +1 -1
  66. package/plugins/vantuz/tools/vision.js +3 -3
  67. package/server/app.js +8 -8
  68. package/DOCS_TR.md +0 -80
  69. package/modules/team/agents/base.js +0 -92
  70. package/modules/team/agents/dev.js +0 -33
  71. package/modules/team/agents/josh.js +0 -40
  72. package/modules/team/agents/marketing.js +0 -33
  73. package/modules/team/agents/milo.js +0 -36
  74. package/modules/team/index.js +0 -78
  75. package/modules/team/shared-memory.js +0 -87
  76. package/n11docs.md +0 -1680
  77. package/openclawdocs.md +0 -3
  78. package/vantuz.sqlite +0 -0
  79. package/workspace/AGENTS.md +0 -73
  80. package/workspace/BRAND.md +0 -29
  81. package/workspace/SOUL.md +0 -72
  82. package/workspace/team/DECISIONS.md +0 -3
  83. package/workspace/team/GOALS.md +0 -3
  84. package/workspace/team/PROJECT_STATUS.md +0 -3
  85. package/workspace/team/agents/dev/SOUL.md +0 -12
  86. package/workspace/team/agents/josh/SOUL.md +0 -12
  87. package/workspace/team/agents/marketing/SOUL.md +0 -12
  88. package/workspace/team/agents/milo/SOUL.md +0 -12
package/index.js CHANGED
@@ -1,5 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ /**
4
+ * 🐙 VANTUZ v4.0 - E-Ticaret Yönetim Platformu
5
+ * Stabilite ve Genel İyileştirmeler ile Güncellenmiş Versiyon
6
+ */
7
+
8
+ // --- YENİ İMPORTLAR (Stabilite İyileştirmeleri) ---
3
9
  const fs = require('fs');
4
10
  const { execSync } = require('child_process');
5
11
  const clear = require('console-clear');
@@ -9,10 +15,59 @@ const inquirer = require('inquirer');
9
15
  const boxen = require('boxen');
10
16
  const ora = require('ora');
11
17
  const Conf = require('conf');
18
+ const http = require('http');
19
+ const { URL } = require('url');
20
+
21
+ // --- YENİ STABİLİTE MODÜLLERİ ---
22
+ const logger = require('./core/logger');
23
+ const { setupGracefulShutdown, withErrorHandler, withTimeout, APITimeoutHandler } = require('./core/error-handler');
24
+ const { globalCache, debounce, createLazyLoader } = require('./core/cache-manager');
25
+ const { DatabaseManager, scheduleDailyBackup } = require('./core/database-manager');
26
+
27
+ // --- MEVCUT MODÜLLER ---
12
28
  const db = require('./core/database');
13
29
  const licenseManager = require('./core/license-manager');
30
+ const productManager = require('./core/product-manager');
31
+ const brandAnalyst = require('./core/brand-analyst');
32
+ const { getCopilot, getCopilotFunctions } = require('./core/ai-copilot');
14
33
  const pkg = require('./package.json');
15
34
 
35
+ // Session tracking
36
+ process.env.SESSION_START = Date.now();
37
+ process.env.SESSION_ID = `session-${Date.now()}`;
38
+ logger.startSession(process.env.SESSION_ID);
39
+
40
+ const config = new Conf({ projectName: 'vantuz' });
41
+ const DEFAULT_API_PORT = process.env.VANTUZ_API_PORT || 3131;
42
+ const apiTimeout = new APITimeoutHandler(30000); // 30s default timeout
43
+
44
+ // --- DATABASE MANAGER BAŞLATICI ---
45
+ let dbManager = null;
46
+ async function initDatabaseManager() {
47
+ try {
48
+ await db.initDB();
49
+ dbManager = new DatabaseManager(db, require('./core/database').dbPath || require('path').join(process.cwd(), 'vantuz.sqlite'));
50
+
51
+ // Auto-migration
52
+ await dbManager.runMigrations();
53
+
54
+ // Bütünlük kontrolü
55
+ const integrity = await dbManager.checkIntegrity();
56
+ if (!integrity.valid) {
57
+ logger.warn('Veri bütünlüğü sorunları tespit edildi', { issues: integrity.issues });
58
+ }
59
+
60
+ // Günlük backup planla
61
+ scheduleDailyBackup(dbManager, 3, 0); // Her gece 03:00
62
+
63
+ logger.info('Database Manager başlatıldı');
64
+ return dbManager;
65
+ } catch (error) {
66
+ logger.error('Database Manager başlatma hatası', { error: error.message });
67
+ return null;
68
+ }
69
+ }
70
+
16
71
  // --- BASİT KOMUT SATIRI ARGÜMANLARI ---
17
72
  const args = process.argv.slice(2);
18
73
 
@@ -27,19 +82,13 @@ if (args.includes('--upgrade') || args.includes('-U')) {
27
82
  console.log(chalk.yellow(' 🚀 Güncelleme Kontrol Ediliyor...\n'));
28
83
 
29
84
  try {
30
- // Check current version
31
85
  const currentVersion = pkg.version;
32
-
33
- // Run upgrade
34
86
  console.log(chalk.cyan(' 📦 En güncel paketler indiriliyor...'));
35
87
  execSync('npm install -g vantuz@latest', { stdio: 'pipe' });
36
-
37
- // Show success
38
88
  console.log(chalk.green(' ✅ Tüm paketler güncellendi!'));
39
89
  console.log(chalk.white('\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
40
90
  console.log(chalk.green(' 🎉 Vantuz ' + currentVersion + ' → ' + pkg.version + ' başarıyla yükseltildi!'));
41
91
  console.log(chalk.white(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
42
-
43
92
  } catch(e) {
44
93
  console.log(chalk.red(' ❌ Güncelleme sırasında hata oluştu:'));
45
94
  console.log(chalk.gray(' ' + e.message));
@@ -47,43 +96,350 @@ if (args.includes('--upgrade') || args.includes('-U')) {
47
96
  process.exit(0);
48
97
  }
49
98
 
50
- // ... (Diğer importlar aynı) ...
51
- const productManager = require('./core/product-manager');
52
- const brandAnalyst = require('./core/brand-analyst');
53
- const platforms = {
54
- trendyol: require('./platforms/trendyol')
55
- };
99
+ // --- YARDIM KOMUTU ---
100
+ if (args.includes('--help') || args.includes('-h')) {
101
+ clear();
102
+ console.log(chalk.cyan(figlet.textSync('VANTUZ', { horizontalLayout: 'full' })));
103
+ console.log(chalk.white(`
104
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
105
+ 🐙 E-Ticaretin Yapay Zeka Beyni
106
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
107
+
108
+ Kullanım: vantuz [komut] [seçenekler]
109
+
110
+ Komutlar:
111
+ (boş) Interaktif mod başlat
112
+ --api API server modu başlat
113
+ --version Versiyon göster
114
+ --upgrade Paketi güncelle
115
+ --help Bu yardımı göster
116
+
117
+ Seçenekler:
118
+ --port <p> API port (varsayılan: 3131)
119
+ --debug Debug modu
120
+
121
+ Interaktif Mod Komutları:
122
+ /orders Sipariş yönetimi
123
+ /products Ürün & Stok (Vision AI)
124
+ /analytics Pazar analizi
125
+ /chat AI Takımı ile sohbet
126
+ /stores Mağazalarım
127
+ /settings Ayarlar
128
+ /exit Çıkış
129
+
130
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
131
+ `));
132
+ process.exit(0);
133
+ }
56
134
 
57
- const config = new Conf({ projectName: 'vantuz' });
135
+ // --- YENİ: CACHE İSTATİSTİKLERİ ---
136
+ if (args.includes('--cache-stats')) {
137
+ const stats = globalCache.getStats();
138
+ console.log(chalk.cyan('📊 Cache İstatistikleri:'));
139
+ console.log(JSON.stringify(stats, null, 2));
140
+ process.exit(0);
141
+ }
142
+
143
+ // --- YENİ: BACKUP OLUŞTUR ---
144
+ if (args.includes('--backup')) {
145
+ clear();
146
+ console.log(chalk.cyan('💾 Backup Oluşturuluyor...'));
147
+ initDatabaseManager().then(async (mgr) => {
148
+ if (mgr) {
149
+ const result = await mgr.createBackup('manual');
150
+ if (result.success) {
151
+ console.log(chalk.green(`✅ Backup oluşturuldu: ${result.file}`));
152
+ } else {
153
+ console.log(chalk.red(`❌ Backup hatası: ${result.error}`));
154
+ }
155
+ }
156
+ process.exit(0);
157
+ });
158
+ }
159
+
160
+ // --- YENİ: SİSTEM KONTROLÜ ---
161
+ if (args.includes('--doctor') || args.includes('--check')) {
162
+ clear();
163
+ console.log(chalk.cyan(figlet.textSync('VANTUZ', { horizontalLayout: 'full' })));
164
+ console.log(chalk.yellow(' 🔍 Sistem Sağlık Kontrolü\n'));
165
+
166
+ const checks = [
167
+ { name: 'Veritabanı', check: async () => {
168
+ try {
169
+ await db.initDB();
170
+ return { status: 'ok', info: 'Bağlantı başarılı' };
171
+ } catch (e) {
172
+ return { status: 'error', info: e.message };
173
+ }
174
+ }},
175
+ { name: 'Cache', check: async () => {
176
+ const stats = globalCache.getStats();
177
+ return { status: 'ok', info: `Hit Rate: ${stats.hitRate}` };
178
+ }},
179
+ { name: 'Logs', check: async () => {
180
+ const logs = logger.getLogs(5);
181
+ return { status: 'ok', info: `${logs.length} son log` };
182
+ }}
183
+ ];
184
+
185
+ (async () => {
186
+ for (const check of checks) {
187
+ const spinner = ora(`${check.name} kontrol ediliyor...`).start();
188
+ try {
189
+ const result = await check.check();
190
+ spinner.succeed(`${check.name}: ${result.status === 'ok' ? '✅' : '❌'} ${result.info}`);
191
+ } catch (e) {
192
+ spinner.fail(`${check.name}: ❌ ${e.message}`);
193
+ }
194
+ }
195
+ console.log(chalk.gray('\n Tam rapor için vantuz doctor'));
196
+ process.exit(0);
197
+ })();
198
+ }
199
+
200
+ // --- API HELPERS (Timeout ile) ---
201
+ function sendJson(res, status, payload) {
202
+ res.statusCode = status;
203
+ res.setHeader('Content-Type', 'application/json; charset=utf-8');
204
+ res.end(JSON.stringify(payload));
205
+ }
206
+
207
+ async function parseBody(req) {
208
+ return new Promise((resolve, reject) => {
209
+ let body = '';
210
+ req.on('data', chunk => { body += chunk; });
211
+ req.on('end', () => {
212
+ if (!body) return resolve({});
213
+ try {
214
+ resolve(JSON.parse(body));
215
+ } catch (e) {
216
+ reject(new Error('Geçersiz JSON'));
217
+ }
218
+ });
219
+ });
220
+ }
221
+
222
+ // --- LAZY LOADERS ---
223
+ const statsLoader = createLazyLoader(async () => {
224
+ logger.debug('Stats yükleniyor (lazy)');
225
+ const orders = await db.Order.findAll();
226
+ const revenue = orders.reduce((sum, order) => sum + (Number(order.totalAmount) || 0), 0);
227
+ const products = await db.Product.count();
228
+ const stores = await db.Store.count();
229
+ return { orders: orders.length, revenue, products, stores };
230
+ });
231
+
232
+ const ordersLoader = createLazyLoader(async () => {
233
+ logger.debug('Siparişler yükleniyor (lazy)');
234
+ return await db.Order.findAll();
235
+ });
236
+
237
+ const productsLoader = createLazyLoader(async () => {
238
+ logger.debug('Ürünler yükleniyor (lazy)');
239
+ return await db.Product.findAll();
240
+ });
241
+
242
+ // --- DEBOUNCED API CALLS ---
243
+ const debouncedStatsRefresh = debounce(async () => {
244
+ logger.info('Debounced stats refresh tetiklendi');
245
+ statsLoader.refresh();
246
+ }, 500);
247
+
248
+ // --- API SERVER ---
249
+ async function startApiServer(options = {}) {
250
+ const port = options.port || DEFAULT_API_PORT;
251
+
252
+ await initDatabaseManager();
253
+ await db.initDB();
254
+
255
+ const server = http.createServer(async (req, res) => {
256
+ const requestUrl = new URL(req.url, `http://${req.headers.host}`);
257
+ const { pathname } = requestUrl;
258
+
259
+ if (!pathname.startsWith('/api')) {
260
+ res.statusCode = 404;
261
+ return res.end('Not Found');
262
+ }
263
+
264
+ // CORS headers
265
+ res.setHeader('Access-Control-Allow-Origin', '*');
266
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
267
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
268
+
269
+ if (req.method === 'OPTIONS') {
270
+ res.statusCode = 204;
271
+ return res.end();
272
+ }
273
+
274
+ try {
275
+ // --- /api/stats (Cache ile) ---
276
+ if (req.method === 'GET' && pathname === '/api/stats') {
277
+ const stats = await statsLoader.get();
278
+ return sendJson(res, 200, stats);
279
+ }
280
+
281
+ // --- /api/stats/refresh ---
282
+ if (req.method === 'POST' && pathname === '/api/stats/refresh') {
283
+ debouncedStatsRefresh();
284
+ return sendJson(res, 200, { message: 'Refresh tetiklendi' });
285
+ }
286
+
287
+ // --- /api/orders (Lazy load) ---
288
+ if (req.method === 'GET' && pathname === '/api/orders') {
289
+ const orders = await ordersLoader.get();
290
+ return sendJson(res, 200, orders);
291
+ }
292
+
293
+ // --- /api/products (Lazy load) ---
294
+ if (req.method === 'GET' && pathname === '/api/products') {
295
+ const products = await productsLoader.get();
296
+ return sendJson(res, 200, products);
297
+ }
298
+
299
+ // --- /api/stores ---
300
+ if (req.method === 'GET' && pathname === '/api/stores') {
301
+ const stores = await withTimeout(
302
+ db.Store.findAll(),
303
+ 10000,
304
+ 'Store Query'
305
+ );
306
+ return sendJson(res, 200, stores);
307
+ }
58
308
 
59
- // --- GİZLİ ADMIN MODU ---
60
- // KODDAN SİLİNDİ. Lisans üretimi harici araçla yapılır.
309
+ // --- /api/cache/stats ---
310
+ if (req.method === 'GET' && pathname === '/api/cache/stats') {
311
+ return sendJson(res, 200, globalCache.getStats());
312
+ }
313
+
314
+ // --- /api/cache/clear ---
315
+ if (req.method === 'POST' && pathname === '/api/cache/clear') {
316
+ globalCache.clear();
317
+ statsLoader.refresh();
318
+ ordersLoader.refresh();
319
+ productsLoader.refresh();
320
+ return sendJson(res, 200, { message: 'Cache temizlendi' });
321
+ }
322
+
323
+ // --- /api/chat (Timeout ile) ---
324
+ if (req.method === 'POST' && pathname === '/api/chat') {
325
+ const body = await parseBody(req);
326
+ const message = (body.message || '').toString().trim();
327
+ if (!message) return sendJson(res, 400, { error: 'Mesaj gerekli' });
328
+
329
+ const response = await apiTimeout.request(async () => {
330
+ const lower = message.toLowerCase();
331
+ const [orderCount, productCount, storeCount] = await Promise.all([
332
+ db.Order.count(),
333
+ db.Product.count(),
334
+ db.Store.count()
335
+ ]);
336
+
337
+ if (lower.includes('sipariş')) {
338
+ return `📦 Toplam sipariş: ${orderCount}`;
339
+ } else if (lower.includes('ürün') || lower.includes('stok')) {
340
+ return `🛍️ Toplam ürün: ${productCount}`;
341
+ } else if (lower.includes('mağaza') || lower.includes('store')) {
342
+ return `🏪 Aktif mağaza: ${storeCount}`;
343
+ } else {
344
+ return '💬 Mesajınızı aldım. Size yardımcı olmak için verileri hazırlıyorum.';
345
+ }
346
+ }, 15000);
347
+
348
+ return sendJson(res, 200, { response });
349
+ }
350
+
351
+ // --- /api/settings ---
352
+ if (req.method === 'GET' && pathname === '/api/settings') {
353
+ const licenseKey = config.get('licenseKey');
354
+ const licenseStatus = licenseKey ? licenseManager.verifyLicense(licenseKey) : { valid: false };
355
+ const userName = licenseStatus.valid ? licenseStatus.data.customer : 'Misafir';
356
+ const plan = licenseStatus.valid ? 'Pro Plan' : 'Free Plan';
357
+ const avatar = userName ? userName[0].toUpperCase() : 'V';
358
+
359
+ return sendJson(res, 200, {
360
+ user: { name: userName, plan, avatar },
361
+ companyInfo: config.get('companyInfo') || null,
362
+ ai: { provider: config.get('ai.provider') || 'OpenAI' },
363
+ cache: globalCache.getStats()
364
+ });
365
+ }
366
+
367
+ // --- Health check ---
368
+ if (req.method === 'GET' && pathname === '/api/health') {
369
+ return sendJson(res, 200, {
370
+ status: 'ok',
371
+ timestamp: new Date().toISOString(),
372
+ uptime: process.uptime(),
373
+ memory: process.memoryUsage(),
374
+ cache: globalCache.getStats()
375
+ });
376
+ }
377
+
378
+ return sendJson(res, 404, { error: 'Not Found' });
61
379
 
380
+ } catch (e) {
381
+ logger.error('API Error', {
382
+ path: pathname,
383
+ error: e.message,
384
+ stack: e.stack
385
+ });
386
+ return sendJson(res, 500, { error: e.message || 'Sunucu hatası' });
387
+ }
388
+ });
389
+
390
+ // Graceful shutdown kur
391
+ setupGracefulShutdown(server, db);
392
+
393
+ return new Promise(resolve => {
394
+ server.listen(port, () => {
395
+ logger.info(`API Server başladı`, { port });
396
+ resolve(server);
397
+ });
398
+ });
399
+ }
400
+
401
+ // --- HELPERS ---
62
402
  const printHeader = () => {
63
403
  clear();
64
404
  console.log(chalk.cyan(figlet.textSync('VANTUZ', { horizontalLayout: 'full' })));
65
405
  console.log(chalk.grey(` 🐙 E-Ticaretin Yapay Zeka Beyni | v${pkg.version}\n`));
66
406
  };
67
407
 
68
- async function main() {
69
- printHeader();
408
+ const printHeaderCompact = () => {
409
+ clear();
410
+ console.log(chalk.cyan(figlet.textSync('VANTUZ', { horizontalLayout: 'full' })));
411
+ };
70
412
 
71
- // 1. Karşılama ve İlk Kurulum Kontrolü
72
- const isFirstRun = !config.get('installed');
413
+ // --- MAIN ---
414
+ async function main() {
415
+ printHeaderCompact();
73
416
 
74
- if (isFirstRun) {
75
- await welcomeScreen();
76
- }
417
+ // Database Manager init
418
+ await initDatabaseManager();
77
419
 
78
- // 2. Lisans Kontrolü
420
+ // 1. Lisans Kontrolü
79
421
  let licenseKey = config.get('licenseKey');
80
422
  let licenseStatus = licenseKey ? licenseManager.verifyLicense(licenseKey) : { valid: false };
81
423
 
82
424
  if (!licenseStatus.valid) {
83
425
  if (licenseKey) console.log(chalk.red(`⚠️ Lisans Hatası: ${licenseStatus.reason}`));
84
426
 
85
- console.log(boxen(chalk.white('🔒 VANTUZ Lisans Aktivasyonu\nDevam etmek için satıcınızdan aldığınız anahtarı girin.'), { padding: 1, borderColor: 'cyan', borderStyle: 'classic' }));
86
- await activateLicense();
427
+ console.log(boxen(chalk.white('🔒 VANTUZ Lisens Aktivasyonu\nDevam etmek için satıcınızdan aldığınız anahtarı girin.'), { padding: 1, borderColor: 'cyan', borderStyle: 'classic' }));
428
+
429
+ const { key } = await inquirer.prompt([{ type: 'password', name: 'key', message: 'Lisans Anahtarı:', mask: '*' }]);
430
+ const spinner = ora('Anahtar doğrulanıyor...').start();
431
+ await new Promise(r => setTimeout(r, 1500));
432
+
433
+ const status = licenseManager.verifyLicense(key);
434
+ if (status.valid) {
435
+ spinner.succeed(`Lisans Aktif: ${status.data.customer}`);
436
+ config.set('licenseKey', key);
437
+ licenseStatus = status;
438
+ } else {
439
+ spinner.fail(`Hata: ${status.reason}`);
440
+ console.log(chalk.yellow('Lütfen geçerli bir anahtar girin.'));
441
+ process.exit(1);
442
+ }
87
443
  } else {
88
444
  const expiryDate = licenseStatus.data.expires || licenseStatus.data.expiry || new Date(Date.now() + 365*24*60*60*1000).toISOString();
89
445
  const daysLeft = Math.floor((new Date(expiryDate) - new Date()) / (1000 * 60 * 60 * 24));
@@ -91,21 +447,26 @@ async function main() {
91
447
  await new Promise(r => setTimeout(r, 1000));
92
448
  }
93
449
 
94
- // 3. Veritabanı ve Sistem
450
+ // 2. Veritabanı Bağlantısı
95
451
  const spinner = ora('Sistem nöronları başlatılıyor...').start();
96
- await db.initDB();
97
- spinner.succeed('Çekirdek Aktif');
452
+ try {
453
+ await withTimeout(db.initDB(), 10000, 'Database Init');
454
+ spinner.succeed('Çekirdek Aktif');
455
+ } catch (error) {
456
+ spinner.fail(`Veritabanı hatası: ${error.message}`);
457
+ process.exit(1);
458
+ }
98
459
 
99
- // 4. Mağaza Kontrolü
460
+ // 3. Mağaza Kontrolü
100
461
  const storeCount = await db.Store.count();
101
462
  if (storeCount === 0) {
102
463
  console.log(chalk.yellow('\n⚠️ Hiçbir mağaza bağlı değil.'));
103
464
  await setupWizard();
104
465
  }
105
466
 
106
- // 5. Ana Döngü
467
+ // 4. Ana Döngü
107
468
  while (true) {
108
- printHeader();
469
+ printHeaderCompact();
109
470
  await showDashboard(licenseStatus.data || { customer: 'Misafir', expires: '2099-01-01' });
110
471
 
111
472
  const { action } = await inquirer.prompt([
@@ -125,56 +486,16 @@ async function main() {
125
486
  }
126
487
  ]);
127
488
 
128
- if (action === 'exit') process.exit(0);
489
+ if (action === 'exit') {
490
+ console.log(chalk.green('\n👋 Güle güle!'));
491
+ process.exit(0);
492
+ }
493
+
129
494
  await handleAction(action);
130
495
  }
131
496
  }
132
497
 
133
- async function welcomeScreen() {
134
- clear();
135
- console.log(chalk.cyan(figlet.textSync('Merhaba!', { horizontalLayout: 'full' })));
136
- console.log(boxen(chalk.white(`
137
- VANTUZ'a Hoşgeldiniz.
138
-
139
- Bu yazılım, e-ticaret operasyonlarınızı yapay zeka ile yönetmenizi sağlar.
140
- Kuruluma başlamadan önce lütfen şunları hazırlayın:
141
-
142
- 1. Lisans Anahtarınız
143
- 2. Pazaryeri API Bilgileriniz (Trendyol, Hepsiburada vb.)
144
- 3. (Opsiyonel) OpenAI API Anahtarı - Vision özelliği için
145
-
146
- Başlamaya hazır mısınız?
147
- `), { padding: 1, borderStyle: 'double', borderColor: 'green' }));
148
-
149
- const { ready } = await inquirer.prompt([{ type: 'confirm', name: 'ready', message: 'Kuruluma Başla', default: true }]);
150
- if (!ready) {
151
- console.log(chalk.yellow('Kurulum iptal edildi. Çıkılıyor...'));
152
- process.exit(0);
153
- }
154
- config.set('installed', true);
155
- }
156
-
157
- async function activateLicense() {
158
- const { key } = await inquirer.prompt([{ type: 'password', name: 'key', message: 'Lisans Anahtarı:', mask: '*' }]);
159
- const spinner = ora('Anahtar doğrulanıyor...').start();
160
- await new Promise(r => setTimeout(r, 1500)); // Dramatik bekleme
161
-
162
- const status = licenseManager.verifyLicense(key);
163
-
164
- if (status.valid) {
165
- spinner.succeed(`Lisans Aktif: ${status.data.customer}`);
166
- config.set('licenseKey', key);
167
- await new Promise(r => setTimeout(r, 1000));
168
- } else {
169
- spinner.fail(`Hata: ${status.reason}`);
170
- console.log(chalk.yellow('Lütfen geçerli bir anahtar girin veya satıcınızla görüşün.'));
171
- process.exit(1);
172
- }
173
- }
174
-
175
- // ... (setupWizard, showDashboard, handleAction fonksiyonları aynı kalacak, sadece ufak revizyonlar) ...
176
-
177
- // setupWizard fonksiyonunu güncelleme (Mağaza kurulumu)
498
+ // --- WIZARD ---
178
499
  async function setupWizard() {
179
500
  console.log(chalk.bold('\n🛒 Mağaza Bağlantı Sihirbazı\n'));
180
501
  const { storeName } = await inquirer.prompt([{ type: 'input', name: 'storeName', message: 'Mağaza Adı:' }]);
@@ -194,64 +515,71 @@ async function setupWizard() {
194
515
  ]);
195
516
 
196
517
  let creds = {};
197
-
198
518
  if (platform === 'trendyol') {
199
- console.log(chalk.cyan('\n👉 Trendyol Entegrasyonu:'));
200
519
  creds = await inquirer.prompt([
201
520
  { type: 'password', name: 'supplierId', message: 'Supplier ID:', mask: '*' },
202
521
  { type: 'password', name: 'apiKey', message: 'API Key:', mask: '*' },
203
522
  { type: 'password', name: 'apiSecret', message: 'API Secret:', mask: '*' }
204
523
  ]);
205
524
  } else if (platform === 'hepsiburada') {
206
- console.log(chalk.cyan('\n👉 Hepsiburada Entegrasyonu:'));
207
525
  creds = await inquirer.prompt([
208
526
  { type: 'input', name: 'merchantId', message: 'Merchant ID:' },
209
527
  { type: 'password', name: 'username', message: 'Username (MP):', mask: '*' },
210
528
  { type: 'password', name: 'password', message: 'Password:', mask: '*' }
211
529
  ]);
212
530
  } else if (platform === 'n11') {
213
- console.log(chalk.cyan('\n👉 N11 Entegrasyonu:'));
214
531
  creds = await inquirer.prompt([
215
532
  { type: 'password', name: 'apiKey', message: 'API Key:', mask: '*' },
216
533
  { type: 'password', name: 'apiSecret', message: 'API Secret:', mask: '*' }
217
534
  ]);
218
535
  } else if (platform === 'amazon') {
219
- console.log(chalk.cyan('\n👉 Amazon SP-API Entegrasyonu:'));
220
536
  creds = await inquirer.prompt([
221
537
  { type: 'input', name: 'sellerId', message: 'Seller ID:' },
222
538
  { type: 'password', name: 'clientId', message: 'Client ID:', mask: '*' },
223
539
  { type: 'password', name: 'clientSecret', message: 'Client Secret:', mask: '*' },
224
- { type: 'password', name: 'refreshToken', message: 'Refresh Token:', mask: '*' },
225
- { type: 'list', name: 'region', message: 'Bölge:', choices: ['eu', 'na', 'tr'], default: 'tr' }
540
+ { type: 'password', name: 'refreshToken', message: 'Refresh Token:', mask: '*' }
226
541
  ]);
227
542
  }
228
543
 
229
- await db.Store.create({ name: storeName, platform, credentials: creds });
230
- console.log(chalk.green(`\n✅ ${storeName} (${platform}) Başarıyla Bağlandı!`));
231
-
232
- // AI Brand Analysis
233
- await brandAnalyst.analyzeAndSave(storeName, config);
234
-
544
+ try {
545
+ await db.Store.create({ name: storeName, platform, credentials: creds });
546
+ console.log(chalk.green(`\n✅ ${storeName} (${platform}) Başarıyla Bağlandı!`));
547
+ await brandAnalyst.analyzeAndSave(storeName, config);
548
+ } catch (error) {
549
+ logger.error('Mağaza oluşturma hatası', { error: error.message });
550
+ console.log(chalk.red(`\n❌ Hata: ${error.message}`));
551
+ }
235
552
  await new Promise(r => setTimeout(r, 1500));
236
553
  }
237
554
 
555
+ // --- DASHBOARD ---
238
556
  async function showDashboard(licenseData) {
239
- const stores = await db.Store.findAll();
240
- const orders = await db.Order.count();
241
-
242
- console.log(chalk.bold(`🏢 Lisans Sahibi: ${chalk.cyan(licenseData.customer)}`));
243
- console.log(`📦 Aktif Mağazalar: ${stores.length} | Toplam Sipariş: ${orders}`);
244
- console.log(chalk.grey('----------------------------------------'));
557
+ const spinner = ora('Veriler yükleniyor...').start();
558
+ try {
559
+ const [stores, orders] = await Promise.all([
560
+ db.Store.findAll(),
561
+ db.Order.count()
562
+ ]);
563
+ spinner.stop();
564
+
565
+ console.log(chalk.bold(`🏢 Lisans Sahibi: ${chalk.cyan(licenseData.customer)}`));
566
+ console.log(`📦 Aktif Mağazalar: ${stores.length} | Toplam Sipariş: ${orders}`);
567
+ console.log(chalk.grey('----------------------------------------'));
568
+
569
+ // Cache stats
570
+ const cacheStats = globalCache.getStats();
571
+ console.log(chalk.dim(` Cache Hit Rate: ${cacheStats.hitRate}`));
572
+
573
+ } catch (error) {
574
+ spinner.fail(`Dashboard yükleme hatası: ${error.message}`);
575
+ }
245
576
  }
246
577
 
578
+ // --- ACTION HANDLER ---
247
579
  async function handleAction(action) {
248
- const inquirer = require('inquirer');
249
- const chalk = require('chalk');
250
-
251
580
  if (action === 'products') {
252
581
  await productManager.manageProducts();
253
582
  } else if (action === 'ai_chat') {
254
- // AI Chat
255
583
  let companyInfo = config.get('companyInfo');
256
584
  if (!companyInfo || !companyInfo.market) {
257
585
  console.log(chalk.cyan('\n🏢 FİRMA KAYDI'));
@@ -279,19 +607,18 @@ async function handleAction(action) {
279
607
  let response = '';
280
608
 
281
609
  if (lower.includes('pazar') || lower.includes('araştır')) {
282
- response = `📊 ${companyInfo.market} pazarında araştırma yapıyorum...\n\n• Fiyat analizi\n• Rakip takibi\n• Kar marjı`;
610
+ response = `📊 ${companyInfo.market} pazarında araştırma yapıyorum...`;
283
611
  } else if (lower.includes('stok') || lower.includes('ürün')) {
284
- response = `📦 Stok durumu:\n\n• Toplam ürün: ${await db.Product.count()}\n• Mağaza: ${(await db.Store.findAll()).length}`;
612
+ response = `📦 Stok: ${await db.Product.count()} ürün, ${await db.Store.count()} mağaza`;
285
613
  } else if (lower.includes('sipariş')) {
286
- response = `📦 Sipariş durumu:\n\n• Toplam: ${await db.Order.count()}`;
614
+ response = `📦 Sipariş: ${await db.Order.count()} toplam sipariş`;
287
615
  } else {
288
- response = `💬 "${message}" anladım.\n\nKomutlar: "pazar araştır", "stok durumu", "siparişler"`;
616
+ response = `"${message}" anladım. Komutlar: "pazar araştır", "stok durumu", "siparişler"`;
289
617
  }
290
618
 
291
619
  console.log(chalk.white('\n' + response + '\n'));
292
620
  }
293
621
  } else if (action === 'stores') {
294
- // Mağazalarım
295
622
  console.log(chalk.cyan('\n🏪 MAĞAZALARIM'));
296
623
  console.log(chalk.grey('─'.repeat(40)));
297
624
  const stores = await db.Store.findAll();
@@ -302,10 +629,8 @@ async function handleAction(action) {
302
629
  console.log(chalk.white(` ${i+1}. ${s.name} (${s.platform})`));
303
630
  });
304
631
  }
305
- console.log(chalk.grey('\n [Devam için Enter]'));
306
- await inquirer.prompt([{ type: 'input', name: 'ok', message: '' }]);
632
+ await inquirer.prompt([{ type: 'input', name: 'ok', message: '\n Devam için Enter...' }]);
307
633
  } else if (action === 'settings') {
308
- // Settings
309
634
  console.log(chalk.cyan('\n⚙️ AYARLAR'));
310
635
  console.log(chalk.grey('─'.repeat(40)));
311
636
 
@@ -317,6 +642,8 @@ async function handleAction(action) {
317
642
  choices: [
318
643
  '🔑 Lisans Değiştir',
319
644
  '🤖 AI Model Ayarları',
645
+ '💾 Backup Oluştur',
646
+ '📊 Cache Durumu',
320
647
  '🔙 Geri'
321
648
  ]
322
649
  }
@@ -324,7 +651,7 @@ async function handleAction(action) {
324
651
 
325
652
  if (setting === '🔑 Lisans Değiştir') {
326
653
  const { newKey } = await inquirer.prompt([
327
- { type: 'input', name: 'newKey', message: 'Yeni lisans anahtarı:' }
654
+ { type: 'password', name: 'newKey', message: 'Yeni lisans anahtarı:', mask: '*' }
328
655
  ]);
329
656
  const result = licenseManager.verifyLicense(newKey);
330
657
  if (result.valid) {
@@ -335,7 +662,6 @@ async function handleAction(action) {
335
662
  }
336
663
  } else if (setting === '🤖 AI Model Ayarları') {
337
664
  console.log(chalk.yellow('\n 📝 AI Model Ayarları:'));
338
-
339
665
  const { provider } = await inquirer.prompt([
340
666
  {
341
667
  type: 'list',
@@ -356,12 +682,54 @@ async function handleAction(action) {
356
682
  console.log(chalk.green(' ✅ Kaydedildi!'));
357
683
  }
358
684
  }
685
+ } else if (setting === '💾 Backup Oluştur') {
686
+ console.log(chalk.cyan('\n💾 Backup oluşturuluyor...'));
687
+ if (dbManager) {
688
+ const result = await dbManager.createBackup('manual');
689
+ if (result.success) {
690
+ console.log(chalk.green(` ✅ ${result.file}`));
691
+ } else {
692
+ console.log(chalk.red(` ❌ ${result.error}`));
693
+ }
694
+ } else {
695
+ console.log(chalk.yellow(' ⚠️ Database Manager hazır değil'));
696
+ }
697
+ } else if (setting === '📊 Cache Durumu') {
698
+ const stats = globalCache.getStats();
699
+ console.log(chalk.cyan('\n📊 Cache İstatistikleri:'));
700
+ console.log(JSON.stringify(stats, null, 2));
359
701
  }
360
- await inquirer.prompt([{ type: 'input', name: 'ok', message: '\n Devam...' }]);
702
+
703
+ await inquirer.prompt([{ type: 'input', name: 'ok', message: '\n Devam için Enter...' }]);
361
704
  }
362
705
  }
363
706
 
364
- main().catch(err => {
365
- console.error(err);
366
- process.exit(1);
367
- });
707
+ // --- ENTRY POINT ---
708
+ if (require.main === module) {
709
+ const isApiMode = process.argv.includes('--api') || process.env.VANTUZ_DESKTOP_API === '1';
710
+
711
+ (async () => {
712
+ try {
713
+ if (isApiMode) {
714
+ await startApiServer();
715
+ } else {
716
+ await main();
717
+ }
718
+ } catch (error) {
719
+ logger.fatal('Fatal error', {
720
+ message: error.message,
721
+ stack: error.stack
722
+ });
723
+ console.error(chalk.red(`\n💀 Fatal Error: ${error.message}`));
724
+ process.exit(1);
725
+ }
726
+ })();
727
+ }
728
+
729
+ module.exports = {
730
+ startApiServer,
731
+ initDatabaseManager,
732
+ globalCache,
733
+ getCopilot,
734
+ getCopilotFunctions
735
+ };