Active la regle isort (I) de ruff. 45 fichiers reordonnes, aucun
changement de comportement : la suite passe avant comme apres.
app/models/__init__.py en est exclu. Ses imports sont ranges en onze
couches commentees qui decrivent le graphe de dependances ; trier par
ordre alphabetique laisse chaque titre au-dessus d un import qu il ne
decrit pas, et ce fichier n a qu un role, etre lu.
Commit isole, comme le formatage : un diff de brassage ne doit pas
servir de couverture a un changement de comportement.
QUA-002, premiere moitie. **Ce commit ne fait que reformater** : aucun
changement de comportement, aucune ligne de logique touchee. 72 fichiers,
4 restaient deja conformes. Il est isole exprès, pour que `git log -p` sur
les commits voisins reste lisible.
`quote-style = "preserve"` etait deja pose dans pyproject.toml, ce qui
evite le brassage guillemets simples / doubles : le diff porte sur les
retours a la ligne, l indentation des appels longs et les virgules
finales, pas sur le style de chaine.
Verification : 263 tests passent avant et apres, ruff check propre.
L activation en CI arrive dans le commit suivant, separement, pour que ce
diff-ci ne contienne rien d autre.
Co-Authored-By: Claude Opus 5 <[email protected]>
DATA-004, DATA-005, DATA-006. L'audit les classait "forte probabilite" faute
de pouvoir les executer. Les tests les confirment : ce sont des bugs averes,
declenchables par tout manager ou administrateur depuis l'interface.
Erreurs reellement obtenues avant correction :
NOT NULL constraint failed: match_participants.match_id
NOT NULL constraint failed: team_matches.org_team_id
Supprimer un match (DATA-004)
Match.participants n'avait pas de cascade. SQLAlchemy tentait donc de
detacher les participants en mettant match_id a NULL, ce que la colonne
refuse. Tout match ayant eu des participants etait indestructible.
TeamMatch.participants declarait deja delete-orphan ; Match non.
Supprimer un tryout (DATA-006)
Les PersonalNote pointant vers ses matchs, equipes ou vers lui-meme
n'etaient pas traitees.
Supprimer une equipe (DATA-005)
TeamNote.org_team_id et TeamMatch.org_team_id sont NOT NULL et n'etaient
pas traites du tout. De plus la fonction validait trois fois : un echec au
troisieme temps laissait les tryouts detaches et les joueurs retires sans
que l'equipe soit supprimee -- un etat incoherent que rien ne rattrapait.
Une seule transaction desormais.
Regle appliquee, uniforme
Ce qui n'a de sens que dans le parent est supprime avec lui : participants,
membres, notes d'equipe, matchs de saison.
Ce qui lui survit est seulement detache : les notes personnelles sont les
observations d'un coach sur un joueur, pas des donnees de tryout. Les
supprimer avec le tryout detruirait du contenu sans rapport. Idem pour les
contrats et les demandes de rencontre individuelle.
Fidelite des tests
conftest.py active PRAGMA foreign_keys=ON. SQLite ignore les cles
etrangeres par defaut ; PostgreSQL les applique toujours. Sans ce reglage,
la suite pouvait valider une suppression qui echoue en production --
precisement la classe de bug corrigee ici. Les 146 tests passent avec les
contraintes actives.
9 tests, dont trois qui verifient que les entites survivantes survivent
vraiment : une note garde son contenu et perd son contexte, un tryout
survit a l'equipe qu'il visait.
Co-Authored-By: Claude Opus 5 <[email protected]>