156 lines
5.1 KiB
Python
156 lines
5.1 KiB
Python
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
|
|
]
|
|
}
|
|
}) |