New enterprise feature

This commit is contained in:
Urtzi Alfaro
2025-11-30 09:12:40 +01:00
parent f9d0eec6ec
commit 972db02f6d
176 changed files with 19741 additions and 1361 deletions

View File

@@ -260,44 +260,44 @@ class ArtifactRepository(TrainingBaseRepository):
base_filters = {}
if tenant_id:
base_filters["tenant_id"] = tenant_id
# Get basic counts
total_artifacts = await self.count(filters=base_filters)
# Get artifacts by type
type_query_params = {}
type_query_filter = ""
if tenant_id:
type_query_filter = "WHERE tenant_id = :tenant_id"
type_query_params["tenant_id"] = tenant_id
type_query = text(f"""
SELECT artifact_type, COUNT(*) as count
FROM model_artifacts
SELECT artifact_type, COUNT(*) as count
FROM model_artifacts
{type_query_filter}
GROUP BY artifact_type
ORDER BY count DESC
""")
result = await self.session.execute(type_query, type_query_params)
artifacts_by_type = {row.artifact_type: row.count for row in result.fetchall()}
# Get storage location stats
location_query = text(f"""
SELECT
storage_location,
SELECT
storage_location,
COUNT(*) as count,
SUM(COALESCE(file_size_bytes, 0)) as total_size_bytes
FROM model_artifacts
FROM model_artifacts
{type_query_filter}
GROUP BY storage_location
ORDER BY count DESC
""")
location_result = await self.session.execute(location_query, type_query_params)
storage_stats = {}
total_size_bytes = 0
for row in location_result.fetchall():
storage_stats[row.storage_location] = {
"artifact_count": row.count,
@@ -305,10 +305,10 @@ class ArtifactRepository(TrainingBaseRepository):
"total_size_mb": round((row.total_size_bytes or 0) / (1024 * 1024), 2)
}
total_size_bytes += row.total_size_bytes or 0
# Get expired artifacts count
expired_artifacts = len(await self.get_expired_artifacts())
return {
"total_artifacts": total_artifacts,
"expired_artifacts": expired_artifacts,
@@ -321,7 +321,7 @@ class ArtifactRepository(TrainingBaseRepository):
"total_size_gb": round(total_size_bytes / (1024 * 1024 * 1024), 2)
}
}
except Exception as e:
logger.error("Failed to get artifact statistics",
tenant_id=tenant_id,

View File

@@ -35,25 +35,22 @@ logger = structlog.get_logger()
# ============================================================================
# Demo Tenant IDs (from seed_demo_tenants.py)
DEMO_TENANT_SAN_PABLO = UUID("a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6")
DEMO_TENANT_LA_ESPIGA = UUID("b2c3d4e5-f6a7-48b9-c0d1-e2f3a4b5c6d7")
DEMO_TENANT_PROFESSIONAL = UUID("a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6") # Panadería Artesana Madrid
DEMO_TENANT_ENTERPRISE_CHAIN = UUID("c3d4e5f6-a7b8-49c0-d1e2-f3a4b5c6d7e8") # Enterprise parent (Obrador)
# Sample Product IDs for each tenant (these should match finished products from inventory seed)
# Note: These are example UUIDs - in production, these would be actual product IDs from inventory
DEMO_PRODUCTS = {
DEMO_TENANT_SAN_PABLO: [
{"id": UUID("10000000-0000-0000-0000-000000000001"), "name": "Barra de Pan"},
{"id": UUID("10000000-0000-0000-0000-000000000002"), "name": "Croissant"},
{"id": UUID("10000000-0000-0000-0000-000000000003"), "name": "Magdalenas"},
{"id": UUID("10000000-0000-0000-0000-000000000004"), "name": "Empanada"},
{"id": UUID("10000000-0000-0000-0000-000000000005"), "name": "Pan Integral"},
DEMO_TENANT_PROFESSIONAL: [
{"id": UUID("20000000-0000-0000-0000-000000000001"), "name": "Baguette Tradicional"},
{"id": UUID("20000000-0000-0000-0000-000000000002"), "name": "Croissant de Mantequilla"},
{"id": UUID("20000000-0000-0000-0000-000000000003"), "name": "Pan de Pueblo"},
{"id": UUID("20000000-0000-0000-0000-000000000004"), "name": "Napolitana de Chocolate"},
],
DEMO_TENANT_LA_ESPIGA: [
{"id": UUID("20000000-0000-0000-0000-000000000001"), "name": "Pan de Molde"},
{"id": UUID("20000000-0000-0000-0000-000000000002"), "name": "Bollo Suizo"},
{"id": UUID("20000000-0000-0000-0000-000000000003"), "name": "Palmera de Chocolate"},
{"id": UUID("20000000-0000-0000-0000-000000000004"), "name": "Napolitana"},
{"id": UUID("20000000-0000-0000-0000-000000000005"), "name": "Pan Rústico"},
DEMO_TENANT_ENTERPRISE_CHAIN: [
# Same products as professional but for enterprise parent (Obrador)
{"id": UUID("20000000-0000-0000-0000-000000000001"), "name": "Baguette Tradicional"},
{"id": UUID("20000000-0000-0000-0000-000000000002"), "name": "Croissant de Mantequilla"},
{"id": UUID("20000000-0000-0000-0000-000000000003"), "name": "Pan de Pueblo"},
{"id": UUID("20000000-0000-0000-0000-000000000004"), "name": "Napolitana de Chocolate"},
]
}
@@ -210,21 +207,21 @@ class DemoAIModelSeeder:
total_models_created = 0
try:
# Seed models for San Pablo
san_pablo_count = await self.seed_models_for_tenant(
tenant_id=DEMO_TENANT_SAN_PABLO,
tenant_name="Panadería San Pablo",
products=DEMO_PRODUCTS[DEMO_TENANT_SAN_PABLO]
# Professional Bakery (single location)
professional_count = await self.seed_models_for_tenant(
tenant_id=DEMO_TENANT_PROFESSIONAL,
tenant_name="Panadería Artesana Madrid (Professional)",
products=DEMO_PRODUCTS[DEMO_TENANT_PROFESSIONAL]
)
total_models_created += san_pablo_count
total_models_created += professional_count
# Seed models for La Espiga
la_espiga_count = await self.seed_models_for_tenant(
tenant_id=DEMO_TENANT_LA_ESPIGA,
tenant_name="Panadería La Espiga",
products=DEMO_PRODUCTS[DEMO_TENANT_LA_ESPIGA]
# Enterprise Parent (central production - Obrador)
enterprise_count = await self.seed_models_for_tenant(
tenant_id=DEMO_TENANT_ENTERPRISE_CHAIN,
tenant_name="Panadería Central - Obrador Madrid (Enterprise Parent)",
products=DEMO_PRODUCTS[DEMO_TENANT_ENTERPRISE_CHAIN]
)
total_models_created += la_espiga_count
total_models_created += enterprise_count
logger.info("=" * 80)
logger.info(