refactor: extract duplicated patterns into shared helpers

Backend: create api/helpers.py with eligible_enrollment_filter,
count_eligible_students, get_active_enrollment, ensure_unique_name,
upsert_app_configs, and build_heatmap. Add full_name properties to
Student model. Apply across all route files (-481/+184 lines).

Frontend: create stores/helpers.js with withLoading composable,
apply to assessments and classes Pinia stores.

96/96 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 14:05:10 +01:00
parent b1b7d12a9f
commit a0ab7224e1
10 changed files with 402 additions and 481 deletions

View File

@@ -12,6 +12,7 @@ from sqlalchemy import select, func
from sqlalchemy.orm import selectinload
from api.dependencies import AsyncSessionDep
from api.helpers import ensure_unique_name
from infrastructure.database.models import (
ClassGroup,
Student,
@@ -201,7 +202,7 @@ async def get_class_students(
last_name=student.last_name,
first_name=student.first_name,
email=student.email,
full_name=f"{student.first_name} {student.last_name}",
full_name=student.full_name,
current_class_id=class_id if is_active else None,
current_class_name=cls.name if is_active else None,
enrollment_id=enrollment.id,
@@ -419,13 +420,7 @@ async def create_class(
Crée une nouvelle classe.
"""
# Vérifier l'unicité du nom
existing_query = select(ClassGroup).where(ClassGroup.name == class_data.name)
existing_result = await session.execute(existing_query)
if existing_result.scalar_one_or_none():
raise HTTPException(
status_code=400,
detail=f"Une classe avec le nom '{class_data.name}' existe déjà"
)
await ensure_unique_name(session, ClassGroup, class_data.name, entity_label="classe")
# Créer la nouvelle classe
new_class = ClassGroup(
@@ -466,16 +461,10 @@ async def update_class(
# Vérifier l'unicité du nouveau nom si modifié
if class_data.name and class_data.name != cls.name:
existing_query = select(ClassGroup).where(
ClassGroup.name == class_data.name,
ClassGroup.id != class_id
await ensure_unique_name(
session, ClassGroup, class_data.name,
exclude_id=class_id, entity_label="classe"
)
existing_result = await session.execute(existing_query)
if existing_result.scalar_one_or_none():
raise HTTPException(
status_code=400,
detail=f"Une autre classe avec le nom '{class_data.name}' existe déjà"
)
# Appliquer les modifications
if class_data.name is not None: