Fix new services implementation 3

This commit is contained in:
Urtzi Alfaro
2025-08-14 16:47:34 +02:00
parent 0951547e92
commit 03737430ee
51 changed files with 657 additions and 982 deletions

View File

@@ -29,7 +29,7 @@ class ModelRepository(TrainingBaseRepository):
# Validate model data
validation_result = self._validate_training_data(
model_data,
["tenant_id", "product_name", "model_path", "job_id"]
["tenant_id", "inventory_product_id", "model_path", "job_id"]
)
if not validation_result["is_valid"]:
@@ -38,7 +38,7 @@ class ModelRepository(TrainingBaseRepository):
# Check for duplicate active models for same tenant+product
existing_model = await self.get_active_model_for_product(
model_data["tenant_id"],
model_data["product_name"]
model_data["inventory_product_id"]
)
# If there's an existing active model, we may want to deactivate it
@@ -46,7 +46,7 @@ class ModelRepository(TrainingBaseRepository):
logger.info("Deactivating previous production model",
previous_model_id=existing_model.id,
tenant_id=model_data["tenant_id"],
product_name=model_data["product_name"])
inventory_product_id=model_data["inventory_product_id"])
await self.update(existing_model.id, {"is_production": False})
# Create new model
@@ -55,7 +55,7 @@ class ModelRepository(TrainingBaseRepository):
logger.info("Trained model created successfully",
model_id=model.id,
tenant_id=model.tenant_id,
product_name=model.product_name,
inventory_product_id=str(model.inventory_product_id),
model_type=model.model_type)
return model
@@ -65,21 +65,21 @@ class ModelRepository(TrainingBaseRepository):
except Exception as e:
logger.error("Failed to create trained model",
tenant_id=model_data.get("tenant_id"),
product_name=model_data.get("product_name"),
inventory_product_id=model_data.get("inventory_product_id"),
error=str(e))
raise DatabaseError(f"Failed to create model: {str(e)}")
async def get_model_by_tenant_and_product(
self,
tenant_id: str,
product_name: str
inventory_product_id: str
) -> List[TrainedModel]:
"""Get all models for a tenant and product"""
try:
return await self.get_multi(
filters={
"tenant_id": tenant_id,
"product_name": product_name
"inventory_product_id": inventory_product_id
},
order_by="created_at",
order_desc=True
@@ -87,21 +87,21 @@ class ModelRepository(TrainingBaseRepository):
except Exception as e:
logger.error("Failed to get models by tenant and product",
tenant_id=tenant_id,
product_name=product_name,
inventory_product_id=inventory_product_id,
error=str(e))
raise DatabaseError(f"Failed to get models: {str(e)}")
async def get_active_model_for_product(
self,
tenant_id: str,
product_name: str
inventory_product_id: str
) -> Optional[TrainedModel]:
"""Get the active production model for a product"""
try:
models = await self.get_multi(
filters={
"tenant_id": tenant_id,
"product_name": product_name,
"inventory_product_id": inventory_product_id,
"is_active": True,
"is_production": True
},
@@ -113,7 +113,7 @@ class ModelRepository(TrainingBaseRepository):
except Exception as e:
logger.error("Failed to get active model for product",
tenant_id=tenant_id,
product_name=product_name,
inventory_product_id=inventory_product_id,
error=str(e))
raise DatabaseError(f"Failed to get active model: {str(e)}")
@@ -137,7 +137,7 @@ class ModelRepository(TrainingBaseRepository):
# Deactivate other production models for the same tenant+product
await self._deactivate_other_production_models(
model.tenant_id,
model.product_name,
str(model.inventory_product_id),
model_id
)
@@ -150,7 +150,7 @@ class ModelRepository(TrainingBaseRepository):
logger.info("Model promoted to production",
model_id=model_id,
tenant_id=model.tenant_id,
product_name=model.product_name)
inventory_product_id=str(model.inventory_product_id))
return updated_model
@@ -223,16 +223,16 @@ class ModelRepository(TrainingBaseRepository):
# Get models by product using raw query
product_query = text("""
SELECT product_name, COUNT(*) as count
SELECT inventory_product_id, COUNT(*) as count
FROM trained_models
WHERE tenant_id = :tenant_id
AND is_active = true
GROUP BY product_name
GROUP BY inventory_product_id
ORDER BY count DESC
""")
result = await self.session.execute(product_query, {"tenant_id": tenant_id})
product_stats = {row.product_name: row.count for row in result.fetchall()}
product_stats = {row.inventory_product_id: row.count for row in result.fetchall()}
# Recent activity (models created in last 30 days)
thirty_days_ago = datetime.utcnow() - timedelta(days=30)
@@ -274,7 +274,7 @@ class ModelRepository(TrainingBaseRepository):
async def _deactivate_other_production_models(
self,
tenant_id: str,
product_name: str,
inventory_product_id: str,
exclude_model_id: str
) -> int:
"""Deactivate other production models for the same tenant+product"""
@@ -283,14 +283,14 @@ class ModelRepository(TrainingBaseRepository):
UPDATE trained_models
SET is_production = false
WHERE tenant_id = :tenant_id
AND product_name = :product_name
AND inventory_product_id = :inventory_product_id
AND id != :exclude_model_id
AND is_production = true
""")
result = await self.session.execute(query, {
"tenant_id": tenant_id,
"product_name": product_name,
"inventory_product_id": inventory_product_id,
"exclude_model_id": exclude_model_id
})
@@ -299,7 +299,7 @@ class ModelRepository(TrainingBaseRepository):
except Exception as e:
logger.error("Failed to deactivate other production models",
tenant_id=tenant_id,
product_name=product_name,
inventory_product_id=inventory_product_id,
error=str(e))
raise DatabaseError(f"Failed to deactivate models: {str(e)}")
@@ -313,7 +313,7 @@ class ModelRepository(TrainingBaseRepository):
return {
"model_id": model.id,
"tenant_id": model.tenant_id,
"product_name": model.product_name,
"inventory_product_id": str(model.inventory_product_id),
"model_type": model.model_type,
"metrics": {
"mape": model.mape,