vantuz 3.4.1 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +45 -45
- package/admin-keygen.js +51 -0
- package/cli.js +685 -585
- package/config.js +733 -733
- package/core/agent-loop.js +190 -190
- package/core/ai-provider.js +298 -261
- package/core/automation.js +523 -523
- package/core/brand-analyst.js +101 -0
- package/core/channels.js +167 -167
- package/core/dashboard.js +230 -230
- package/core/database.js +135 -36
- package/core/eia-monitor.js +3 -1
- package/core/engine.js +648 -636
- package/core/gateway.js +447 -447
- package/core/learning.js +214 -214
- package/core/license.js +113 -0
- package/core/marketplace-adapter.js +168 -168
- package/core/memory.js +190 -190
- package/core/migrations/001-initial-schema.sql +1 -1
- package/core/queue.js +120 -120
- package/core/self-healer.js +314 -314
- package/core/unified-product.js +214 -214
- package/core/vision-service.js +113 -113
- package/index.js +217 -174
- package/modules/crm/sentiment-crm.js +231 -231
- package/modules/healer/listing-healer.js +201 -201
- package/modules/oracle/predictor.js +214 -214
- package/modules/researcher/agent.js +169 -169
- package/modules/team/agents/base.js +92 -92
- package/modules/team/agents/dev.js +33 -33
- package/modules/team/agents/josh.js +40 -40
- package/modules/team/agents/marketing.js +33 -33
- package/modules/team/agents/milo.js +36 -36
- package/modules/team/index.js +78 -78
- package/modules/team/shared-memory.js +87 -87
- package/modules/war-room/competitor-tracker.js +250 -250
- package/modules/war-room/pricing-engine.js +308 -308
- package/nodes/warehouse.js +238 -238
- package/onboard.js +1 -1
- package/package.json +7 -6
- package/platforms/pttavm.js +14 -14
- package/plugins/vantuz/index.js +528 -528
- package/plugins/vantuz/memory/hippocampus.js +465 -464
- package/plugins/vantuz/package.json +20 -20
- package/plugins/vantuz/platforms/_template.js +118 -118
- package/plugins/vantuz/platforms/amazon.js +236 -236
- package/plugins/vantuz/platforms/ciceksepeti.js +166 -166
- package/plugins/vantuz/platforms/hepsiburada.js +180 -180
- package/plugins/vantuz/platforms/index.js +165 -165
- package/plugins/vantuz/platforms/n11.js +229 -229
- package/plugins/vantuz/platforms/pazarama.js +154 -154
- package/plugins/vantuz/platforms/pttavm.js +127 -127
- package/plugins/vantuz/platforms/trendyol.js +326 -326
- package/plugins/vantuz/services/alerts.js +253 -253
- package/plugins/vantuz/services/license.js +34 -34
- package/plugins/vantuz/services/scheduler.js +232 -232
- package/plugins/vantuz/tools/analytics.js +152 -152
- package/plugins/vantuz/tools/crossborder.js +187 -187
- package/plugins/vantuz/tools/nl-parser.js +211 -211
- package/plugins/vantuz/tools/product.js +110 -110
- package/plugins/vantuz/tools/quick-report.js +175 -175
- package/plugins/vantuz/tools/repricer.js +314 -314
- package/plugins/vantuz/tools/sentiment.js +115 -115
- package/plugins/vantuz/tools/vision.js +257 -257
- package/private.pem +28 -0
- package/public.pem +9 -0
- package/server/app.js +260 -260
- package/server/public/index.html +514 -514
- package/start.bat +33 -33
- package/vantuz.sqlite +0 -0
|
@@ -1,253 +1,253 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🔔 AKILLI UYARI SİSTEMİ
|
|
3
|
-
* Stok, fiyat ve sipariş uyarıları
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const DEFAULT_THRESHOLDS = {
|
|
7
|
-
criticalStock: 5, // Kritik stok seviyesi
|
|
8
|
-
lowStock: 20, // Düşük stok uyarısı
|
|
9
|
-
priceDropPercent: 10, // Rakip fiyat düşüşü uyarısı
|
|
10
|
-
orderDelay: 24, // Sipariş gecikme saati
|
|
11
|
-
reviewNegative: 3 // Negatif yorum eşiği
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export class AlertService {
|
|
15
|
-
constructor(config = {}) {
|
|
16
|
-
this.thresholds = { ...DEFAULT_THRESHOLDS, ...config.thresholds };
|
|
17
|
-
this.subscribers = [];
|
|
18
|
-
this.alerts = [];
|
|
19
|
-
this.notifiedToday = new Set(); // Aynı uyarıyı tekrar gönderme
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Uyarı ekle
|
|
24
|
-
*/
|
|
25
|
-
addAlert(alert) {
|
|
26
|
-
const key = `${alert.type}-${alert.productId || alert.orderId || 'general'}`;
|
|
27
|
-
|
|
28
|
-
// Bugün zaten bildirildi mi?
|
|
29
|
-
if (this.notifiedToday.has(key)) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
this.alerts.push({
|
|
34
|
-
...alert,
|
|
35
|
-
id: `alert-${Date.now()}`,
|
|
36
|
-
timestamp: new Date().toISOString(),
|
|
37
|
-
read: false
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
this.notifiedToday.add(key);
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Stok kontrolü
|
|
46
|
-
*/
|
|
47
|
-
async checkStock(products, platform) {
|
|
48
|
-
const alerts = [];
|
|
49
|
-
|
|
50
|
-
for (const product of products) {
|
|
51
|
-
const stock = product.quantity || product.stock || product.availableStock || 0;
|
|
52
|
-
const name = product.title || product.name || product.barcode;
|
|
53
|
-
|
|
54
|
-
if (stock <= 0) {
|
|
55
|
-
alerts.push({
|
|
56
|
-
type: 'stock_out',
|
|
57
|
-
severity: 'critical',
|
|
58
|
-
icon: '🔴',
|
|
59
|
-
message: `Stok bitti: ${name}`,
|
|
60
|
-
productId: product.barcode || product.id,
|
|
61
|
-
platform,
|
|
62
|
-
value: stock
|
|
63
|
-
});
|
|
64
|
-
} else if (stock <= this.thresholds.criticalStock) {
|
|
65
|
-
alerts.push({
|
|
66
|
-
type: 'stock_critical',
|
|
67
|
-
severity: 'high',
|
|
68
|
-
icon: '🟠',
|
|
69
|
-
message: `Kritik stok (${stock}): ${name}`,
|
|
70
|
-
productId: product.barcode || product.id,
|
|
71
|
-
platform,
|
|
72
|
-
value: stock
|
|
73
|
-
});
|
|
74
|
-
} else if (stock <= this.thresholds.lowStock) {
|
|
75
|
-
alerts.push({
|
|
76
|
-
type: 'stock_low',
|
|
77
|
-
severity: 'medium',
|
|
78
|
-
icon: '🟡',
|
|
79
|
-
message: `Düşük stok (${stock}): ${name}`,
|
|
80
|
-
productId: product.barcode || product.id,
|
|
81
|
-
platform,
|
|
82
|
-
value: stock
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
alerts.forEach(a => this.addAlert(a));
|
|
88
|
-
return alerts;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Rakip fiyat kontrolü
|
|
93
|
-
*/
|
|
94
|
-
async checkCompetitorPrices(comparisons) {
|
|
95
|
-
const alerts = [];
|
|
96
|
-
|
|
97
|
-
for (const comp of comparisons) {
|
|
98
|
-
const { product, ourPrice, lowestCompetitor, competitorName } = comp;
|
|
99
|
-
const diff = ((ourPrice - lowestCompetitor) / ourPrice) * 100;
|
|
100
|
-
|
|
101
|
-
if (lowestCompetitor < ourPrice && diff > this.thresholds.priceDropPercent) {
|
|
102
|
-
alerts.push({
|
|
103
|
-
type: 'competitor_undercut',
|
|
104
|
-
severity: 'high',
|
|
105
|
-
icon: '💸',
|
|
106
|
-
message: `Rakip ${Math.round(diff)}% ucuz: ${product.name || product.barcode}`,
|
|
107
|
-
productId: product.barcode,
|
|
108
|
-
competitor: competitorName,
|
|
109
|
-
ourPrice,
|
|
110
|
-
competitorPrice: lowestCompetitor,
|
|
111
|
-
suggestion: `Fiyatı ${lowestCompetitor * 0.99}₺'ye düşürmeyi düşünün`
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
alerts.forEach(a => this.addAlert(a));
|
|
117
|
-
return alerts;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Sipariş gecikme kontrolü
|
|
122
|
-
*/
|
|
123
|
-
async checkOrderDelays(orders) {
|
|
124
|
-
const alerts = [];
|
|
125
|
-
const now = Date.now();
|
|
126
|
-
|
|
127
|
-
for (const order of orders) {
|
|
128
|
-
const createdAt = new Date(order.createdDate || order.orderDate).getTime();
|
|
129
|
-
const hoursAgo = (now - createdAt) / (1000 * 60 * 60);
|
|
130
|
-
|
|
131
|
-
const status = order.status?.toLowerCase();
|
|
132
|
-
const isPending = ['created', 'new', 'pending', 'yeni'].some(s => status?.includes(s));
|
|
133
|
-
|
|
134
|
-
if (isPending && hoursAgo > this.thresholds.orderDelay) {
|
|
135
|
-
alerts.push({
|
|
136
|
-
type: 'order_delayed',
|
|
137
|
-
severity: 'high',
|
|
138
|
-
icon: '⏰',
|
|
139
|
-
message: `${Math.round(hoursAgo)} saat bekleyen sipariş: #${order.orderNumber || order.id}`,
|
|
140
|
-
orderId: order.id,
|
|
141
|
-
hoursDelayed: Math.round(hoursAgo),
|
|
142
|
-
suggestion: 'Siparişi hazırlayın veya iptal edin'
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
alerts.forEach(a => this.addAlert(a));
|
|
148
|
-
return alerts;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Tüm uyarıları formatla
|
|
153
|
-
*/
|
|
154
|
-
formatAlerts(alerts) {
|
|
155
|
-
if (alerts.length === 0) {
|
|
156
|
-
return '✅ Herhangi bir uyarı yok!';
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const grouped = {
|
|
160
|
-
critical: alerts.filter(a => a.severity === 'critical'),
|
|
161
|
-
high: alerts.filter(a => a.severity === 'high'),
|
|
162
|
-
medium: alerts.filter(a => a.severity === 'medium'),
|
|
163
|
-
low: alerts.filter(a => a.severity === 'low')
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
let message = '📋 **Uyarı Özeti**\n\n';
|
|
167
|
-
|
|
168
|
-
if (grouped.critical.length > 0) {
|
|
169
|
-
message += `🔴 **Kritik (${grouped.critical.length})**\n`;
|
|
170
|
-
grouped.critical.forEach(a => {
|
|
171
|
-
message += ` • ${a.message}\n`;
|
|
172
|
-
});
|
|
173
|
-
message += '\n';
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (grouped.high.length > 0) {
|
|
177
|
-
message += `🟠 **Yüksek (${grouped.high.length})**\n`;
|
|
178
|
-
grouped.high.slice(0, 5).forEach(a => {
|
|
179
|
-
message += ` • ${a.message}\n`;
|
|
180
|
-
});
|
|
181
|
-
if (grouped.high.length > 5) {
|
|
182
|
-
message += ` ... ve ${grouped.high.length - 5} uyarı daha\n`;
|
|
183
|
-
}
|
|
184
|
-
message += '\n';
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (grouped.medium.length > 0) {
|
|
188
|
-
message += `🟡 **Orta (${grouped.medium.length})**\n`;
|
|
189
|
-
grouped.medium.slice(0, 3).forEach(a => {
|
|
190
|
-
message += ` • ${a.message}\n`;
|
|
191
|
-
});
|
|
192
|
-
if (grouped.medium.length > 3) {
|
|
193
|
-
message += ` ... ve ${grouped.medium.length - 3} uyarı daha\n`;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return message;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Okunmamış uyarı sayısı
|
|
202
|
-
*/
|
|
203
|
-
getUnreadCount() {
|
|
204
|
-
return this.alerts.filter(a => !a.read).length;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Uyarıları okundu işaretle
|
|
209
|
-
*/
|
|
210
|
-
markAllRead() {
|
|
211
|
-
this.alerts.forEach(a => a.read = true);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Günlük cache'i temizle
|
|
216
|
-
*/
|
|
217
|
-
resetDaily() {
|
|
218
|
-
this.notifiedToday.clear();
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
export const alertTool = {
|
|
223
|
-
name: 'alert',
|
|
224
|
-
|
|
225
|
-
async execute(params, context) {
|
|
226
|
-
const { action, type } = params;
|
|
227
|
-
const alertService = new AlertService();
|
|
228
|
-
|
|
229
|
-
switch (action) {
|
|
230
|
-
case 'check':
|
|
231
|
-
// Tüm kontrolleri yap ve uyarıları topla
|
|
232
|
-
const allAlerts = [];
|
|
233
|
-
// TODO: Platform API'lerinden veri çek ve kontrol et
|
|
234
|
-
return { success: true, alerts: allAlerts };
|
|
235
|
-
|
|
236
|
-
case 'list':
|
|
237
|
-
return {
|
|
238
|
-
success: true,
|
|
239
|
-
alerts: alertService.alerts,
|
|
240
|
-
unread: alertService.getUnreadCount()
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
case 'clear':
|
|
244
|
-
alertService.markAllRead();
|
|
245
|
-
return { success: true };
|
|
246
|
-
|
|
247
|
-
default:
|
|
248
|
-
return { success: false, error: 'Geçersiz action' };
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
export default AlertService;
|
|
1
|
+
/**
|
|
2
|
+
* 🔔 AKILLI UYARI SİSTEMİ
|
|
3
|
+
* Stok, fiyat ve sipariş uyarıları
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const DEFAULT_THRESHOLDS = {
|
|
7
|
+
criticalStock: 5, // Kritik stok seviyesi
|
|
8
|
+
lowStock: 20, // Düşük stok uyarısı
|
|
9
|
+
priceDropPercent: 10, // Rakip fiyat düşüşü uyarısı
|
|
10
|
+
orderDelay: 24, // Sipariş gecikme saati
|
|
11
|
+
reviewNegative: 3 // Negatif yorum eşiği
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export class AlertService {
|
|
15
|
+
constructor(config = {}) {
|
|
16
|
+
this.thresholds = { ...DEFAULT_THRESHOLDS, ...config.thresholds };
|
|
17
|
+
this.subscribers = [];
|
|
18
|
+
this.alerts = [];
|
|
19
|
+
this.notifiedToday = new Set(); // Aynı uyarıyı tekrar gönderme
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Uyarı ekle
|
|
24
|
+
*/
|
|
25
|
+
addAlert(alert) {
|
|
26
|
+
const key = `${alert.type}-${alert.productId || alert.orderId || 'general'}`;
|
|
27
|
+
|
|
28
|
+
// Bugün zaten bildirildi mi?
|
|
29
|
+
if (this.notifiedToday.has(key)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.alerts.push({
|
|
34
|
+
...alert,
|
|
35
|
+
id: `alert-${Date.now()}`,
|
|
36
|
+
timestamp: new Date().toISOString(),
|
|
37
|
+
read: false
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
this.notifiedToday.add(key);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Stok kontrolü
|
|
46
|
+
*/
|
|
47
|
+
async checkStock(products, platform) {
|
|
48
|
+
const alerts = [];
|
|
49
|
+
|
|
50
|
+
for (const product of products) {
|
|
51
|
+
const stock = product.quantity || product.stock || product.availableStock || 0;
|
|
52
|
+
const name = product.title || product.name || product.barcode;
|
|
53
|
+
|
|
54
|
+
if (stock <= 0) {
|
|
55
|
+
alerts.push({
|
|
56
|
+
type: 'stock_out',
|
|
57
|
+
severity: 'critical',
|
|
58
|
+
icon: '🔴',
|
|
59
|
+
message: `Stok bitti: ${name}`,
|
|
60
|
+
productId: product.barcode || product.id,
|
|
61
|
+
platform,
|
|
62
|
+
value: stock
|
|
63
|
+
});
|
|
64
|
+
} else if (stock <= this.thresholds.criticalStock) {
|
|
65
|
+
alerts.push({
|
|
66
|
+
type: 'stock_critical',
|
|
67
|
+
severity: 'high',
|
|
68
|
+
icon: '🟠',
|
|
69
|
+
message: `Kritik stok (${stock}): ${name}`,
|
|
70
|
+
productId: product.barcode || product.id,
|
|
71
|
+
platform,
|
|
72
|
+
value: stock
|
|
73
|
+
});
|
|
74
|
+
} else if (stock <= this.thresholds.lowStock) {
|
|
75
|
+
alerts.push({
|
|
76
|
+
type: 'stock_low',
|
|
77
|
+
severity: 'medium',
|
|
78
|
+
icon: '🟡',
|
|
79
|
+
message: `Düşük stok (${stock}): ${name}`,
|
|
80
|
+
productId: product.barcode || product.id,
|
|
81
|
+
platform,
|
|
82
|
+
value: stock
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
alerts.forEach(a => this.addAlert(a));
|
|
88
|
+
return alerts;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Rakip fiyat kontrolü
|
|
93
|
+
*/
|
|
94
|
+
async checkCompetitorPrices(comparisons) {
|
|
95
|
+
const alerts = [];
|
|
96
|
+
|
|
97
|
+
for (const comp of comparisons) {
|
|
98
|
+
const { product, ourPrice, lowestCompetitor, competitorName } = comp;
|
|
99
|
+
const diff = ((ourPrice - lowestCompetitor) / ourPrice) * 100;
|
|
100
|
+
|
|
101
|
+
if (lowestCompetitor < ourPrice && diff > this.thresholds.priceDropPercent) {
|
|
102
|
+
alerts.push({
|
|
103
|
+
type: 'competitor_undercut',
|
|
104
|
+
severity: 'high',
|
|
105
|
+
icon: '💸',
|
|
106
|
+
message: `Rakip ${Math.round(diff)}% ucuz: ${product.name || product.barcode}`,
|
|
107
|
+
productId: product.barcode,
|
|
108
|
+
competitor: competitorName,
|
|
109
|
+
ourPrice,
|
|
110
|
+
competitorPrice: lowestCompetitor,
|
|
111
|
+
suggestion: `Fiyatı ${lowestCompetitor * 0.99}₺'ye düşürmeyi düşünün`
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
alerts.forEach(a => this.addAlert(a));
|
|
117
|
+
return alerts;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Sipariş gecikme kontrolü
|
|
122
|
+
*/
|
|
123
|
+
async checkOrderDelays(orders) {
|
|
124
|
+
const alerts = [];
|
|
125
|
+
const now = Date.now();
|
|
126
|
+
|
|
127
|
+
for (const order of orders) {
|
|
128
|
+
const createdAt = new Date(order.createdDate || order.orderDate).getTime();
|
|
129
|
+
const hoursAgo = (now - createdAt) / (1000 * 60 * 60);
|
|
130
|
+
|
|
131
|
+
const status = order.status?.toLowerCase();
|
|
132
|
+
const isPending = ['created', 'new', 'pending', 'yeni'].some(s => status?.includes(s));
|
|
133
|
+
|
|
134
|
+
if (isPending && hoursAgo > this.thresholds.orderDelay) {
|
|
135
|
+
alerts.push({
|
|
136
|
+
type: 'order_delayed',
|
|
137
|
+
severity: 'high',
|
|
138
|
+
icon: '⏰',
|
|
139
|
+
message: `${Math.round(hoursAgo)} saat bekleyen sipariş: #${order.orderNumber || order.id}`,
|
|
140
|
+
orderId: order.id,
|
|
141
|
+
hoursDelayed: Math.round(hoursAgo),
|
|
142
|
+
suggestion: 'Siparişi hazırlayın veya iptal edin'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
alerts.forEach(a => this.addAlert(a));
|
|
148
|
+
return alerts;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Tüm uyarıları formatla
|
|
153
|
+
*/
|
|
154
|
+
formatAlerts(alerts) {
|
|
155
|
+
if (alerts.length === 0) {
|
|
156
|
+
return '✅ Herhangi bir uyarı yok!';
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const grouped = {
|
|
160
|
+
critical: alerts.filter(a => a.severity === 'critical'),
|
|
161
|
+
high: alerts.filter(a => a.severity === 'high'),
|
|
162
|
+
medium: alerts.filter(a => a.severity === 'medium'),
|
|
163
|
+
low: alerts.filter(a => a.severity === 'low')
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
let message = '📋 **Uyarı Özeti**\n\n';
|
|
167
|
+
|
|
168
|
+
if (grouped.critical.length > 0) {
|
|
169
|
+
message += `🔴 **Kritik (${grouped.critical.length})**\n`;
|
|
170
|
+
grouped.critical.forEach(a => {
|
|
171
|
+
message += ` • ${a.message}\n`;
|
|
172
|
+
});
|
|
173
|
+
message += '\n';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (grouped.high.length > 0) {
|
|
177
|
+
message += `🟠 **Yüksek (${grouped.high.length})**\n`;
|
|
178
|
+
grouped.high.slice(0, 5).forEach(a => {
|
|
179
|
+
message += ` • ${a.message}\n`;
|
|
180
|
+
});
|
|
181
|
+
if (grouped.high.length > 5) {
|
|
182
|
+
message += ` ... ve ${grouped.high.length - 5} uyarı daha\n`;
|
|
183
|
+
}
|
|
184
|
+
message += '\n';
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (grouped.medium.length > 0) {
|
|
188
|
+
message += `🟡 **Orta (${grouped.medium.length})**\n`;
|
|
189
|
+
grouped.medium.slice(0, 3).forEach(a => {
|
|
190
|
+
message += ` • ${a.message}\n`;
|
|
191
|
+
});
|
|
192
|
+
if (grouped.medium.length > 3) {
|
|
193
|
+
message += ` ... ve ${grouped.medium.length - 3} uyarı daha\n`;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return message;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Okunmamış uyarı sayısı
|
|
202
|
+
*/
|
|
203
|
+
getUnreadCount() {
|
|
204
|
+
return this.alerts.filter(a => !a.read).length;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Uyarıları okundu işaretle
|
|
209
|
+
*/
|
|
210
|
+
markAllRead() {
|
|
211
|
+
this.alerts.forEach(a => a.read = true);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Günlük cache'i temizle
|
|
216
|
+
*/
|
|
217
|
+
resetDaily() {
|
|
218
|
+
this.notifiedToday.clear();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export const alertTool = {
|
|
223
|
+
name: 'alert',
|
|
224
|
+
|
|
225
|
+
async execute(params, context) {
|
|
226
|
+
const { action, type } = params;
|
|
227
|
+
const alertService = new AlertService();
|
|
228
|
+
|
|
229
|
+
switch (action) {
|
|
230
|
+
case 'check':
|
|
231
|
+
// Tüm kontrolleri yap ve uyarıları topla
|
|
232
|
+
const allAlerts = [];
|
|
233
|
+
// TODO: Platform API'lerinden veri çek ve kontrol et
|
|
234
|
+
return { success: true, alerts: allAlerts };
|
|
235
|
+
|
|
236
|
+
case 'list':
|
|
237
|
+
return {
|
|
238
|
+
success: true,
|
|
239
|
+
alerts: alertService.alerts,
|
|
240
|
+
unread: alertService.getUnreadCount()
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
case 'clear':
|
|
244
|
+
alertService.markAllRead();
|
|
245
|
+
return { success: true };
|
|
246
|
+
|
|
247
|
+
default:
|
|
248
|
+
return { success: false, error: 'Geçersiz action' };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export default AlertService;
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* LİSANS YÖNETİCİSİ (DEV MODE - HERKES SÜPER KULLANICI)
|
|
4
|
-
* Kullanıcının isteği üzerine tüm güvenlik/lisans kontrolleri kaldırılmıştır.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export class LicenseManager {
|
|
8
|
-
constructor(api = null) {
|
|
9
|
-
this.isValidated = true; // Her zaman aktif
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async initialize() {
|
|
13
|
-
return { success: true, bypassed: true };
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async activate(key) {
|
|
17
|
-
return {
|
|
18
|
-
success: true,
|
|
19
|
-
data: {
|
|
20
|
-
user: 'Developer',
|
|
21
|
-
features: ['all'],
|
|
22
|
-
expiresAt: '2099-12-31'
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
validateFormat(key) {
|
|
28
|
-
return { valid: true };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async getFeatureStatus() {
|
|
32
|
-
return { enabled: true }; // Tüm özellikler açık
|
|
33
|
-
}
|
|
34
|
-
}
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* LİSANS YÖNETİCİSİ (DEV MODE - HERKES SÜPER KULLANICI)
|
|
4
|
+
* Kullanıcının isteği üzerine tüm güvenlik/lisans kontrolleri kaldırılmıştır.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class LicenseManager {
|
|
8
|
+
constructor(api = null) {
|
|
9
|
+
this.isValidated = true; // Her zaman aktif
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async initialize() {
|
|
13
|
+
return { success: true, bypassed: true };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async activate(key) {
|
|
17
|
+
return {
|
|
18
|
+
success: true,
|
|
19
|
+
data: {
|
|
20
|
+
user: 'Developer',
|
|
21
|
+
features: ['all'],
|
|
22
|
+
expiresAt: '2099-12-31'
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
validateFormat(key) {
|
|
28
|
+
return { valid: true };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async getFeatureStatus() {
|
|
32
|
+
return { enabled: true }; // Tüm özellikler açık
|
|
33
|
+
}
|
|
34
|
+
}
|