Improve the frontend 3

This commit is contained in:
Urtzi Alfaro
2025-10-30 21:08:07 +01:00
parent 36217a2729
commit 63f5c6d512
184 changed files with 21512 additions and 7442 deletions

View File

@@ -0,0 +1,175 @@
# ================================================================
# services/orchestrator/app/repositories/orchestration_run_repository.py
# ================================================================
"""
Orchestration Run Repository - Database operations for orchestration audit trail
"""
import uuid
from datetime import datetime, date
from typing import List, Optional, Dict, Any
from sqlalchemy import select, and_, desc, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.orchestration_run import OrchestrationRun, OrchestrationStatus
class OrchestrationRunRepository:
"""Repository for orchestration run operations"""
def __init__(self, db: AsyncSession):
self.db = db
async def create_run(self, run_data: Dict[str, Any]) -> OrchestrationRun:
"""Create a new orchestration run"""
run = OrchestrationRun(**run_data)
self.db.add(run)
await self.db.flush()
return run
async def get_run_by_id(self, run_id: uuid.UUID) -> Optional[OrchestrationRun]:
"""Get orchestration run by ID"""
stmt = select(OrchestrationRun).where(OrchestrationRun.id == run_id)
result = await self.db.execute(stmt)
return result.scalar_one_or_none()
async def update_run(self, run_id: uuid.UUID, updates: Dict[str, Any]) -> Optional[OrchestrationRun]:
"""Update orchestration run"""
run = await self.get_run_by_id(run_id)
if not run:
return None
for key, value in updates.items():
if hasattr(run, key):
setattr(run, key, value)
run.updated_at = datetime.utcnow()
await self.db.flush()
return run
async def list_runs(
self,
tenant_id: Optional[uuid.UUID] = None,
status: Optional[OrchestrationStatus] = None,
start_date: Optional[date] = None,
end_date: Optional[date] = None,
limit: int = 50,
offset: int = 0
) -> List[OrchestrationRun]:
"""List orchestration runs with filters"""
conditions = []
if tenant_id:
conditions.append(OrchestrationRun.tenant_id == tenant_id)
if status:
conditions.append(OrchestrationRun.status == status)
if start_date:
conditions.append(func.date(OrchestrationRun.started_at) >= start_date)
if end_date:
conditions.append(func.date(OrchestrationRun.started_at) <= end_date)
stmt = (
select(OrchestrationRun)
.where(and_(*conditions) if conditions else True)
.order_by(desc(OrchestrationRun.started_at))
.limit(limit)
.offset(offset)
)
result = await self.db.execute(stmt)
return result.scalars().all()
async def get_latest_run_for_tenant(self, tenant_id: uuid.UUID) -> Optional[OrchestrationRun]:
"""Get the most recent orchestration run for a tenant"""
stmt = (
select(OrchestrationRun)
.where(OrchestrationRun.tenant_id == tenant_id)
.order_by(desc(OrchestrationRun.started_at))
.limit(1)
)
result = await self.db.execute(stmt)
return result.scalar_one_or_none()
async def generate_run_number(self) -> str:
"""Generate unique run number"""
today = date.today()
date_str = today.strftime("%Y%m%d")
# Count existing runs for today
stmt = select(func.count(OrchestrationRun.id)).where(
func.date(OrchestrationRun.started_at) == today
)
result = await self.db.execute(stmt)
count = result.scalar() or 0
return f"ORCH-{date_str}-{count + 1:04d}"
async def get_failed_runs(self, limit: int = 10) -> List[OrchestrationRun]:
"""Get recent failed orchestration runs"""
stmt = (
select(OrchestrationRun)
.where(OrchestrationRun.status == OrchestrationStatus.failed)
.order_by(desc(OrchestrationRun.started_at))
.limit(limit)
)
result = await self.db.execute(stmt)
return result.scalars().all()
async def get_run_statistics(
self,
start_date: Optional[date] = None,
end_date: Optional[date] = None
) -> Dict[str, Any]:
"""Get orchestration run statistics"""
conditions = []
if start_date:
conditions.append(func.date(OrchestrationRun.started_at) >= start_date)
if end_date:
conditions.append(func.date(OrchestrationRun.started_at) <= end_date)
where_clause = and_(*conditions) if conditions else True
# Total runs
total_stmt = select(func.count(OrchestrationRun.id)).where(where_clause)
total_result = await self.db.execute(total_stmt)
total_runs = total_result.scalar() or 0
# Successful runs
success_stmt = select(func.count(OrchestrationRun.id)).where(
and_(
where_clause,
OrchestrationRun.status == OrchestrationStatus.completed
)
)
success_result = await self.db.execute(success_stmt)
successful_runs = success_result.scalar() or 0
# Failed runs
failed_stmt = select(func.count(OrchestrationRun.id)).where(
and_(
where_clause,
OrchestrationRun.status == OrchestrationStatus.failed
)
)
failed_result = await self.db.execute(failed_stmt)
failed_runs = failed_result.scalar() or 0
# Average duration
avg_duration_stmt = select(func.avg(OrchestrationRun.duration_seconds)).where(
and_(
where_clause,
OrchestrationRun.status == OrchestrationStatus.completed
)
)
avg_duration_result = await self.db.execute(avg_duration_stmt)
avg_duration = avg_duration_result.scalar() or 0
return {
'total_runs': total_runs,
'successful_runs': successful_runs,
'failed_runs': failed_runs,
'success_rate': (successful_runs / total_runs * 100) if total_runs > 0 else 0,
'average_duration_seconds': float(avg_duration) if avg_duration else 0
}