feat: add domain
This commit is contained in:
		
							
								
								
									
										156
									
								
								routes/domains.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								routes/domains.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| from flask import Blueprint, jsonify, request, current_app | ||||
| from models import db, Domain | ||||
| from app_config import config_manager | ||||
| from utils import handle_db_errors | ||||
|  | ||||
| bp = Blueprint('domains', __name__, url_prefix='/api/domains') | ||||
|  | ||||
| @bp.route('/', methods=['GET']) | ||||
| @handle_db_errors | ||||
| def list_domains(): | ||||
|     """Liste tous les domaines disponibles.""" | ||||
|     domains = config_manager.get_domains_list() | ||||
|     return jsonify({'success': True, 'domains': domains}) | ||||
|  | ||||
|  | ||||
| @bp.route('/', methods=['POST']) | ||||
| @handle_db_errors | ||||
| def create_domain(): | ||||
|     """Crée un nouveau domaine dynamiquement.""" | ||||
|     data = request.get_json() | ||||
|      | ||||
|     if not data or not data.get('name'): | ||||
|         return jsonify({'success': False, 'error': 'Nom du domaine requis'}), 400 | ||||
|      | ||||
|     name = data['name'].strip() | ||||
|     color = data.get('color', '#6B7280') | ||||
|     description = data.get('description', '') | ||||
|      | ||||
|     # Vérifier que le domaine n'existe pas déjà | ||||
|     if Domain.query.filter_by(name=name).first(): | ||||
|         return jsonify({'success': False, 'error': 'Un domaine avec ce nom existe déjà'}), 400 | ||||
|      | ||||
|     success = config_manager.add_domain(name, color, description) | ||||
|      | ||||
|     if success: | ||||
|         # Récupérer le domaine créé | ||||
|         domain = Domain.query.filter_by(name=name).first() | ||||
|         return jsonify({ | ||||
|             'success': True,  | ||||
|             'domain': { | ||||
|                 'id': domain.id, | ||||
|                 'name': domain.name, | ||||
|                 'color': domain.color, | ||||
|                 'description': domain.description or '' | ||||
|             } | ||||
|         }) | ||||
|     else: | ||||
|         return jsonify({'success': False, 'error': 'Erreur lors de la création du domaine'}), 500 | ||||
|  | ||||
| @bp.route('/search', methods=['GET']) | ||||
| @handle_db_errors | ||||
| def search_domains(): | ||||
|     """Recherche des domaines avec autocomplétion avancée.""" | ||||
|     query = request.args.get('q', '').strip() | ||||
|      | ||||
|     if not query or len(query) < 1: | ||||
|         return jsonify({'success': True, 'domains': []}) | ||||
|      | ||||
|     # Utiliser la recherche directe en base pour plus d'efficacité | ||||
|     domains_query = Domain.query.filter( | ||||
|         Domain.name.ilike(f'%{query}%') | ||||
|     ).order_by( | ||||
|         # Prioriser les correspondances exactes, puis celles qui commencent par la requête | ||||
|         db.case( | ||||
|             (Domain.name.ilike(query), 1), | ||||
|             (Domain.name.ilike(f'{query}%'), 2), | ||||
|             else_=3 | ||||
|         ), | ||||
|         Domain.name.asc() | ||||
|     ).limit(8) | ||||
|      | ||||
|     domains = domains_query.all() | ||||
|      | ||||
|     # Convertir en format JSON | ||||
|     domains_data = [{ | ||||
|         'id': domain.id, | ||||
|         'name': domain.name, | ||||
|         'color': domain.color, | ||||
|         'description': domain.description or '' | ||||
|     } for domain in domains] | ||||
|      | ||||
|     return jsonify({'success': True, 'domains': domains_data}) | ||||
|  | ||||
| @bp.route('/<int:domain_id>', methods=['PUT']) | ||||
| @handle_db_errors | ||||
| def update_domain(domain_id): | ||||
|     """Met à jour un domaine existant.""" | ||||
|     data = request.get_json() | ||||
|     domain = Domain.query.get_or_404(domain_id) | ||||
|      | ||||
|     if data.get('name'): | ||||
|         domain.name = data['name'].strip() | ||||
|     if data.get('color'): | ||||
|         domain.color = data['color'] | ||||
|     if 'description' in data: | ||||
|         domain.description = data['description'] | ||||
|      | ||||
|     try: | ||||
|         db.session.commit() | ||||
|         return jsonify({'success': True}) | ||||
|     except Exception as e: | ||||
|         db.session.rollback() | ||||
|         current_app.logger.error(f"Erreur lors de la mise à jour du domaine: {e}") | ||||
|         return jsonify({'success': False, 'error': 'Erreur lors de la sauvegarde'}), 500 | ||||
|  | ||||
| @bp.route('/<int:domain_id>', methods=['DELETE']) | ||||
| @handle_db_errors | ||||
| def delete_domain(domain_id): | ||||
|     """Supprime un domaine (si non utilisé).""" | ||||
|     domain = Domain.query.get_or_404(domain_id) | ||||
|      | ||||
|     # Vérifier que le domaine n'est pas utilisé | ||||
|     if domain.grading_elements: | ||||
|         return jsonify({ | ||||
|             'success': False,  | ||||
|             'error': f'Ce domaine est utilisé par {len(domain.grading_elements)} éléments de notation' | ||||
|         }), 400 | ||||
|      | ||||
|     try: | ||||
|         db.session.delete(domain) | ||||
|         db.session.commit() | ||||
|         return jsonify({'success': True}) | ||||
|     except Exception as e: | ||||
|         db.session.rollback() | ||||
|         current_app.logger.error(f"Erreur lors de la suppression du domaine: {e}") | ||||
|         return jsonify({'success': False, 'error': 'Erreur lors de la suppression'}), 500 | ||||
|  | ||||
| @bp.route('/<int:domain_id>/usage', methods=['GET']) | ||||
| @handle_db_errors | ||||
| def domain_usage(domain_id): | ||||
|     """Récupère les informations d'utilisation d'un domaine.""" | ||||
|     domain = Domain.query.get_or_404(domain_id) | ||||
|      | ||||
|     # Compter les éléments de notation utilisant ce domaine | ||||
|     elements_count = len(domain.grading_elements) | ||||
|      | ||||
|     # Récupérer les évaluations concernées | ||||
|     assessments = set() | ||||
|     for element in domain.grading_elements: | ||||
|         assessments.add(element.exercise.assessment) | ||||
|      | ||||
|     return jsonify({ | ||||
|         'success': True, | ||||
|         'usage': { | ||||
|             'elements_count': elements_count, | ||||
|             'assessments_count': len(assessments), | ||||
|             'assessments': [ | ||||
|                 { | ||||
|                     'id': assessment.id, | ||||
|                     'title': assessment.title, | ||||
|                     'class_name': assessment.class_group.name | ||||
|                 } | ||||
|                 for assessment in assessments | ||||
|             ] | ||||
|         } | ||||
|     }) | ||||
		Reference in New Issue
	
	Block a user