Improve the demo feature of the project
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Quick Alert Test Script
|
||||
# This script sends a single test alert using the working configuration
|
||||
# Use this for quick testing of the real-time alert system
|
||||
|
||||
echo "🚀 Sending quick test alert..."
|
||||
|
||||
docker exec bakery-ia-alert-processor-1 python -c "
|
||||
import aio_pika
|
||||
import asyncio
|
||||
import json
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
async def quick_alert():
|
||||
connection = await aio_pika.connect_robust('amqp://bakery:forecast123@rabbitmq:5672/')
|
||||
channel = await connection.channel()
|
||||
|
||||
exchange = await channel.declare_exchange(
|
||||
'alerts.exchange',
|
||||
aio_pika.ExchangeType.TOPIC,
|
||||
durable=True
|
||||
)
|
||||
|
||||
tenant_id = 'c464fb3e-7af2-46e6-9e43-85318f34199a'
|
||||
|
||||
# Quick test alert
|
||||
alert = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'tenant_id': tenant_id,
|
||||
'item_type': 'alert',
|
||||
'type': 'quick_test',
|
||||
'severity': 'urgent',
|
||||
'service': 'quick-test',
|
||||
'title': '⚡ QUICK TEST - ' + datetime.now().strftime('%H:%M:%S'),
|
||||
'message': 'Quick test alert sent at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'actions': ['Check frontend', 'Verify reception'],
|
||||
'metadata': {'quick_test': True, 'sent_at': datetime.utcnow().isoformat()},
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}
|
||||
|
||||
await exchange.publish(
|
||||
aio_pika.Message(json.dumps(alert).encode()),
|
||||
routing_key='alert.urgent.quick-test'
|
||||
)
|
||||
|
||||
print(f'✅ Quick alert sent: {alert[\"title\"]}')
|
||||
print(f' ID: {alert[\"id\"]}')
|
||||
print(' Check your frontend for real-time update!')
|
||||
|
||||
await connection.close()
|
||||
|
||||
asyncio.run(quick_alert())
|
||||
"
|
||||
|
||||
echo "✅ Quick test completed!"
|
||||
echo "🌐 Check your frontend - the alert should appear immediately in:"
|
||||
echo " - Notification icon (header)"
|
||||
echo " - Panel de control (alerts section)"
|
||||
echo " - Toast notification (if urgent/high priority)"
|
||||
@@ -1,137 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
WORKING Alert Test Script
|
||||
This script successfully sends alerts that reach the frontend via SSE.
|
||||
Use this for future testing of the real-time alert system.
|
||||
"""
|
||||
|
||||
import aio_pika
|
||||
import asyncio
|
||||
import json
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
async def send_test_alerts():
|
||||
"""Send test alerts and recommendations to the system"""
|
||||
|
||||
# Connect to RabbitMQ using the correct credentials
|
||||
connection = await aio_pika.connect_robust('amqp://bakery:forecast123@rabbitmq:5672/')
|
||||
channel = await connection.channel()
|
||||
|
||||
# Declare the alerts exchange
|
||||
exchange = await channel.declare_exchange(
|
||||
'alerts.exchange',
|
||||
aio_pika.ExchangeType.TOPIC,
|
||||
durable=True
|
||||
)
|
||||
|
||||
# Use your actual tenant ID (replace if different)
|
||||
tenant_id = 'c464fb3e-7af2-46e6-9e43-85318f34199a'
|
||||
|
||||
print("🚀 Sending test alerts to the system...")
|
||||
|
||||
# Test Alert - Urgent
|
||||
urgent_alert = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'tenant_id': tenant_id,
|
||||
'item_type': 'alert',
|
||||
'type': 'test_alert',
|
||||
'severity': 'urgent', # Must be lowercase: urgent, high, medium, low
|
||||
'service': 'test-manual',
|
||||
'title': '🚨 TEST URGENT ALERT',
|
||||
'message': 'This is a test urgent alert that should appear in your frontend immediately',
|
||||
'actions': ['Check frontend dashboard', 'Verify notification icon', 'Confirm real-time reception'],
|
||||
'metadata': {'test': True, 'manual': True, 'timestamp': datetime.utcnow().isoformat()},
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}
|
||||
|
||||
await exchange.publish(
|
||||
aio_pika.Message(json.dumps(urgent_alert).encode()),
|
||||
routing_key='alert.urgent.test-manual'
|
||||
)
|
||||
print(f"✅ Sent urgent alert: {urgent_alert['title']}")
|
||||
|
||||
# Wait a moment between alerts
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# Test Alert - High Priority
|
||||
high_alert = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'tenant_id': tenant_id,
|
||||
'item_type': 'alert',
|
||||
'type': 'test_alert_high',
|
||||
'severity': 'high',
|
||||
'service': 'test-manual',
|
||||
'title': '⚠️ TEST HIGH PRIORITY ALERT',
|
||||
'message': 'This is a high priority test alert for the bakery system',
|
||||
'actions': ['Review inventory', 'Contact supplier', 'Update stock levels'],
|
||||
'metadata': {'test': True, 'priority': 'high', 'category': 'inventory'},
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}
|
||||
|
||||
await exchange.publish(
|
||||
aio_pika.Message(json.dumps(high_alert).encode()),
|
||||
routing_key='alert.high.test-manual'
|
||||
)
|
||||
print(f"✅ Sent high priority alert: {high_alert['title']}")
|
||||
|
||||
# Wait a moment
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# Test Recommendation
|
||||
recommendation = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'tenant_id': tenant_id,
|
||||
'item_type': 'recommendation',
|
||||
'type': 'optimization_suggestion',
|
||||
'severity': 'medium',
|
||||
'service': 'test-manual',
|
||||
'title': '💡 TEST OPTIMIZATION RECOMMENDATION',
|
||||
'message': 'This is a test recommendation to optimize your bakery operations',
|
||||
'actions': ['Review suggestion', 'Analyze impact', 'Consider implementation'],
|
||||
'metadata': {'test': True, 'type': 'optimization', 'potential_savings': '15%'},
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}
|
||||
|
||||
await exchange.publish(
|
||||
aio_pika.Message(json.dumps(recommendation).encode()),
|
||||
routing_key='recommendation.medium.test-manual'
|
||||
)
|
||||
print(f"✅ Sent recommendation: {recommendation['title']}")
|
||||
|
||||
# Wait a moment
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# Test Low Priority Alert
|
||||
low_alert = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'tenant_id': tenant_id,
|
||||
'item_type': 'alert',
|
||||
'type': 'test_info',
|
||||
'severity': 'low',
|
||||
'service': 'test-manual',
|
||||
'title': 'ℹ️ TEST INFO ALERT',
|
||||
'message': 'This is a low priority informational alert for testing',
|
||||
'actions': ['Review when convenient'],
|
||||
'metadata': {'test': True, 'info': True},
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}
|
||||
|
||||
await exchange.publish(
|
||||
aio_pika.Message(json.dumps(low_alert).encode()),
|
||||
routing_key='alert.low.test-manual'
|
||||
)
|
||||
print(f"✅ Sent low priority alert: {low_alert['title']}")
|
||||
|
||||
await connection.close()
|
||||
|
||||
print("\n🎉 All test alerts sent successfully!")
|
||||
print("\nYou should see these alerts in your frontend:")
|
||||
print(" 1. In the notification icon (header) - live counter update")
|
||||
print(" 2. In the panel de control - compact expandable cards")
|
||||
print(" 3. As real-time toast notifications")
|
||||
print("\nNote: Urgent and high alerts will show as toast notifications")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run the async function
|
||||
asyncio.run(send_test_alerts())
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,94 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Out of Stock Alert Test
|
||||
Sends a realistic out of stock alert to test the inventory monitoring system
|
||||
"""
|
||||
|
||||
import aio_pika
|
||||
import asyncio
|
||||
import json
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
async def send_out_of_stock_alert():
|
||||
"""Send a realistic out of stock alert"""
|
||||
|
||||
# Connect to RabbitMQ
|
||||
connection = await aio_pika.connect_robust('amqp://bakery:forecast123@rabbitmq:5672/')
|
||||
channel = await connection.channel()
|
||||
|
||||
# Declare the alerts exchange
|
||||
exchange = await channel.declare_exchange(
|
||||
'alerts.exchange',
|
||||
aio_pika.ExchangeType.TOPIC,
|
||||
durable=True
|
||||
)
|
||||
|
||||
# Use actual tenant ID
|
||||
tenant_id = 'c464fb3e-7af2-46e6-9e43-85318f34199a'
|
||||
|
||||
print("🚨 Sending out of stock alert...")
|
||||
|
||||
# Out of Stock Alert
|
||||
out_of_stock_alert = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'tenant_id': tenant_id,
|
||||
'item_type': 'alert',
|
||||
'type': 'out_of_stock',
|
||||
'severity': 'urgent',
|
||||
'service': 'inventory-service',
|
||||
'title': '🚨 PRODUCTO AGOTADO: Harina de Trigo',
|
||||
'message': 'El ingrediente "Harina de Trigo" está completamente agotado. Stock actual: 0 kg. Este ingrediente es crítico para la producción diaria y afecta 8 productos principales.',
|
||||
'actions': [
|
||||
'Contactar proveedor inmediatamente',
|
||||
'Revisar productos afectados',
|
||||
'Activar stock de emergencia si disponible',
|
||||
'Notificar al equipo de producción',
|
||||
'Actualizar previsiones de ventas'
|
||||
],
|
||||
'metadata': {
|
||||
'ingredient_name': 'Harina de Trigo',
|
||||
'current_stock': 0,
|
||||
'unit': 'kg',
|
||||
'minimum_stock': 50,
|
||||
'critical_ingredient': True,
|
||||
'affected_products': [
|
||||
'Pan Francés',
|
||||
'Croissants',
|
||||
'Pan Integral',
|
||||
'Baguettes',
|
||||
'Pan de Molde',
|
||||
'Empanadas',
|
||||
'Pizza',
|
||||
'Focaccia'
|
||||
],
|
||||
'supplier': 'Molinos San Andrés',
|
||||
'last_order_date': '2024-01-15',
|
||||
'estimated_restock_time': '24-48 horas',
|
||||
'impact_level': 'HIGH'
|
||||
},
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}
|
||||
|
||||
await exchange.publish(
|
||||
aio_pika.Message(json.dumps(out_of_stock_alert).encode()),
|
||||
routing_key='alert.urgent.inventory-service'
|
||||
)
|
||||
|
||||
print(f"✅ Out of stock alert sent: {out_of_stock_alert['title']}")
|
||||
print(f" Alert ID: {out_of_stock_alert['id']}")
|
||||
print(f" Severity: {out_of_stock_alert['severity'].upper()}")
|
||||
print(f" Service: {out_of_stock_alert['service']}")
|
||||
print(f" Affected products: {len(out_of_stock_alert['metadata']['affected_products'])}")
|
||||
|
||||
await connection.close()
|
||||
|
||||
print("\n🎯 Out of stock alert test completed!")
|
||||
print("Check your frontend for:")
|
||||
print(" • Urgent notification in header (red badge)")
|
||||
print(" • Real-time alert in dashboard panel")
|
||||
print(" • Toast notification (urgent priority)")
|
||||
print(" • Expandable card with ingredient details and actions")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(send_out_of_stock_alert())
|
||||
@@ -1,95 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Recommendation Alert Test
|
||||
Sends a realistic optimization recommendation to test the AI recommendations system
|
||||
"""
|
||||
|
||||
import aio_pika
|
||||
import asyncio
|
||||
import json
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
async def send_recommendation_alert():
|
||||
"""Send a realistic optimization recommendation"""
|
||||
|
||||
# Connect to RabbitMQ
|
||||
connection = await aio_pika.connect_robust('amqp://bakery:forecast123@rabbitmq:5672/')
|
||||
channel = await connection.channel()
|
||||
|
||||
# Declare the alerts exchange
|
||||
exchange = await channel.declare_exchange(
|
||||
'alerts.exchange',
|
||||
aio_pika.ExchangeType.TOPIC,
|
||||
durable=True
|
||||
)
|
||||
|
||||
# Use actual tenant ID
|
||||
tenant_id = 'c464fb3e-7af2-46e6-9e43-85318f34199a'
|
||||
|
||||
print("💡 Sending optimization recommendation...")
|
||||
|
||||
# Optimization Recommendation
|
||||
recommendation = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'tenant_id': tenant_id,
|
||||
'item_type': 'recommendation',
|
||||
'type': 'demand_optimization',
|
||||
'severity': 'medium',
|
||||
'service': 'ai-forecast-service',
|
||||
'title': '💡 OPTIMIZACIÓN: Ajustar Producción de Croissants',
|
||||
'message': 'Nuestro análisis de IA detectó que la demanda de croissants aumenta un 35% los viernes. Se recomienda incrementar la producción para maximizar ventas y reducir desperdicio.',
|
||||
'actions': [
|
||||
'Revisar análisis de demanda detallado',
|
||||
'Ajustar plan de producción para viernes',
|
||||
'Evaluar capacidad de horno disponible',
|
||||
'Calcular ROI del incremento propuesto',
|
||||
'Implementar cambio gradualmente',
|
||||
'Monitorear resultados por 2 semanas'
|
||||
],
|
||||
'metadata': {
|
||||
'product_name': 'Croissants',
|
||||
'current_friday_production': 120,
|
||||
'recommended_friday_production': 162,
|
||||
'increase_percentage': 35,
|
||||
'confidence_score': 0.87,
|
||||
'data_period_analyzed': '3 meses',
|
||||
'potential_revenue_increase': 280.50,
|
||||
'currency': 'EUR',
|
||||
'historical_sellout_rate': 0.95,
|
||||
'waste_reduction_potential': '15%',
|
||||
'implementation_effort': 'LOW',
|
||||
'roi_timeframe': '2 semanas',
|
||||
'seasonal_factors': [
|
||||
'Viernes laboral',
|
||||
'Proximidad fin de semana',
|
||||
'Horario de desayuno extendido'
|
||||
],
|
||||
'risk_level': 'BAJO'
|
||||
},
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}
|
||||
|
||||
await exchange.publish(
|
||||
aio_pika.Message(json.dumps(recommendation).encode()),
|
||||
routing_key='recommendation.medium.ai-forecast-service'
|
||||
)
|
||||
|
||||
print(f"✅ Recommendation sent: {recommendation['title']}")
|
||||
print(f" Recommendation ID: {recommendation['id']}")
|
||||
print(f" Severity: {recommendation['severity'].upper()}")
|
||||
print(f" Service: {recommendation['service']}")
|
||||
print(f" Confidence: {recommendation['metadata']['confidence_score']*100:.0f}%")
|
||||
print(f" Potential revenue increase: €{recommendation['metadata']['potential_revenue_increase']}")
|
||||
|
||||
await connection.close()
|
||||
|
||||
print("\n🎯 Recommendation test completed!")
|
||||
print("Check your frontend for:")
|
||||
print(" • Medium priority notification in header")
|
||||
print(" • Real-time recommendation in dashboard panel")
|
||||
print(" • Blue info badge (recommendation type)")
|
||||
print(" • Expandable card with AI analysis and business impact")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(send_recommendation_alert())
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify traffic data fetching and storage
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# Add the services path to Python path
|
||||
sys.path.insert(0, '/Users/urtzialfaro/Documents/bakery-ia/services/external')
|
||||
|
||||
async def test_traffic_storage():
|
||||
"""Test traffic data fetching and storage"""
|
||||
print("Testing traffic data storage workflow...")
|
||||
|
||||
try:
|
||||
from app.services.traffic_service import TrafficService
|
||||
from app.core.database import database_manager
|
||||
from app.repositories.traffic_repository import TrafficRepository
|
||||
|
||||
# Initialize traffic service
|
||||
traffic_service = TrafficService()
|
||||
|
||||
# Madrid coordinates (within bounds)
|
||||
latitude = 40.4168
|
||||
longitude = -3.7038
|
||||
tenant_id = "test_tenant"
|
||||
|
||||
print(f"Testing location: {latitude}, {longitude}")
|
||||
|
||||
# Test 1: Check current traffic
|
||||
print("\n1. Testing current traffic...")
|
||||
current_traffic = await traffic_service.get_current_traffic(latitude, longitude, tenant_id)
|
||||
if current_traffic:
|
||||
print(f"Current traffic data retrieved:")
|
||||
print(f" - Traffic volume: {current_traffic.get('traffic_volume')}")
|
||||
print(f" - Source: {current_traffic.get('source')}")
|
||||
print(f" - Congestion: {current_traffic.get('congestion_level')}")
|
||||
else:
|
||||
print("No current traffic data available")
|
||||
|
||||
# Test 2: Check historical traffic (short range to avoid large downloads)
|
||||
print("\n2. Testing historical traffic storage...")
|
||||
end_date = datetime.now()
|
||||
start_date = end_date - timedelta(days=2) # Just 2 days to test
|
||||
|
||||
print(f"Requesting historical data from {start_date} to {end_date}")
|
||||
|
||||
historical_data = await traffic_service.get_historical_traffic(
|
||||
latitude, longitude, start_date, end_date, tenant_id
|
||||
)
|
||||
|
||||
print(f"Historical traffic records retrieved: {len(historical_data)}")
|
||||
|
||||
if historical_data:
|
||||
print("Sample record:")
|
||||
sample = historical_data[0]
|
||||
for key, value in sample.items():
|
||||
if key != 'raw_data': # Skip raw data to keep output clean
|
||||
print(f" - {key}: {value}")
|
||||
|
||||
# Test 3: Check database storage
|
||||
print("\n3. Checking database storage...")
|
||||
async with database_manager.get_session() as session:
|
||||
traffic_repo = TrafficRepository(session)
|
||||
|
||||
# Check what's actually stored in the database
|
||||
db_records = await traffic_repo.get_by_location_and_date_range(
|
||||
latitude, longitude, start_date, end_date, tenant_id
|
||||
)
|
||||
|
||||
print(f"Records found in database: {len(db_records)}")
|
||||
|
||||
if db_records:
|
||||
print("Sample database record:")
|
||||
sample_db = db_records[0]
|
||||
print(f" - ID: {sample_db.id}")
|
||||
print(f" - Date: {sample_db.date}")
|
||||
print(f" - Traffic volume: {sample_db.traffic_volume}")
|
||||
print(f" - Location ID: {sample_db.location_id}")
|
||||
print(f" - Source: {sample_db.source}")
|
||||
print(f" - Tenant ID: {sample_db.tenant_id}")
|
||||
|
||||
print("\n✅ Traffic storage test completed successfully")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Traffic storage test failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_traffic_storage())
|
||||
Reference in New Issue
Block a user