from sqlalchemy.orm import Session from sqlalchemy.exc import IntegrityError from fastapi import HTTPException from typing import List import uuid from app.models.auth.module_model import Module from app.models.auth.module_environment_model import ModuleEnvironment from app.schemas.auth.module_environment_schema import EnvironmentCreate, EnvironmentUpdate class ModuleEnvironmentService: @staticmethod def list_environments(db: Session, module_id: str) -> List[ModuleEnvironment]: module = db.query(Module).filter(Module.id == uuid.UUID(module_id)).first() if not module: raise HTTPException(status_code=404, detail="Module not found") return db.query(ModuleEnvironment).filter( ModuleEnvironment.module_id == module.id ).order_by(ModuleEnvironment.is_default.desc(), ModuleEnvironment.slug).all() @staticmethod def create_environment(db: Session, module_id: str, env_data: EnvironmentCreate) -> ModuleEnvironment: module = db.query(Module).filter(Module.id == uuid.UUID(module_id)).first() if not module: raise HTTPException(status_code=404, detail="Module not found") if env_data.is_default: db.query(ModuleEnvironment).filter( ModuleEnvironment.module_id == module.id, ModuleEnvironment.is_default == True ).update({"is_default": False}) try: environment = ModuleEnvironment( module_id=module.id, slug=env_data.slug, frontend_base_url=env_data.frontend_base_url, backend_base_url=env_data.backend_base_url, sso_entry_path=env_data.sso_entry_path, permission_sync_endpoint=env_data.permission_sync_endpoint, sso_exchange_endpoint=env_data.sso_exchange_endpoint, trust_type=env_data.trust_type, trust_credentials=env_data.trust_credentials, is_default=env_data.is_default, is_active=env_data.is_active ) db.add(environment) db.commit() db.refresh(environment) return environment except IntegrityError: db.rollback() raise HTTPException(status_code=409, detail="Environment slug already exists for this module") @staticmethod def update_environment(db: Session, module_id: str, env_id: str, env_data: EnvironmentUpdate) -> ModuleEnvironment: environment = db.query(ModuleEnvironment).filter( ModuleEnvironment.id == uuid.UUID(env_id), ModuleEnvironment.module_id == uuid.UUID(module_id) ).first() if not environment: raise HTTPException(status_code=404, detail="Environment not found") if env_data.is_default and env_data.is_default != environment.is_default: db.query(ModuleEnvironment).filter( ModuleEnvironment.module_id == environment.module_id, ModuleEnvironment.id != environment.id, ModuleEnvironment.is_default == True ).update({"is_default": False}) update_data = env_data.model_dump(exclude_unset=True) for key, value in update_data.items(): setattr(environment, key, value) db.commit() db.refresh(environment) return environment @staticmethod def set_default_environment(db: Session, module_id: str, env_id: str): environment = db.query(ModuleEnvironment).filter( ModuleEnvironment.id == uuid.UUID(env_id), ModuleEnvironment.module_id == uuid.UUID(module_id) ).first() if not environment: raise HTTPException(status_code=404, detail="Environment not found") db.query(ModuleEnvironment).filter( ModuleEnvironment.module_id == environment.module_id ).update({"is_default": False}) environment.is_default = True db.commit() @staticmethod def delete_environment(db: Session, module_id: str, env_id: str): environment = db.query(ModuleEnvironment).filter( ModuleEnvironment.id == uuid.UUID(env_id), ModuleEnvironment.module_id == uuid.UUID(module_id) ).first() if not environment: raise HTTPException(status_code=404, detail="Environment not found") if environment.is_default: raise HTTPException(status_code=400, detail="Cannot delete default environment. Set another environment as default first.") db.delete(environment) db.commit()