Improve AI logic

This commit is contained in:
Urtzi Alfaro
2025-11-05 13:34:56 +01:00
parent 5c87fbcf48
commit 394ad3aea4
218 changed files with 30627 additions and 7658 deletions

View File

@@ -0,0 +1,11 @@
"""Database models for AI Insights Service."""
from app.models.ai_insight import AIInsight
from app.models.insight_feedback import InsightFeedback
from app.models.insight_correlation import InsightCorrelation
__all__ = [
"AIInsight",
"InsightFeedback",
"InsightCorrelation",
]

View File

@@ -0,0 +1,129 @@
"""AI Insight database model."""
from sqlalchemy import Column, String, Integer, Boolean, DECIMAL, TIMESTAMP, Text, Index, CheckConstraint
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.sql import func
import uuid
from app.core.database import Base
class AIInsight(Base):
"""AI Insight model for storing intelligent recommendations and predictions."""
__tablename__ = "ai_insights"
# Primary Key
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
# Tenant Information
tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
# Classification
type = Column(
String(50),
nullable=False,
index=True,
comment="optimization, alert, prediction, recommendation, insight, anomaly"
)
priority = Column(
String(20),
nullable=False,
index=True,
comment="low, medium, high, critical"
)
category = Column(
String(50),
nullable=False,
index=True,
comment="forecasting, inventory, production, procurement, customer, cost, quality, efficiency, demand, maintenance, energy, scheduling"
)
# Content
title = Column(String(255), nullable=False)
description = Column(Text, nullable=False)
# Impact Information
impact_type = Column(
String(50),
comment="cost_savings, revenue_increase, waste_reduction, efficiency_gain, quality_improvement, risk_mitigation"
)
impact_value = Column(DECIMAL(10, 2), comment="Numeric impact value")
impact_unit = Column(
String(20),
comment="euros, percentage, hours, units, euros/month, euros/year"
)
# Confidence and Metrics
confidence = Column(
Integer,
CheckConstraint('confidence >= 0 AND confidence <= 100'),
nullable=False,
index=True,
comment="Confidence score 0-100"
)
metrics_json = Column(
JSONB,
comment="Dynamic metrics specific to insight type"
)
# Actionability
actionable = Column(
Boolean,
default=True,
nullable=False,
index=True,
comment="Whether this insight can be acted upon"
)
recommendation_actions = Column(
JSONB,
comment="List of possible actions: [{label, action, endpoint}]"
)
# Status
status = Column(
String(20),
default='new',
nullable=False,
index=True,
comment="new, acknowledged, in_progress, applied, dismissed, expired"
)
# Source Information
source_service = Column(
String(50),
comment="Service that generated this insight"
)
source_data_id = Column(
String(100),
comment="Reference to source data (e.g., forecast_id, model_id)"
)
# Timestamps
created_at = Column(
TIMESTAMP(timezone=True),
server_default=func.now(),
nullable=False,
index=True
)
updated_at = Column(
TIMESTAMP(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False
)
applied_at = Column(TIMESTAMP(timezone=True), comment="When insight was applied")
expired_at = Column(
TIMESTAMP(timezone=True),
comment="When insight expires (auto-calculated based on TTL)"
)
# Composite Indexes
__table_args__ = (
Index('idx_tenant_status_category', 'tenant_id', 'status', 'category'),
Index('idx_tenant_created_confidence', 'tenant_id', 'created_at', 'confidence'),
Index('idx_actionable_status', 'actionable', 'status'),
)
def __repr__(self):
return f"<AIInsight(id={self.id}, type={self.type}, title={self.title[:30]}, confidence={self.confidence})>"

View File

@@ -0,0 +1,69 @@
"""Insight Correlation database model for cross-service intelligence."""
from sqlalchemy import Column, String, Integer, DECIMAL, TIMESTAMP, ForeignKey, Index
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
import uuid
from app.core.database import Base
class InsightCorrelation(Base):
"""Track correlations between insights from different services."""
__tablename__ = "insight_correlations"
# Primary Key
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
# Foreign Keys to AIInsights
parent_insight_id = Column(
UUID(as_uuid=True),
ForeignKey('ai_insights.id', ondelete='CASCADE'),
nullable=False,
index=True,
comment="Primary insight that leads to correlation"
)
child_insight_id = Column(
UUID(as_uuid=True),
ForeignKey('ai_insights.id', ondelete='CASCADE'),
nullable=False,
index=True,
comment="Related insight"
)
# Correlation Information
correlation_type = Column(
String(50),
nullable=False,
comment="forecast_inventory, production_procurement, weather_customer, demand_supplier, etc."
)
correlation_strength = Column(
DECIMAL(3, 2),
nullable=False,
comment="0.00 to 1.00 indicating strength of correlation"
)
# Combined Metrics
combined_confidence = Column(
Integer,
comment="Weighted combined confidence of both insights"
)
# Timestamp
created_at = Column(
TIMESTAMP(timezone=True),
server_default=func.now(),
nullable=False,
index=True
)
# Composite Indexes
__table_args__ = (
Index('idx_parent_child', 'parent_insight_id', 'child_insight_id'),
Index('idx_correlation_type', 'correlation_type'),
)
def __repr__(self):
return f"<InsightCorrelation(id={self.id}, type={self.correlation_type}, strength={self.correlation_strength})>"

View File

@@ -0,0 +1,87 @@
"""Insight Feedback database model for closed-loop learning."""
from sqlalchemy import Column, String, Boolean, DECIMAL, TIMESTAMP, Text, ForeignKey, Index
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
import uuid
from app.core.database import Base
class InsightFeedback(Base):
"""Feedback tracking for AI Insights to enable learning."""
__tablename__ = "insight_feedback"
# Primary Key
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
# Foreign Key to AIInsight
insight_id = Column(
UUID(as_uuid=True),
ForeignKey('ai_insights.id', ondelete='CASCADE'),
nullable=False,
index=True
)
# Action Information
action_taken = Column(
String(100),
comment="Specific action that was taken from recommendation_actions"
)
# Result Data
result_data = Column(
JSONB,
comment="Detailed result data from applying the insight"
)
# Success Tracking
success = Column(
Boolean,
nullable=False,
index=True,
comment="Whether the insight application was successful"
)
error_message = Column(
Text,
comment="Error message if success = false"
)
# Impact Comparison
expected_impact_value = Column(
DECIMAL(10, 2),
comment="Expected impact value from original insight"
)
actual_impact_value = Column(
DECIMAL(10, 2),
comment="Measured actual impact after application"
)
variance_percentage = Column(
DECIMAL(5, 2),
comment="(actual - expected) / expected * 100"
)
# User Information
applied_by = Column(
String(100),
comment="User or system that applied the insight"
)
# Timestamp
created_at = Column(
TIMESTAMP(timezone=True),
server_default=func.now(),
nullable=False,
index=True
)
# Composite Indexes
__table_args__ = (
Index('idx_insight_success', 'insight_id', 'success'),
Index('idx_created_success', 'created_at', 'success'),
)
def __repr__(self):
return f"<InsightFeedback(id={self.id}, insight_id={self.insight_id}, success={self.success})>"