Warehouse Analytics & Enterprise Automation
Warehouse Analytics & Enterprise Automation
Enterprise-ΡΡΠΎΠ²Π΅Π½Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·Π°ΡΠΈΠΈ ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΠΈ Π°Π½Π°Π»ΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ ΡΠ΅ΡΠ΅Π½ΠΈΠΉ Π΄Π»Ρ OZON Warehouse API.
π ΠΠΠ ΠΠΠ ΠΠ’ΠΠΠΠΠ― ΠΠΠ’ΠΠΠΠ’ΠΠΠΠ¦ΠΠ― β ΠΡΠΎΡΠ΅ΡΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΠΌΠΈ ΡΠ΅ΡΡΠΌΠΈ ΠΌΠ°ΡΡΡΠ°Π±Π° ΠΏΡΠ΅Π΄ΠΏΡΠΈΡΡΠΈΡ.
π’ Enterprise ΠΊΠ»Π°ΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·Π°ΡΠΈΠΈ
WarehouseIntelligenceEngine
ΠΠ½ΡΠ΅Π»Π»Π΅ΠΊΡΡΠ°Π»ΡΠ½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° Π°Π½Π°Π»ΠΈΠ·Π° ΠΈ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Ρ ΠΌΠ°ΡΠΈΠ½Π½ΡΠΌ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ΠΌ.
import { WarehouseApi } from 'daytona-ozon-seller-api';
/**
* Π‘ΠΈΡΡΠ΅ΠΌΠ° ΠΈΠ½ΡΠ΅Π»Π»Π΅ΠΊΡΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΡ
ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ
* Enterprise ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ ΠΊΡΡΠΏΠ½ΡΡ
ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΡ
ΡΠ΅ΡΠ΅ΠΉ
*/
class WarehouseIntelligenceEngine {
private warehouseApi: WarehouseApi;
private analyticsCache: Map<string, AnalyticsData> = new Map();
private predictionModel: PerformancePredictionModel;
private alertSystem: WarehouseAlertSystem;
constructor(httpClient: HttpClient, config: IntelligenceConfig) {
this.warehouseApi = new WarehouseApi(httpClient);
this.predictionModel = new PerformancePredictionModel(config.mlConfig);
this.alertSystem = new WarehouseAlertSystem(config.alertConfig);
}
/**
* ΠΠΎΠΌΠΏΠ»Π΅ΠΊΡΠ½ΡΠΉ Π°Π½Π°Π»ΠΈΠ· Π²ΡΠ΅ΠΉ ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ
* ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π΅ΠΆΠ΅Π΄Π½Π΅Π²Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΠΈ ΠΏΠ»Π°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΡ
*/
async performNetworkAnalysis(): Promise<NetworkAnalysisResult> {
const warehouses = await this.warehouseApi.getWarehousesList();
if (!warehouses.result) {
throw new Error('ΠΠ΅ ΡΠ΄Π°Π»ΠΎΡΡ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄Π°Π½Π½ΡΠ΅ ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ');
}
const analysisResult: NetworkAnalysisResult = {
timestamp: new Date().toISOString(),
totalWarehouses: warehouses.result.length,
networkHealth: {
healthy: 0,
warning: 0,
critical: 0
},
performanceMetrics: {
averageCapacityUtilization: 0,
networkResilience: 0,
operationalEfficiency: 0
},
predictedIssues: [],
optimizationOpportunities: [],
regionalDistribution: new Map(),
capacityForecast: []
};
// ΠΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΡΠΉ Π°Π½Π°Π»ΠΈΠ· ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠΊΠ»Π°Π΄Π°
const warehouseAnalyses = await Promise.all(
warehouses.result.map(warehouse => this.analyzeWarehousePerformance(warehouse))
);
// ΠΠ³ΡΠ΅Π³Π°ΡΠΈΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² Π°Π½Π°Π»ΠΈΠ·Π°
warehouseAnalyses.forEach(analysis => {
// ΠΡΠ΅Π½ΠΊΠ° Π·Π΄ΠΎΡΠΎΠ²ΡΡ ΡΠ΅ΡΠΈ
switch (analysis.healthStatus) {
case 'healthy':
analysisResult.networkHealth.healthy++;
break;
case 'warning':
analysisResult.networkHealth.warning++;
break;
case 'critical':
analysisResult.networkHealth.critical++;
break;
}
// Π Π΅Π³ΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ΅ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅
const region = this.determineWarehouseRegion(analysis.warehouse);
const regionCount = analysisResult.regionalDistribution.get(region) || 0;
analysisResult.regionalDistribution.set(region, regionCount + 1);
});
// Π Π°ΡΡΠ΅Ρ ΠΎΠ±ΡΠΈΡ
ΠΌΠ΅ΡΡΠΈΠΊ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ
analysisResult.performanceMetrics = this.calculateNetworkPerformance(warehouseAnalyses);
// ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΠΏΡΠΎΠ³Π½ΠΎΠ·ΠΎΠ² ΠΈ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠΉ
analysisResult.predictedIssues = await this.predictPotentialIssues(warehouseAnalyses);
analysisResult.optimizationOpportunities = this.identifyOptimizations(warehouseAnalyses);
analysisResult.capacityForecast = this.generateCapacityForecast(warehouseAnalyses);
// ΠΡΠΏΡΠ°Π²ΠΊΠ° ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
await this.alertSystem.processAnalysisResult(analysisResult);
// ΠΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² Π΄Π»Ρ Π±ΡΡΡΡΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ°
this.cacheAnalysisResult(analysisResult);
return analysisResult;
}
/**
* ΠΠ»ΡΠ±ΠΎΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ· ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠΊΠ»Π°Π΄Π°
*/
private async analyzeWarehousePerformance(warehouse: Warehouse): Promise<WarehouseAnalysis> {
const analysis: WarehouseAnalysis = {
warehouse,
healthStatus: 'healthy',
performanceScore: 0,
deliveryMethods: [],
capacityMetrics: {
utilizationRate: 0,
throughputEfficiency: 0,
scalabilityIndex: 0
},
riskFactors: [],
recommendations: []
};
// ΠΠ½Π°Π»ΠΈΠ· ΡΡΠ°ΡΡΡΠ° ΠΈ Π±Π°Π·ΠΎΠ²ΡΡ
ΠΏΠΎΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ
analysis.healthStatus = this.evaluateWarehouseHealth(warehouse);
// ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΈ Π°Π½Π°Π»ΠΈΠ· ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Π΄ΠΎΡΡΠ°Π²ΠΊΠΈ
if (warehouse.warehouse_id && warehouse.status === 'created') {
const deliveryMethods = await this.getDeliveryMethodsWithAnalysis(warehouse.warehouse_id);
analysis.deliveryMethods = deliveryMethods;
// Π Π°ΡΡΠ΅Ρ ΠΏΠΎΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Π΄ΠΎΡΡΠ°Π²ΠΊΠΈ
analysis.performanceScore = this.calculatePerformanceScore(warehouse, deliveryMethods);
analysis.capacityMetrics = this.calculateCapacityMetrics(warehouse, deliveryMethods);
}
// ΠΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΡΠΈΡΠΊΠΎΠ²
analysis.riskFactors = this.identifyRiskFactors(warehouse, analysis.deliveryMethods);
// ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΡΠ½ΡΡ
ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠΉ
analysis.recommendations = this.generateWarehouseRecommendations(analysis);
return analysis;
}
/**
* Π‘ΠΈΡΡΠ΅ΠΌΠ° ΠΏΡΠΎΠ³Π½ΠΎΠ·ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ML
*/
private async predictPotentialIssues(analyses: WarehouseAnalysis[]): Promise<PredictedIssue[]> {
const issues: PredictedIssue[] = [];
for (const analysis of analyses) {
// ΠΡΠΎΠ³Π½ΠΎΠ· Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΈΡΡΠΎΡΠΈΡΠ΅ΡΠΊΠΈΡ
Π΄Π°Π½Π½ΡΡ
const prediction = await this.predictionModel.predictIssues({
warehouseId: analysis.warehouse.warehouse_id!,
currentMetrics: analysis.capacityMetrics,
riskFactors: analysis.riskFactors,
historicalData: this.getHistoricalData(analysis.warehouse.warehouse_id!)
});
if (prediction.issuesProbability > 0.7) {
issues.push({
warehouseId: analysis.warehouse.warehouse_id!,
warehouseName: analysis.warehouse.name || `Π‘ΠΊΠ»Π°Π΄ ${analysis.warehouse.warehouse_id}`,
issueType: prediction.mostLikelyIssue,
probability: prediction.issuesProbability,
estimatedImpact: prediction.estimatedImpact,
recommendedActions: prediction.recommendedActions,
timeframe: prediction.timeframe
});
}
}
return issues.sort((a, b) => b.probability - a.probability);
}
/**
* ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΎΠ½Π½ΡΡ
Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ
*/
private identifyOptimizations(analyses: WarehouseAnalysis[]): Promise<OptimizationOpportunity[]> {
const opportunities: OptimizationOpportunity[] = [];
// ΠΠ½Π°Π»ΠΈΠ· Π±Π°Π»Π°Π½ΡΠΈΡΠΎΠ²ΠΊΠΈ Π½Π°Π³ΡΡΠ·ΠΊΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΊΠ»Π°Π΄Π°ΠΌΠΈ
const loadBalancingOpp = this.analyzeLoadBalancing(analyses);
if (loadBalancingOpp) opportunities.push(loadBalancingOpp);
// ΠΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Π΄ΠΎΡΡΠ°Π²ΠΊΠΈ
const deliveryOptimizations = this.analyzeDeliveryOptimization(analyses);
opportunities.push(...deliveryOptimizations);
// Π Π΅Π³ΠΈΠΎΠ½Π°Π»ΡΠ½Π°Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ
const regionalOpt = this.analyzeRegionalOptimization(analyses);
if (regionalOpt) opportunities.push(regionalOpt);
// ΠΡΠΎΠ³Π½ΠΎΠ·ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎΡΡΠΈ Π² ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠΈ
const expansionNeeds = this.analyzeExpansionNeeds(analyses);
if (expansionNeeds) opportunities.push(expansionNeeds);
return Promise.resolve(opportunities.sort((a, b) => b.priority - a.priority));
}
private evaluateWarehouseHealth(warehouse: Warehouse): 'healthy' | 'warning' | 'critical' {
// ΠΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΡΠ°ΡΡΡ
if (['error', 'blocked'].includes(warehouse.status || '')) {
return 'critical';
}
// ΠΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅
if (['disabled_due_to_limit', 'disabled'].includes(warehouse.status || '')) {
return 'warning';
}
// ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π΄Π»Ρ Π°ΠΊΡΠΈΠ²Π½ΡΡ
ΡΠΊΠ»Π°Π΄ΠΎΠ²
if (warehouse.status === 'created') {
const warningFactors = [];
if (warehouse.is_karantin) warningFactors.push('quarantine');
if (warehouse.has_postings_limit && (warehouse.postings_limit || 0) < 10) {
warningFactors.push('low_limit');
}
if (!warehouse.working_days || warehouse.working_days.length < 5) {
warningFactors.push('limited_schedule');
}
return warningFactors.length > 1 ? 'warning' : 'healthy';
}
return 'warning'; // ΠΠΎΠ²ΡΠ΅ ΠΈΠ»ΠΈ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠ΅ ΡΡΠ°ΡΡΡΡ
}
private async getDeliveryMethodsWithAnalysis(warehouseId: number): Promise<AnalyzedDeliveryMethod[]> {
const allMethods: AnalyzedDeliveryMethod[] = [];
let offset = 0;
const limit = 50;
do {
const response = await this.warehouseApi.getDeliveryMethods({
limit,
offset,
filter: { warehouse_id: warehouseId }
});
if (response.result) {
const analyzedMethods = response.result.map(method => ({
...method,
analysisData: {
performanceRating: this.rateMethodPerformance(method),
reliabilityScore: this.calculateReliabilityScore(method),
costEfficiencyIndex: this.calculateCostEfficiency(method)
}
}));
allMethods.push(...analyzedMethods);
}
if (!response.has_next) break;
offset += limit;
} while (true);
return allMethods;
}
private rateMethodPerformance(method: WarehouseDeliveryMethod): number {
let score = 100;
// Π¨ΡΡΠ°Ρ Π·Π° Π½Π΅Π°ΠΊΡΠΈΠ²Π½ΡΠΉ ΡΡΠ°ΡΡΡ
if (method.status !== 'ACTIVE') score -= 50;
// ΠΡΠ΅Π½ΠΊΠ° SLA
const sla = method.sla_cut_in || 0;
if (sla > 240) score -= 20; // > 4 ΡΠ°ΡΠΎΠ²
else if (sla > 120) score -= 10; // > 2 ΡΠ°ΡΠΎΠ²
else if (sla < 60) score += 10; // < 1 ΡΠ°ΡΠ°
// ΠΠΎΠ½ΡΡ Π·Π° Π½Π°Π»ΠΈΡΠΈΠ΅ cutoff Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ
if (method.cutoff) score += 5;
return Math.max(0, Math.min(100, score));
}
private calculateReliabilityScore(method: WarehouseDeliveryMethod): number {
// ΠΠ°Π·ΠΎΠ²Π°Ρ ΠΎΡΠ΅Π½ΠΊΠ° Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡΠΈ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΡΡΠ°ΡΡΡΠ°
let score = 50;
switch (method.status) {
case 'ACTIVE':
score = 90;
break;
case 'NEW':
score = 60;
break;
case 'EDITED':
score = 70;
break;
case 'DISABLED':
score = 10;
break;
}
// ΠΡΡΠΎΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΡΡΠΈ (Π΅ΡΠ»ΠΈ Π΄ΠΎΡΡΡΠΏΠ½Ρ)
const historicalReliability = this.getHistoricalReliability(method.id);
if (historicalReliability) {
score = (score + historicalReliability) / 2;
}
return score;
}
private calculateCostEfficiency(method: WarehouseDeliveryMethod): number {
// ΠΡΠΈΠΌΠ΅ΡΠ½Π°Ρ ΠΎΡΠ΅Π½ΠΊΠ° cost-efficiency
// Π ΡΠ΅Π°Π»ΡΠ½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π·Π΄Π΅ΡΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΎ ΡΡΠΎΠΈΠΌΠΎΡΡΠΈ
let efficiency = 70;
// ΠΠΎΠ»Π΅Π΅ Π±ΡΡΡΡΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΎΠ±ΡΡΠ½ΠΎ Π΄ΠΎΡΠΎΠΆΠ΅
const sla = method.sla_cut_in || 120;
if (sla < 60) efficiency -= 10; // ΠΡΡΡΡΠΎ Π½ΠΎ Π΄ΠΎΡΠΎΠ³ΠΎ
if (sla > 240) efficiency += 10; // ΠΠ΅Π΄Π»Π΅Π½Π½ΠΎ Π½ΠΎ Π΄Π΅ΡΠ΅Π²ΠΎ
return Math.max(0, Math.min(100, efficiency));
}
}
// Π’ΠΈΠΏΡ Π΄Π»Ρ ΡΠΈΡΡΠ΅ΠΌΡ Π°Π½Π°Π»ΠΈΡΠΈΠΊΠΈ
interface NetworkAnalysisResult {
timestamp: string;
totalWarehouses: number;
networkHealth: {
healthy: number;
warning: number;
critical: number;
};
performanceMetrics: {
averageCapacityUtilization: number;
networkResilience: number;
operationalEfficiency: number;
};
predictedIssues: PredictedIssue[];
optimizationOpportunities: OptimizationOpportunity[];
regionalDistribution: Map<string, number>;
capacityForecast: CapacityForecast[];
}
interface WarehouseAnalysis {
warehouse: Warehouse;
healthStatus: 'healthy' | 'warning' | 'critical';
performanceScore: number;
deliveryMethods: AnalyzedDeliveryMethod[];
capacityMetrics: {
utilizationRate: number;
throughputEfficiency: number;
scalabilityIndex: number;
};
riskFactors: string[];
recommendations: string[];
}
interface AnalyzedDeliveryMethod extends WarehouseDeliveryMethod {
analysisData: {
performanceRating: number;
reliabilityScore: number;
costEfficiencyIndex: number;
};
}
interface PredictedIssue {
warehouseId: number;
warehouseName: string;
issueType: string;
probability: number;
estimatedImpact: 'low' | 'medium' | 'high' | 'critical';
recommendedActions: string[];
timeframe: 'immediate' | 'short_term' | 'medium_term' | 'long_term';
}
interface OptimizationOpportunity {
type: 'load_balancing' | 'delivery_optimization' | 'regional_expansion' | 'cost_reduction';
title: string;
description: string;
priority: number;
estimatedBenefit: string;
implementationComplexity: 'low' | 'medium' | 'high';
requiredActions: string[];
}
interface CapacityForecast {
period: string;
expectedDemand: number;
currentCapacity: number;
capacityGap: number;
recommendedActions: string[];
}
Π‘ΠΈΡΡΠ΅ΠΌΠ° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
/**
* Enterprise ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ ΠΎ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ
*/
class WarehouseAlertSystem {
private config: AlertConfig;
private notificationChannels: NotificationChannel[];
constructor(config: AlertConfig) {
this.config = config;
this.notificationChannels = this.initializeChannels(config);
}
async processAnalysisResult(result: NetworkAnalysisResult): Promise<void> {
const alerts = this.generateAlerts(result);
for (const alert of alerts) {
await this.sendAlert(alert);
}
}
private generateAlerts(result: NetworkAnalysisResult): WarehouseAlert[] {
const alerts: WarehouseAlert[] = [];
// ΠΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΡΠ΅ΡΠΈ
if (result.networkHealth.critical > 0) {
alerts.push({
level: 'critical',
type: 'network_health',
title: `ΠΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ`,
message: `${result.networkHealth.critical} ΡΠΊΠ»Π°Π΄(ΠΎΠ²) Π² ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ`,
data: result,
timestamp: new Date().toISOString()
});
}
// ΠΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π²ΡΡΠΎΠΊΠΎΠΉ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠΈ
const highProbabilityIssues = result.predictedIssues.filter(issue => issue.probability > 0.8);
if (highProbabilityIssues.length > 0) {
alerts.push({
level: 'warning',
type: 'predicted_issues',
title: `ΠΡΠΎΠ³Π½ΠΎΠ·ΠΈΡΡΠ΅ΠΌΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π²ΡΡΠΎΠΊΠΎΠΉ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠΈ`,
message: `${highProbabilityIssues.length} ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ
ΠΏΡΠΎΠ±Π»Π΅ΠΌ ΡΡΠ΅Π±ΡΡΡ Π²Π½ΠΈΠΌΠ°Π½ΠΈΡ`,
data: highProbabilityIssues,
timestamp: new Date().toISOString()
});
}
// ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ Π²ΡΡΠΎΠΊΠΎΠ³ΠΎ ΠΏΡΠΈΠΎΡΠΈΡΠ΅ΡΠ°
const highPriorityOptimizations = result.optimizationOpportunities.filter(opp => opp.priority > 8);
if (highPriorityOptimizations.length > 0) {
alerts.push({
level: 'info',
type: 'optimization_opportunities',
title: `ΠΡΡΠ²Π»Π΅Π½Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ`,
message: `${highPriorityOptimizations.length} Π²ΡΡΠΎΠΊΠΎΠΏΡΠΈΠΎΡΠΈΡΠ΅ΡΠ½ΡΡ
Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ ΡΠ»ΡΡΡΠ΅Π½ΠΈΡ`,
data: highPriorityOptimizations,
timestamp: new Date().toISOString()
});
}
return alerts;
}
private async sendAlert(alert: WarehouseAlert): Promise<void> {
const channelsForLevel = this.notificationChannels.filter(
channel => channel.alertLevels.includes(alert.level)
);
await Promise.all(
channelsForLevel.map(channel => this.sendToChannel(channel, alert))
);
}
private async sendToChannel(channel: NotificationChannel, alert: WarehouseAlert): Promise<void> {
try {
await channel.send(this.formatAlertForChannel(channel, alert));
} catch (error) {
console.error(`Failed to send alert to ${channel.type}:`, error);
}
}
private formatAlertForChannel(channel: NotificationChannel, alert: WarehouseAlert): string {
switch (channel.type) {
case 'slack':
return this.formatSlackMessage(alert);
case 'email':
return this.formatEmailMessage(alert);
case 'telegram':
return this.formatTelegramMessage(alert);
case 'webhook':
return JSON.stringify(alert);
default:
return alert.message;
}
}
private formatSlackMessage(alert: WarehouseAlert): string {
const emoji = {
'critical': 'π¨',
'warning': 'β οΈ',
'info': 'βΉοΈ'
};
return `${emoji[alert.level]} *${alert.title}*\n${alert.message}\n_${alert.timestamp}_`;
}
private formatEmailMessage(alert: WarehouseAlert): string {
return `
<h2>${alert.title}</h2>
<p><strong>Π£ΡΠΎΠ²Π΅Π½Ρ:</strong> ${alert.level}</p>
<p><strong>Π‘ΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅:</strong> ${alert.message}</p>
<p><strong>ΠΡΠ΅ΠΌΡ:</strong> ${alert.timestamp}</p>
<hr>
<pre>${JSON.stringify(alert.data, null, 2)}</pre>
`;
}
private formatTelegramMessage(alert: WarehouseAlert): string {
const emoji = {
'critical': 'π¨',
'warning': 'β οΈ',
'info': 'βΉοΈ'
};
return `${emoji[alert.level]} <b>${alert.title}</b>\n\n${alert.message}\n\n<i>${alert.timestamp}</i>`;
}
private initializeChannels(config: AlertConfig): NotificationChannel[] {
const channels: NotificationChannel[] = [];
if (config.slack?.enabled) {
channels.push(new SlackNotificationChannel(config.slack));
}
if (config.email?.enabled) {
channels.push(new EmailNotificationChannel(config.email));
}
if (config.telegram?.enabled) {
channels.push(new TelegramNotificationChannel(config.telegram));
}
if (config.webhook?.enabled) {
channels.push(new WebhookNotificationChannel(config.webhook));
}
return channels;
}
}
// Π’ΠΈΠΏΡ Π΄Π»Ρ ΡΠΈΡΡΠ΅ΠΌΡ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
interface WarehouseAlert {
level: 'critical' | 'warning' | 'info';
type: string;
title: string;
message: string;
data: any;
timestamp: string;
}
interface AlertConfig {
slack?: SlackConfig & { enabled: boolean };
email?: EmailConfig & { enabled: boolean };
telegram?: TelegramConfig & { enabled: boolean };
webhook?: WebhookConfig & { enabled: boolean };
}
interface NotificationChannel {
type: string;
alertLevels: Array<'critical' | 'warning' | 'info'>;
send(message: string): Promise<void>;
}
Π‘ΠΈΡΡΠ΅ΠΌΠ° Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°
/**
* Π‘Π΅ΡΠ²ΠΈΡ Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ
* Π Π°Π±ΠΎΡΠ°Π΅Ρ Π² ΡΠΎΠ½ΠΎΠ²ΠΎΠΌ ΡΠ΅ΠΆΠΈΠΌΠ΅, Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΡΠ²Π»ΡΠ΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ
*/
class ContinuousWarehouseMonitor {
private warehouseApi: WarehouseApi;
private intelligenceEngine: WarehouseIntelligenceEngine;
private isRunning: boolean = false;
private monitoringInterval: number;
constructor(
httpClient: HttpClient,
intelligenceEngine: WarehouseIntelligenceEngine,
config: MonitoringConfig
) {
this.warehouseApi = new WarehouseApi(httpClient);
this.intelligenceEngine = intelligenceEngine;
this.monitoringInterval = config.intervalMinutes * 60 * 1000;
}
/**
* ΠΠ°ΠΏΡΡΠΊ Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°
*/
async startMonitoring(): Promise<void> {
if (this.isRunning) {
console.warn('ΠΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ ΡΠΆΠ΅ Π·Π°ΠΏΡΡΠ΅Π½');
return;
}
this.isRunning = true;
console.log('π ΠΠ°ΠΏΡΡΠΊ Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ...');
// ΠΠ΅ΡΠ²ΠΈΡΠ½ΡΠΉ Π°Π½Π°Π»ΠΈΠ·
await this.performMonitoringCycle();
// ΠΠ»Π°Π½ΠΈΡΡΠ΅ΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΡΠΈΠΊΠ»Ρ
this.scheduleNextCycle();
}
/**
* ΠΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°
*/
stopMonitoring(): void {
this.isRunning = false;
console.log('βΉοΈ ΠΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ ΠΎΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½');
}
private async performMonitoringCycle(): Promise<void> {
try {
console.log(`π ΠΠ°ΡΠ°Π»ΠΎ ΡΠΈΠΊΠ»Π° ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°: ${new Date().toISOString()}`);
// ΠΠΎΠ»Π½ΡΠΉ Π°Π½Π°Π»ΠΈΠ· ΡΠ΅ΡΠΈ
const analysis = await this.intelligenceEngine.performNetworkAnalysis();
// ΠΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ²
this.logMonitoringResults(analysis);
// ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ
await this.checkForCriticalChanges(analysis);
console.log(`β
Π¦ΠΈΠΊΠ» ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° Π·Π°Π²Π΅ΡΡΠ΅Π½: ${new Date().toISOString()}`);
} catch (error) {
console.error('β ΠΡΠΈΠ±ΠΊΠ° Π² ΡΠΈΠΊΠ»Π΅ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°:', error);
// Π£Π²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ΅ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°
await this.notifyMonitoringError(error);
}
}
private scheduleNextCycle(): void {
if (!this.isRunning) return;
setTimeout(() => {
if (this.isRunning) {
this.performMonitoringCycle().then(() => {
this.scheduleNextCycle();
});
}
}, this.monitoringInterval);
}
private logMonitoringResults(analysis: NetworkAnalysisResult): void {
const summary = {
timestamp: analysis.timestamp,
totalWarehouses: analysis.totalWarehouses,
healthSummary: {
healthy: analysis.networkHealth.healthy,
warning: analysis.networkHealth.warning,
critical: analysis.networkHealth.critical
},
performanceScore: analysis.performanceMetrics.operationalEfficiency,
predictedIssuesCount: analysis.predictedIssues.length,
optimizationOpportunitiesCount: analysis.optimizationOpportunities.length
};
console.log('π Π Π΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°:', JSON.stringify(summary, null, 2));
}
private async checkForCriticalChanges(analysis: NetworkAnalysisResult): Promise<void> {
// Π‘ΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Ρ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΠΌΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°ΠΌΠΈ Π΄Π»Ρ Π²ΡΡΠ²Π»Π΅Π½ΠΈΡ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
const previousAnalysis = this.getPreviousAnalysis();
if (previousAnalysis) {
const criticalChanges = this.identifyCriticalChanges(previousAnalysis, analysis);
if (criticalChanges.length > 0) {
console.warn('β οΈ ΠΠ±Π½Π°ΡΡΠΆΠ΅Π½Ρ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ:', criticalChanges);
await this.handleCriticalChanges(criticalChanges);
}
}
// Π‘ΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° Π΄Π»Ρ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ
this.savePreviousAnalysis(analysis);
}
private identifyCriticalChanges(previous: NetworkAnalysisResult, current: NetworkAnalysisResult): CriticalChange[] {
const changes: CriticalChange[] = [];
// Π£Π²Π΅Π»ΠΈΡΠ΅Π½ΠΈΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΡΠΊΠ»Π°Π΄ΠΎΠ²
if (current.networkHealth.critical > previous.networkHealth.critical) {
changes.push({
type: 'critical_warehouses_increase',
severity: 'high',
description: `ΠΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΡΠΊΠ»Π°Π΄ΠΎΠ² ΡΠ²Π΅Π»ΠΈΡΠΈΠ»ΠΎΡΡ Ρ ${previous.networkHealth.critical} Π΄ΠΎ ${current.networkHealth.critical}`,
impact: 'immediate'
});
}
// Π Π΅Π·ΠΊΠΎΠ΅ ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΉ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ
const efficiencyDrop = previous.performanceMetrics.operationalEfficiency - current.performanceMetrics.operationalEfficiency;
if (efficiencyDrop > 20) {
changes.push({
type: 'efficiency_drop',
severity: 'medium',
description: `ΠΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ ΡΠΏΠ°Π»Π° Π½Π° ${efficiencyDrop.toFixed(1)}%`,
impact: 'short_term'
});
}
// ΠΠΎΡΠ²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΡΡ
ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΏΡΠΎΠ±Π»Π΅ΠΌ
const newCriticalIssues = current.predictedIssues.filter(
issue => issue.probability > 0.8 && issue.estimatedImpact === 'critical'
);
if (newCriticalIssues.length > 0) {
changes.push({
type: 'new_critical_predictions',
severity: 'high',
description: `ΠΠΎΡΠ²ΠΈΠ»ΠΈΡΡ Π½ΠΎΠ²ΡΠ΅ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΡΠΎΠ³Π½ΠΎΠ·Ρ: ${newCriticalIssues.length}`,
impact: 'medium_term'
});
}
return changes;
}
private async handleCriticalChanges(changes: CriticalChange[]): Promise<void> {
// ΠΡΠΏΡΠ°Π²ΠΊΠ° ΡΠΊΡΡΡΠ΅Π½Π½ΡΡ
ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
for (const change of changes) {
if (change.severity === 'high') {
await this.sendEmergencyNotification(change);
}
}
// ΠΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π°
console.log('π¨ ΠΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π·Π°ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Ρ:', changes);
}
private async sendEmergencyNotification(change: CriticalChange): Promise<void> {
// Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠΊΡΡΡΠ΅Π½Π½ΡΡ
ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
console.log('π¨ ΠΠΊΡΡΡΠ΅Π½Π½ΠΎΠ΅ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅:', change.description);
}
// ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΡ/Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΡ
ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² Π°Π½Π°Π»ΠΈΠ·Π°
private getPreviousAnalysis(): NetworkAnalysisResult | null {
// Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΠΈΠ· ΠΊΡΡΠ°/Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ
return null; // ΠΠ°Π³Π»ΡΡΠΊΠ°
}
private savePreviousAnalysis(analysis: NetworkAnalysisResult): void {
// Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΡ Π² ΠΊΡΡ/Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ
console.log('πΎ Π‘ΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ² Π°Π½Π°Π»ΠΈΠ·Π° Π΄Π»Ρ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΡΠΈΠΊΠ»Π°');
}
private async notifyMonitoringError(error: any): Promise<void> {
console.error('π¨ ΠΡΠΈΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΎΡΠΈΠ±ΠΊΠ° ΡΠΈΡΡΠ΅ΠΌΡ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°:', error);
// ΠΠ΄Π΅ΡΡ Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΠ° ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠ°ΡΠΎΡΠ°ΠΌ
}
}
// ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΠΈΠΏΡ
interface CriticalChange {
type: string;
severity: 'low' | 'medium' | 'high';
description: string;
impact: 'immediate' | 'short_term' | 'medium_term' | 'long_term';
}
interface MonitoringConfig {
intervalMinutes: number;
alertThresholds: {
criticalWarehousesThreshold: number;
efficiencyDropThreshold: number;
predictionProbabilityThreshold: number;
};
emergencyContacts: string[];
}
π Π‘ΠΈΡΡΠ΅ΠΌΠ° ΠΎΡΡΠ΅ΡΠ½ΠΎΡΡΠΈ ΠΈ Π΄Π°ΡΠ±ΠΎΡΠ΄Ρ
ΠΠ΅Π½Π΅ΡΠ°ΡΠΎΡ ΠΈΡΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΎΡΡΠ΅ΡΠΎΠ²
/**
* ΠΠ΅Π½Π΅ΡΠ°ΡΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΡ
ΠΎΡΡΠ΅ΡΠΎΠ² Π΄Π»Ρ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²Π°
*/
class ExecutiveReportGenerator {
private intelligenceEngine: WarehouseIntelligenceEngine;
constructor(intelligenceEngine: WarehouseIntelligenceEngine) {
this.intelligenceEngine = intelligenceEngine;
}
/**
* Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π΅ΠΆΠ΅Π½Π΅Π΄Π΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΎΡΡΠ΅ΡΠ° Π΄Π»Ρ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²Π°
*/
async generateWeeklyExecutiveSummary(): Promise<ExecutiveReport> {
const networkAnalysis = await this.intelligenceEngine.performNetworkAnalysis();
const report: ExecutiveReport = {
reportDate: new Date().toISOString(),
period: 'weekly',
executiveSummary: this.createExecutiveSummary(networkAnalysis),
keyMetrics: this.extractKeyMetrics(networkAnalysis),
riskAssessment: this.createRiskAssessment(networkAnalysis),
strategicRecommendations: this.createStrategicRecommendations(networkAnalysis),
financialImpact: this.estimateFinancialImpact(networkAnalysis),
nextSteps: this.defineNextSteps(networkAnalysis)
};
return report;
}
private createExecutiveSummary(analysis: NetworkAnalysisResult): string {
const totalWarehouses = analysis.totalWarehouses;
const healthyPercent = Math.round((analysis.networkHealth.healthy / totalWarehouses) * 100);
const efficiency = analysis.performanceMetrics.operationalEfficiency;
return `
ΠΠ° ΠΎΡΡΠ΅ΡΠ½ΡΠΉ ΠΏΠ΅ΡΠΈΠΎΠ΄ ΡΠΊΠ»Π°Π΄ΡΠΊΠ°Ρ ΡΠ΅ΡΡ ΠΏΡΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΠΎΠ²Π°Π»Π° ${efficiency > 75 ? 'Π²ΡΡΠΎΠΊΡΡ' : efficiency > 50 ? 'ΡΠ΄ΠΎΠ²Π»Π΅ΡΠ²ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΡΡ' : 'Π½ΠΈΠ·ΠΊΡΡ'} ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΡΡ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ (${efficiency.toFixed(1)}%).
ΠΠ· ${totalWarehouses} ΡΠΊΠ»Π°Π΄ΠΎΠ² ${healthyPercent}% Π½Π°Ρ
ΠΎΠ΄ΡΡΡΡ Π² Π½ΠΎΡΠΌΠ°Π»ΡΠ½ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ.
${analysis.networkHealth.critical > 0 ? `ΠΠΠΠΠΠΠΠ: ${analysis.networkHealth.critical} ΡΠΊΠ»Π°Π΄ΠΎΠ² ΡΡΠ΅Π±ΡΡΡ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ³ΠΎ Π²ΠΌΠ΅ΡΠ°ΡΠ΅Π»ΡΡΡΠ²Π°.` : ''}
Π‘ΠΈΡΡΠ΅ΠΌΠ° ΠΏΡΠΎΠ³Π½ΠΎΠ·ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π²ΡΡΠ²ΠΈΠ»Π° ${analysis.predictedIssues.length} ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ
ΠΏΡΠΎΠ±Π»Π΅ΠΌ,
${analysis.optimizationOpportunities.length} Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ Π΄Π»Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ.
${analysis.optimizationOpportunities.length > 0 ? `Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π²ΡΡΠ²Π»Π΅Π½Π½ΡΡ
ΡΠ»ΡΡΡΠ΅Π½ΠΈΠΉ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ½Π΅ΡΡΠΈ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΏΠΎΠ»ΡΠ·Ρ Π΄Π»Ρ Π±ΠΈΠ·Π½Π΅ΡΠ°.` : ''}
`.trim();
}
private extractKeyMetrics(analysis: NetworkAnalysisResult): KeyMetrics {
return {
networkHealth: {
overallScore: this.calculateOverallHealthScore(analysis.networkHealth),
trend: 'improving', // ΠΠ΄Π΅ΡΡ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Ρ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΠΌ ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΎΠΌ
healthyWarehouses: analysis.networkHealth.healthy,
totalWarehouses: analysis.totalWarehouses
},
performance: {
operationalEfficiency: analysis.performanceMetrics.operationalEfficiency,
capacityUtilization: analysis.performanceMetrics.averageCapacityUtilization,
networkResilience: analysis.performanceMetrics.networkResilience
},
predictiveInsights: {
highRiskIssues: analysis.predictedIssues.filter(issue => issue.probability > 0.8).length,
totalPredictions: analysis.predictedIssues.length,
optimizationOpportunities: analysis.optimizationOpportunities.length
}
};
}
private createRiskAssessment(analysis: NetworkAnalysisResult): RiskAssessment {
const criticalRisks = analysis.predictedIssues.filter(
issue => issue.estimatedImpact === 'critical' && issue.probability > 0.7
);
const highRisks = analysis.predictedIssues.filter(
issue => issue.estimatedImpact === 'high' && issue.probability > 0.6
);
return {
overallRiskLevel: this.calculateOverallRiskLevel(analysis),
criticalRisks: criticalRisks.map(risk => ({
description: `${risk.warehouseName}: ${risk.issueType}`,
probability: risk.probability,
impact: risk.estimatedImpact,
timeframe: risk.timeframe,
mitigationActions: risk.recommendedActions
})),
emergingRisks: highRisks.map(risk => ({
description: `${risk.warehouseName}: ${risk.issueType}`,
probability: risk.probability,
impact: risk.estimatedImpact,
timeframe: risk.timeframe
})),
riskMitigationStatus: this.assessRiskMitigationStatus(analysis)
};
}
private createStrategicRecommendations(analysis: NetworkAnalysisResult): StrategicRecommendation[] {
const recommendations: StrategicRecommendation[] = [];
// ΠΡΡΠΎΠΊΠΎΠΏΡΠΈΠΎΡΠΈΡΠ΅ΡΠ½ΡΠ΅ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠΈ
const highPriorityOpps = analysis.optimizationOpportunities.filter(opp => opp.priority > 8);
highPriorityOpps.forEach(opp => {
recommendations.push({
category: this.categorizePriority(opp.priority),
title: opp.title,
description: opp.description,
expectedBenefit: opp.estimatedBenefit,
implementationComplexity: opp.implementationComplexity,
timeline: this.estimateImplementationTimeline(opp.implementationComplexity),
requiredResources: this.estimateRequiredResources(opp),
strategicAlignment: this.assessStrategicAlignment(opp)
});
});
// ΠΠΎΠ»Π³ΠΎΡΡΠΎΡΠ½ΡΠ΅ ΡΡΡΠ°ΡΠ΅Π³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠΈ
if (analysis.capacityForecast.some(forecast => forecast.capacityGap > 0)) {
recommendations.push({
category: 'strategic',
title: 'ΠΠ»Π°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΡ
ΠΌΠΎΡΠ½ΠΎΡΡΠ΅ΠΉ',
description: 'ΠΡΠΎΠ³Π½ΠΎΠ·ΠΈΡΡΠ΅ΡΡΡ Π½Π΅Ρ
Π²Π°ΡΠΊΠ° ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΡ
ΠΌΠΎΡΠ½ΠΎΡΡΠ΅ΠΉ Π² ΡΡΠ΅Π΄Π½Π΅ΡΡΠΎΡΠ½ΠΎΠΉ ΠΏΠ΅ΡΡΠΏΠ΅ΠΊΡΠΈΠ²Π΅',
expectedBenefit: 'ΠΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠ° Π±ΠΈΠ·Π½Π΅ΡΠ° ΠΈ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΡΠ·ΠΊΠΈΡ
ΠΌΠ΅ΡΡ',
implementationComplexity: 'high',
timeline: '6-12 ΠΌΠ΅ΡΡΡΠ΅Π²',
requiredResources: ['ΠΠ°ΠΏΠΈΡΠ°Π»ΡΠ½ΡΠ΅ ΠΈΠ½Π²Π΅ΡΡΠΈΡΠΈΠΈ', 'ΠΠΎΠΌΠ°Π½Π΄Π° ΠΏΡΠΎΠ΅ΠΊΡΠ°', 'ΠΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ°'],
strategicAlignment: 'high'
});
}
return recommendations.sort((a, b) => {
const priorityOrder = { 'critical': 3, 'strategic': 2, 'operational': 1 };
return priorityOrder[b.category] - priorityOrder[a.category];
});
}
}
// Π’ΠΈΠΏΡ Π΄Π»Ρ ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΡΡΠ΅ΡΠ½ΠΎΡΡΠΈ
interface ExecutiveReport {
reportDate: string;
period: 'weekly' | 'monthly' | 'quarterly';
executiveSummary: string;
keyMetrics: KeyMetrics;
riskAssessment: RiskAssessment;
strategicRecommendations: StrategicRecommendation[];
financialImpact: FinancialImpact;
nextSteps: NextStep[];
}
interface KeyMetrics {
networkHealth: {
overallScore: number;
trend: 'improving' | 'stable' | 'declining';
healthyWarehouses: number;
totalWarehouses: number;
};
performance: {
operationalEfficiency: number;
capacityUtilization: number;
networkResilience: number;
};
predictiveInsights: {
highRiskIssues: number;
totalPredictions: number;
optimizationOpportunities: number;
};
}
interface RiskAssessment {
overallRiskLevel: 'low' | 'medium' | 'high' | 'critical';
criticalRisks: Array<{
description: string;
probability: number;
impact: string;
timeframe: string;
mitigationActions: string[];
}>;
emergingRisks: Array<{
description: string;
probability: number;
impact: string;
timeframe: string;
}>;
riskMitigationStatus: 'on-track' | 'behind' | 'at-risk';
}
interface StrategicRecommendation {
category: 'critical' | 'strategic' | 'operational';
title: string;
description: string;
expectedBenefit: string;
implementationComplexity: 'low' | 'medium' | 'high';
timeline: string;
requiredResources: string[];
strategicAlignment: 'high' | 'medium' | 'low';
}
interface FinancialImpact {
currentCosts: number;
projectedSavings: number;
investmentRequired: number;
roi: number;
paybackPeriod: string;
}
interface NextStep {
action: string;
owner: string;
deadline: string;
priority: 'high' | 'medium' | 'low';
dependencies: string[];
}
π ΠΡΡΡΡΡΠΉ ΡΡΠ°ΡΡ Enterprise ΡΠ΅ΡΠ΅Π½ΠΈΡ
// ΠΠΎΠ»Π½Π°Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠ° enterprise ΡΠΈΡΡΠ΅ΠΌΡ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΡΠΊΠ»Π°Π΄ΠΎΠ²
import { HttpClient } from 'daytona-ozon-seller-api';
async function setupEnterpriseWarehouseMonitoring() {
// ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° HTTP ΠΊΠ»ΠΈΠ΅Π½ΡΠ°
const httpClient = new HttpClient({
clientId: process.env.OZON_CLIENT_ID!,
apiKey: process.env.OZON_API_KEY!
});
// ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΠΈΡΡΠ΅ΠΌΡ Π°Π½Π°Π»ΠΈΡΠΈΠΊΠΈ
const intelligenceConfig: IntelligenceConfig = {
mlConfig: {
predictionThreshold: 0.7,
historicalDataDays: 30,
learningRate: 0.1
},
alertConfig: {
slack: {
enabled: true,
webhookUrl: process.env.SLACK_WEBHOOK_URL!,
channel: '#warehouse-alerts',
alertLevels: ['critical', 'warning']
},
email: {
enabled: true,
smtpConfig: {
host: process.env.SMTP_HOST!,
port: 587,
secure: false,
auth: {
user: process.env.SMTP_USER!,
pass: process.env.SMTP_PASS!
}
},
recipients: ['warehouse-manager@company.com', 'operations@company.com'],
alertLevels: ['critical']
}
}
};
// ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΡΠ½ΠΎΠ²Π½ΡΡ
ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ²
const intelligenceEngine = new WarehouseIntelligenceEngine(httpClient, intelligenceConfig);
const reportGenerator = new ExecutiveReportGenerator(intelligenceEngine);
// ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°
const monitoringConfig: MonitoringConfig = {
intervalMinutes: 30,
alertThresholds: {
criticalWarehousesThreshold: 1,
efficiencyDropThreshold: 15,
predictionProbabilityThreshold: 0.8
},
emergencyContacts: ['+7-xxx-xxx-xxxx']
};
const monitor = new ContinuousWarehouseMonitor(
httpClient,
intelligenceEngine,
monitoringConfig
);
// ΠΠ°ΠΏΡΡΠΊ ΡΠΈΡΡΠ΅ΠΌΡ
console.log('π ΠΠ°ΠΏΡΡΠΊ Enterprise ΡΠΈΡΡΠ΅ΠΌΡ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΡΠΊΠ»Π°Π΄ΠΎΠ²...');
// ΠΠ΅ΡΠ²ΠΈΡΠ½ΡΠΉ Π°Π½Π°Π»ΠΈΠ·
const initialAnalysis = await intelligenceEngine.performNetworkAnalysis();
console.log('π ΠΠ°ΡΠ°Π»ΡΠ½ΡΠΉ Π°Π½Π°Π»ΠΈΠ· ΡΠ΅ΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½:', {
warehouses: initialAnalysis.totalWarehouses,
health: initialAnalysis.networkHealth,
performance: initialAnalysis.performanceMetrics.operationalEfficiency
});
// ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΎΡΡΠ΅ΡΠ°
const executiveReport = await reportGenerator.generateWeeklyExecutiveSummary();
console.log('π ΠΡΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΎΡΡΠ΅Ρ Π³ΠΎΡΠΎΠ²');
// ΠΠ°ΠΏΡΡΠΊ Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°
await monitor.startMonitoring();
// ΠΠ»Π°Π½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΡΡ
ΠΎΡΡΠ΅ΡΠΎΠ²
setInterval(async () => {
const report = await reportGenerator.generateWeeklyExecutiveSummary();
console.log('π ΠΠΆΠ΅Π½Π΅Π΄Π΅Π»ΡΠ½ΡΠΉ ΠΎΡΡΠ΅Ρ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π½:', report.reportDate);
}, 7 * 24 * 60 * 60 * 1000); // ΠΠ°ΠΆΠ΄ΡΡ Π½Π΅Π΄Π΅Π»Ρ
console.log('β
Enterprise ΡΠΈΡΡΠ΅ΠΌΠ° ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΡΠΊΠ»Π°Π΄ΠΎΠ² Π·Π°ΠΏΡΡΠ΅Π½Π° ΠΈ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ');
return {
intelligenceEngine,
reportGenerator,
monitor
};
}
// ΠΡΠΈΠΌΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ
setupEnterpriseWarehouseMonitoring()
.then(system => {
console.log('π Enterprise ΡΠΈΡΡΠ΅ΠΌΠ° Π³ΠΎΡΠΎΠ²Π° ΠΊ ΡΠ°Π±ΠΎΡΠ΅');
// Π‘ΠΈΡΡΠ΅ΠΌΠ° Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎ
// ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ, ΠΎΡΡΠ΅ΡΡ ΠΈ ΠΏΡΠΎΠ³Π½ΠΎΠ·Ρ
})
.catch(error => {
console.error('β ΠΡΠΈΠ±ΠΊΠ° Π·Π°ΠΏΡΡΠΊΠ° ΡΠΈΡΡΠ΅ΠΌΡ:', error);
});
π‘ ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
Enterprise ΡΠ΅ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ OZON Warehouse API ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡ:
π ΠΠ½ΡΠ΅Π»Π»Π΅ΠΊΡΡΠ°Π»ΡΠ½ΡΡ Π°Π½Π°Π»ΠΈΡΠΈΠΊΡ:
- ΠΡΠ΅Π΄ΠΈΠΊΡΠΈΠ²Π½ΠΎΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌ ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ
- ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ Π²ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ
- ΠΠΎΠΌΠΏΠ»Π΅ΠΊΡΠ½Π°Ρ ΠΎΡΠ΅Π½ΠΊΠ° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΈ ΡΠΈΡΠΊΠΎΠ²
π¨ ΠΡΠΎΠ°ΠΊΡΠΈΠ²Π½ΡΠ΅ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ:
- ΠΠ½ΠΎΠ³ΠΎΠΊΠ°Π½Π°Π»ΡΠ½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΠΉ (Slack, Email, Telegram)
- ΠΠ°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌΡΠ΅ ΡΡΠΎΠ²Π½ΠΈ ΠΊΡΠΈΡΠΈΡΠ½ΠΎΡΡΠΈ
- ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΡΡΠΊΠ°Π»Π°ΡΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ
π ΠΡΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΎΡΡΠ΅ΡΠ½ΠΎΡΡΡ:
- ΠΠΆΠ΅Π½Π΅Π΄Π΅Π»ΡΠ½ΡΠ΅ ΠΎΡΡΠ΅ΡΡ Π΄Π»Ρ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²Π°
- Π€ΠΈΠ½Π°Π½ΡΠΎΠ²ΡΠ΅ ΠΎΡΠ΅Π½ΠΊΠΈ ΠΈ ΠΏΡΠΎΠ³Π½ΠΎΠ·Ρ ROI
- Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠΈ
π ΠΠ΅ΠΏΡΠ΅ΡΡΠ²Π½ΡΠΉ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³:
- 24/7 ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΡΠΊΠ»Π°Π΄ΡΠΊΠΎΠΉ ΡΠ΅ΡΠΈ
- ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ Π²ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
- Π‘ΠΈΡΡΠ΅ΠΌΠ° ΡΠ°Π½Π½Π΅Π³ΠΎ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΡ
ΠΡΠΈ ΡΠ΅ΡΠ΅Π½ΠΈΡ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠΈΡΡΡΡ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΠΌΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠΌΠΈ ΠΈΠ· ΡΠ΅Π°ΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ Π² ΠΏΡΠΎΠ°ΠΊΡΠΈΠ²Π½ΠΎΠ΅, ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΡ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ ΠΈ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·Π°ΡΠΈΡ ΡΠΈΡΠΊΠΎΠ² Π΄Π»Ρ ΠΊΡΡΠΏΠ½ΡΡ ΡΠΊΠ»Π°Π΄ΡΠΊΠΈΡ ΡΠ΅ΡΠ΅ΠΉ.