Improve AI logic
This commit is contained in:
11
services/ai_insights/app/models/__init__.py
Normal file
11
services/ai_insights/app/models/__init__.py
Normal 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",
|
||||
]
|
||||
129
services/ai_insights/app/models/ai_insight.py
Normal file
129
services/ai_insights/app/models/ai_insight.py
Normal 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})>"
|
||||
69
services/ai_insights/app/models/insight_correlation.py
Normal file
69
services/ai_insights/app/models/insight_correlation.py
Normal 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})>"
|
||||
87
services/ai_insights/app/models/insight_feedback.py
Normal file
87
services/ai_insights/app/models/insight_feedback.py
Normal 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})>"
|
||||
Reference in New Issue
Block a user