Add more services
This commit is contained in:
250
services/inventory/app/schemas/dashboard.py
Normal file
250
services/inventory/app/schemas/dashboard.py
Normal file
@@ -0,0 +1,250 @@
|
||||
# ================================================================
|
||||
# services/inventory/app/schemas/dashboard.py
|
||||
# ================================================================
|
||||
"""
|
||||
Dashboard and analytics schemas for Inventory Service
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import List, Optional, Dict, Any
|
||||
from uuid import UUID
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
# ===== Dashboard Summary Schemas =====
|
||||
|
||||
class InventoryDashboardSummary(BaseModel):
|
||||
"""Comprehensive dashboard summary for inventory management"""
|
||||
|
||||
# Current inventory metrics
|
||||
total_ingredients: int
|
||||
active_ingredients: int
|
||||
total_stock_value: Decimal
|
||||
total_stock_items: int
|
||||
|
||||
# Stock status breakdown
|
||||
in_stock_items: int
|
||||
low_stock_items: int
|
||||
out_of_stock_items: int
|
||||
expired_items: int
|
||||
expiring_soon_items: int
|
||||
|
||||
# Food safety metrics
|
||||
food_safety_alerts_active: int
|
||||
temperature_violations_today: int
|
||||
compliance_issues: int
|
||||
certifications_expiring_soon: int
|
||||
|
||||
# Recent activity
|
||||
recent_stock_movements: int
|
||||
recent_purchases: int
|
||||
recent_waste: int
|
||||
recent_adjustments: int
|
||||
|
||||
# Business model context
|
||||
business_model: Optional[str] = None # individual_bakery, central_bakery
|
||||
business_model_confidence: Optional[Decimal] = None
|
||||
|
||||
# Category breakdown
|
||||
stock_by_category: Dict[str, Any]
|
||||
alerts_by_severity: Dict[str, int]
|
||||
movements_by_type: Dict[str, int]
|
||||
|
||||
# Performance indicators
|
||||
inventory_turnover_ratio: Optional[Decimal] = None
|
||||
waste_percentage: Optional[Decimal] = None
|
||||
compliance_score: Optional[Decimal] = None
|
||||
cost_per_unit_avg: Optional[Decimal] = None
|
||||
|
||||
# Trending data
|
||||
stock_value_trend: List[Dict[str, Any]] = []
|
||||
alert_trend: List[Dict[str, Any]] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class StockStatusSummary(BaseModel):
|
||||
"""Summary of stock status by category"""
|
||||
category: str
|
||||
total_ingredients: int
|
||||
in_stock: int
|
||||
low_stock: int
|
||||
out_of_stock: int
|
||||
total_value: Decimal
|
||||
percentage_of_total: Decimal
|
||||
|
||||
|
||||
class AlertSummary(BaseModel):
|
||||
"""Summary of alerts by type and severity"""
|
||||
alert_type: str
|
||||
severity: str
|
||||
count: int
|
||||
oldest_alert_age_hours: Optional[int] = None
|
||||
average_resolution_time_hours: Optional[int] = None
|
||||
|
||||
|
||||
class RecentActivity(BaseModel):
|
||||
"""Recent activity item for dashboard"""
|
||||
activity_type: str # stock_added, stock_consumed, alert_created, etc.
|
||||
description: str
|
||||
timestamp: datetime
|
||||
user_name: Optional[str] = None
|
||||
impact_level: str = Field(default="low") # low, medium, high
|
||||
entity_id: Optional[UUID] = None
|
||||
entity_type: Optional[str] = None
|
||||
|
||||
|
||||
# ===== Food Safety Dashboard Schemas =====
|
||||
|
||||
class FoodSafetyDashboard(BaseModel):
|
||||
"""Food safety specific dashboard metrics"""
|
||||
|
||||
# Compliance overview
|
||||
total_compliance_items: int
|
||||
compliant_items: int
|
||||
non_compliant_items: int
|
||||
pending_review_items: int
|
||||
compliance_percentage: Decimal
|
||||
|
||||
# Temperature monitoring
|
||||
temperature_sensors_online: int
|
||||
temperature_sensors_total: int
|
||||
temperature_violations_24h: int
|
||||
current_temperature_status: str # all_good, warnings, violations
|
||||
|
||||
# Expiration tracking
|
||||
items_expiring_today: int
|
||||
items_expiring_this_week: int
|
||||
expired_items_requiring_action: int
|
||||
|
||||
# Audit and certification status
|
||||
upcoming_audits: int
|
||||
overdue_audits: int
|
||||
certifications_valid: int
|
||||
certifications_expiring_soon: int
|
||||
|
||||
# Risk assessment
|
||||
high_risk_items: int
|
||||
critical_alerts: int
|
||||
regulatory_notifications_pending: int
|
||||
|
||||
# Recent safety events
|
||||
recent_safety_incidents: List[RecentActivity] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class TemperatureMonitoringStatus(BaseModel):
|
||||
"""Current temperature monitoring status"""
|
||||
location: str
|
||||
equipment_id: Optional[str] = None
|
||||
current_temperature: Decimal
|
||||
target_min: Decimal
|
||||
target_max: Decimal
|
||||
status: str # normal, warning, critical
|
||||
last_reading: datetime
|
||||
hours_since_last_reading: Decimal
|
||||
alert_active: bool = False
|
||||
|
||||
|
||||
class ComplianceStatusSummary(BaseModel):
|
||||
"""Compliance status summary by standard"""
|
||||
standard: str
|
||||
standard_name: str
|
||||
total_items: int
|
||||
compliant: int
|
||||
non_compliant: int
|
||||
pending_review: int
|
||||
expired: int
|
||||
compliance_rate: Decimal
|
||||
next_audit_date: Optional[datetime] = None
|
||||
|
||||
|
||||
# ===== Analytics and Reporting Schemas =====
|
||||
|
||||
class InventoryAnalytics(BaseModel):
|
||||
"""Advanced analytics for inventory management"""
|
||||
|
||||
# Turnover analysis
|
||||
inventory_turnover_rate: Decimal
|
||||
fast_moving_items: List[Dict[str, Any]]
|
||||
slow_moving_items: List[Dict[str, Any]]
|
||||
dead_stock_items: List[Dict[str, Any]]
|
||||
|
||||
# Cost analysis
|
||||
total_inventory_cost: Decimal
|
||||
cost_by_category: Dict[str, Decimal]
|
||||
average_unit_cost_trend: List[Dict[str, Any]]
|
||||
waste_cost_analysis: Dict[str, Any]
|
||||
|
||||
# Efficiency metrics
|
||||
stockout_frequency: Dict[str, int]
|
||||
overstock_frequency: Dict[str, int]
|
||||
reorder_accuracy: Decimal
|
||||
forecast_accuracy: Decimal
|
||||
|
||||
# Quality and safety metrics
|
||||
quality_incidents_rate: Decimal
|
||||
food_safety_score: Decimal
|
||||
compliance_score_by_standard: Dict[str, Decimal]
|
||||
temperature_compliance_rate: Decimal
|
||||
|
||||
# Supplier performance
|
||||
supplier_performance: List[Dict[str, Any]]
|
||||
delivery_reliability: Decimal
|
||||
quality_consistency: Decimal
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class BusinessModelInsights(BaseModel):
|
||||
"""Business model insights based on inventory patterns"""
|
||||
detected_model: str # individual_bakery, central_bakery, mixed
|
||||
confidence_score: Decimal
|
||||
|
||||
# Model characteristics
|
||||
total_ingredient_types: int
|
||||
average_stock_per_ingredient: Decimal
|
||||
finished_product_ratio: Decimal
|
||||
supplier_diversity: int
|
||||
|
||||
# Operational patterns
|
||||
order_frequency_pattern: str
|
||||
seasonal_variation: bool
|
||||
bulk_purchasing_indicator: Decimal
|
||||
production_scale_indicator: str
|
||||
|
||||
# Recommendations
|
||||
model_specific_recommendations: List[str]
|
||||
optimization_opportunities: List[str]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Request/Filter Schemas =====
|
||||
|
||||
class DashboardFilter(BaseModel):
|
||||
"""Filtering options for dashboard data"""
|
||||
date_from: Optional[datetime] = None
|
||||
date_to: Optional[datetime] = None
|
||||
categories: Optional[List[str]] = None
|
||||
severity_levels: Optional[List[str]] = None
|
||||
alert_types: Optional[List[str]] = None
|
||||
business_model: Optional[str] = None
|
||||
include_inactive: bool = False
|
||||
|
||||
|
||||
class AlertsFilter(BaseModel):
|
||||
"""Filtering options for alerts dashboard"""
|
||||
alert_types: Optional[List[str]] = None
|
||||
severities: Optional[List[str]] = None
|
||||
statuses: Optional[List[str]] = None
|
||||
date_from: Optional[datetime] = None
|
||||
date_to: Optional[datetime] = None
|
||||
assigned_to: Optional[UUID] = None
|
||||
unresolved_only: bool = True
|
||||
283
services/inventory/app/schemas/food_safety.py
Normal file
283
services/inventory/app/schemas/food_safety.py
Normal file
@@ -0,0 +1,283 @@
|
||||
# ================================================================
|
||||
# services/inventory/app/schemas/food_safety.py
|
||||
# ================================================================
|
||||
"""
|
||||
Food safety schemas for Inventory Service
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import List, Optional, Dict, Any
|
||||
from uuid import UUID
|
||||
from pydantic import BaseModel, Field, validator
|
||||
|
||||
|
||||
# ===== Food Safety Compliance Schemas =====
|
||||
|
||||
class FoodSafetyComplianceBase(BaseModel):
|
||||
ingredient_id: UUID
|
||||
standard: str
|
||||
compliance_status: str = Field(default="pending_review")
|
||||
certification_number: Optional[str] = None
|
||||
certifying_body: Optional[str] = None
|
||||
certification_date: Optional[datetime] = None
|
||||
expiration_date: Optional[datetime] = None
|
||||
requirements: Optional[Dict[str, Any]] = None
|
||||
compliance_notes: Optional[str] = None
|
||||
documentation_url: Optional[str] = None
|
||||
last_audit_date: Optional[datetime] = None
|
||||
next_audit_date: Optional[datetime] = None
|
||||
auditor_name: Optional[str] = None
|
||||
audit_score: Optional[float] = Field(None, ge=0, le=100)
|
||||
risk_level: str = Field(default="medium")
|
||||
risk_factors: Optional[List[str]] = None
|
||||
mitigation_measures: Optional[List[str]] = None
|
||||
requires_monitoring: bool = Field(default=True)
|
||||
monitoring_frequency_days: Optional[int] = Field(None, gt=0)
|
||||
|
||||
|
||||
class FoodSafetyComplianceCreate(FoodSafetyComplianceBase):
|
||||
tenant_id: UUID
|
||||
|
||||
|
||||
class FoodSafetyComplianceUpdate(BaseModel):
|
||||
compliance_status: Optional[str] = None
|
||||
certification_number: Optional[str] = None
|
||||
certifying_body: Optional[str] = None
|
||||
certification_date: Optional[datetime] = None
|
||||
expiration_date: Optional[datetime] = None
|
||||
requirements: Optional[Dict[str, Any]] = None
|
||||
compliance_notes: Optional[str] = None
|
||||
documentation_url: Optional[str] = None
|
||||
last_audit_date: Optional[datetime] = None
|
||||
next_audit_date: Optional[datetime] = None
|
||||
auditor_name: Optional[str] = None
|
||||
audit_score: Optional[float] = Field(None, ge=0, le=100)
|
||||
risk_level: Optional[str] = None
|
||||
risk_factors: Optional[List[str]] = None
|
||||
mitigation_measures: Optional[List[str]] = None
|
||||
requires_monitoring: Optional[bool] = None
|
||||
monitoring_frequency_days: Optional[int] = Field(None, gt=0)
|
||||
|
||||
|
||||
class FoodSafetyComplianceResponse(FoodSafetyComplianceBase):
|
||||
id: UUID
|
||||
tenant_id: UUID
|
||||
is_active: bool
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
created_by: Optional[UUID] = None
|
||||
updated_by: Optional[UUID] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Temperature Monitoring Schemas =====
|
||||
|
||||
class TemperatureLogBase(BaseModel):
|
||||
storage_location: str = Field(..., min_length=1, max_length=100)
|
||||
warehouse_zone: Optional[str] = Field(None, max_length=50)
|
||||
equipment_id: Optional[str] = Field(None, max_length=100)
|
||||
temperature_celsius: float
|
||||
humidity_percentage: Optional[float] = Field(None, ge=0, le=100)
|
||||
target_temperature_min: Optional[float] = None
|
||||
target_temperature_max: Optional[float] = None
|
||||
measurement_method: str = Field(default="manual")
|
||||
device_id: Optional[str] = Field(None, max_length=100)
|
||||
calibration_date: Optional[datetime] = None
|
||||
|
||||
|
||||
class TemperatureLogCreate(TemperatureLogBase):
|
||||
tenant_id: UUID
|
||||
|
||||
|
||||
class TemperatureLogResponse(TemperatureLogBase):
|
||||
id: UUID
|
||||
tenant_id: UUID
|
||||
is_within_range: bool
|
||||
alert_triggered: bool
|
||||
deviation_minutes: Optional[int] = None
|
||||
recorded_at: datetime
|
||||
created_at: datetime
|
||||
recorded_by: Optional[UUID] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Food Safety Alert Schemas =====
|
||||
|
||||
class FoodSafetyAlertBase(BaseModel):
|
||||
alert_type: str
|
||||
severity: str = Field(default="medium")
|
||||
risk_level: str = Field(default="medium")
|
||||
source_entity_type: str
|
||||
source_entity_id: UUID
|
||||
ingredient_id: Optional[UUID] = None
|
||||
stock_id: Optional[UUID] = None
|
||||
title: str = Field(..., min_length=1, max_length=200)
|
||||
description: str = Field(..., min_length=1)
|
||||
detailed_message: Optional[str] = None
|
||||
regulatory_requirement: Optional[str] = Field(None, max_length=100)
|
||||
compliance_standard: Optional[str] = None
|
||||
regulatory_action_required: bool = Field(default=False)
|
||||
trigger_condition: Optional[str] = Field(None, max_length=200)
|
||||
threshold_value: Optional[Decimal] = None
|
||||
actual_value: Optional[Decimal] = None
|
||||
alert_data: Optional[Dict[str, Any]] = None
|
||||
environmental_factors: Optional[Dict[str, Any]] = None
|
||||
affected_products: Optional[List[UUID]] = None
|
||||
public_health_risk: bool = Field(default=False)
|
||||
business_impact: Optional[str] = None
|
||||
estimated_loss: Optional[Decimal] = Field(None, ge=0)
|
||||
|
||||
|
||||
class FoodSafetyAlertCreate(FoodSafetyAlertBase):
|
||||
tenant_id: UUID
|
||||
alert_code: str = Field(..., min_length=1, max_length=50)
|
||||
|
||||
|
||||
class FoodSafetyAlertUpdate(BaseModel):
|
||||
status: Optional[str] = None
|
||||
alert_state: Optional[str] = None
|
||||
immediate_actions_taken: Optional[List[str]] = None
|
||||
investigation_notes: Optional[str] = None
|
||||
resolution_action: Optional[str] = Field(None, max_length=200)
|
||||
resolution_notes: Optional[str] = None
|
||||
corrective_actions: Optional[List[str]] = None
|
||||
preventive_measures: Optional[List[str]] = None
|
||||
assigned_to: Optional[UUID] = None
|
||||
assigned_role: Optional[str] = Field(None, max_length=50)
|
||||
escalated_to: Optional[UUID] = None
|
||||
escalation_deadline: Optional[datetime] = None
|
||||
documentation: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class FoodSafetyAlertResponse(FoodSafetyAlertBase):
|
||||
id: UUID
|
||||
tenant_id: UUID
|
||||
alert_code: str
|
||||
status: str
|
||||
alert_state: str
|
||||
immediate_actions_taken: Optional[List[str]] = None
|
||||
investigation_notes: Optional[str] = None
|
||||
resolution_action: Optional[str] = None
|
||||
resolution_notes: Optional[str] = None
|
||||
corrective_actions: Optional[List[str]] = None
|
||||
preventive_measures: Optional[List[str]] = None
|
||||
first_occurred_at: datetime
|
||||
last_occurred_at: datetime
|
||||
acknowledged_at: Optional[datetime] = None
|
||||
resolved_at: Optional[datetime] = None
|
||||
escalation_deadline: Optional[datetime] = None
|
||||
occurrence_count: int
|
||||
is_recurring: bool
|
||||
recurrence_pattern: Optional[str] = None
|
||||
assigned_to: Optional[UUID] = None
|
||||
assigned_role: Optional[str] = None
|
||||
escalated_to: Optional[UUID] = None
|
||||
escalation_level: int
|
||||
notification_sent: bool
|
||||
notification_methods: Optional[List[str]] = None
|
||||
notification_recipients: Optional[List[str]] = None
|
||||
regulatory_notification_required: bool
|
||||
regulatory_notification_sent: bool
|
||||
documentation: Optional[Dict[str, Any]] = None
|
||||
audit_trail: Optional[List[Dict[str, Any]]] = None
|
||||
external_reference: Optional[str] = None
|
||||
detection_time: Optional[datetime] = None
|
||||
response_time_minutes: Optional[int] = None
|
||||
resolution_time_minutes: Optional[int] = None
|
||||
alert_accuracy: Optional[bool] = None
|
||||
false_positive: bool
|
||||
feedback_notes: Optional[str] = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
created_by: Optional[UUID] = None
|
||||
updated_by: Optional[UUID] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Bulk Operations Schemas =====
|
||||
|
||||
class BulkTemperatureLogCreate(BaseModel):
|
||||
"""Schema for bulk temperature logging"""
|
||||
tenant_id: UUID
|
||||
readings: List[TemperatureLogBase] = Field(..., min_items=1, max_items=100)
|
||||
|
||||
|
||||
class BulkComplianceUpdate(BaseModel):
|
||||
"""Schema for bulk compliance updates"""
|
||||
tenant_id: UUID
|
||||
updates: List[Dict[str, Any]] = Field(..., min_items=1, max_items=50)
|
||||
|
||||
|
||||
# ===== Filter and Query Schemas =====
|
||||
|
||||
class FoodSafetyFilter(BaseModel):
|
||||
"""Filtering options for food safety data"""
|
||||
compliance_standards: Optional[List[str]] = None
|
||||
compliance_statuses: Optional[List[str]] = None
|
||||
risk_levels: Optional[List[str]] = None
|
||||
alert_types: Optional[List[str]] = None
|
||||
severities: Optional[List[str]] = None
|
||||
date_from: Optional[datetime] = None
|
||||
date_to: Optional[datetime] = None
|
||||
assigned_to: Optional[UUID] = None
|
||||
include_resolved: bool = False
|
||||
regulatory_action_required: Optional[bool] = None
|
||||
|
||||
|
||||
class TemperatureMonitoringFilter(BaseModel):
|
||||
"""Filtering options for temperature monitoring"""
|
||||
storage_locations: Optional[List[str]] = None
|
||||
equipment_ids: Optional[List[str]] = None
|
||||
date_from: Optional[datetime] = None
|
||||
date_to: Optional[datetime] = None
|
||||
violations_only: bool = False
|
||||
alerts_only: bool = False
|
||||
|
||||
|
||||
# ===== Analytics Schemas =====
|
||||
|
||||
class FoodSafetyMetrics(BaseModel):
|
||||
"""Food safety performance metrics"""
|
||||
compliance_rate: Decimal = Field(..., ge=0, le=100)
|
||||
temperature_compliance_rate: Decimal = Field(..., ge=0, le=100)
|
||||
alert_response_time_avg: Optional[Decimal] = None
|
||||
alert_resolution_time_avg: Optional[Decimal] = None
|
||||
recurring_issues_count: int
|
||||
regulatory_violations: int
|
||||
certification_coverage: Decimal = Field(..., ge=0, le=100)
|
||||
audit_score_avg: Optional[Decimal] = Field(None, ge=0, le=100)
|
||||
risk_score: Decimal = Field(..., ge=0, le=10)
|
||||
|
||||
|
||||
class TemperatureAnalytics(BaseModel):
|
||||
"""Temperature monitoring analytics"""
|
||||
total_readings: int
|
||||
violations_count: int
|
||||
violation_rate: Decimal = Field(..., ge=0, le=100)
|
||||
average_temperature: Decimal
|
||||
temperature_range: Dict[str, Decimal]
|
||||
longest_violation_hours: Optional[int] = None
|
||||
equipment_performance: List[Dict[str, Any]]
|
||||
location_performance: List[Dict[str, Any]]
|
||||
|
||||
|
||||
# ===== Notification Schemas =====
|
||||
|
||||
class AlertNotificationPreferences(BaseModel):
|
||||
"""User preferences for alert notifications"""
|
||||
email_enabled: bool = True
|
||||
sms_enabled: bool = False
|
||||
whatsapp_enabled: bool = False
|
||||
dashboard_enabled: bool = True
|
||||
severity_threshold: str = Field(default="medium") # Only notify for this severity and above
|
||||
alert_types: Optional[List[str]] = None # Specific alert types to receive
|
||||
quiet_hours_start: Optional[str] = Field(None, pattern=r"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")
|
||||
quiet_hours_end: Optional[str] = Field(None, pattern=r"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")
|
||||
weekend_notifications: bool = True
|
||||
Reference in New Issue
Block a user