ARCH-002. La question "a quelles equipes ce coach est-il rattache ?" etait
posee a huit endroits, de cinq facons differentes, et trois d entre elles
donnaient une mauvaise reponse en production.
Le motif fautif, present tel quel dans six routes :
OrgTeam.query.filter_by(coach_id=user.id).first()
Il repond au plus une equipe, et seulement par la colonne heritee. Deux
pannes en decoulaient, silencieuses -- les pages s affichaient, vides :
- un coach rattache uniquement par la relation many-to-many n avait
aucune equipe, donc aucun joueur, aucun contrat, aucune note d equipe,
aucun match a venir sur son tableau de bord ;
- un coach de deux equipes n en voyait qu une. Le formulaire de contrat
lui proposait la moitie de son effectif, alors que la route POST
acceptait l autre moitie.
app/permissions.py devient le module ou la question se pose une fois :
coach_org_teams, manager_org_teams, attached_org_teams, visible_org_teams,
can_manage_org_team, org_team_player_ids, coach_player_ids,
can_manage_player_contract, coach_tryouts, coach_manages_tryout. Toutes
lisent les deux rattachements et toutes les equipes.
Le meme ecart existait dans le modele : Coach.get_visible_tryouts ne lisait
que la relation m2m -- calendrier vide pour un coach rattache par la
colonne -- et can_manage_this_tryout ignorait la colonne pour l equipe
cible. Les deux delegent desormais.
Corrections de portee, au passage
- one_on_one lisait org_team.coach_id : un joueur dont l equipe declare
ses coachs par la relation etait informe qu il n avait pas de coach, et
le formulaire de demande restait ferme. Passe par get_coaches(), qui
retombe deja sur la colonne heritee.
- notes_dashboard conditionnait les notes personnelles du coach a
l existence d une equipe : un coach sans equipe ne voyait pas ses
propres notes.
- can_manage_team_match reformulait can_manage_this_org_team ; la
reformulation avait derive. Elle appelle maintenant la regle.
Limite assumee : le panneau de notes d equipe reste ecrit pour une seule
equipe et affiche donc la premiere. La resolution est corrigee, la mise en
page multi-equipes ne l est pas -- c est un choix produit, pas un bug.
14 tests ajoutes. Cinq echouent sur le code d avant, verifie en remettant
les routes et le modele a leur etat precedent.
ARCH-001 fera disparaitre la colonne heritee ; cela demande une migration
de donnees, donc Alembic. D ici la, ce module est ce qui rend la
duplication inoffensive.
Co-Authored-By: Claude Opus 5 <[email protected]>
39 lines
1.4 KiB
Python
39 lines
1.4 KiB
Python
"""Coach — evaluates, schedules matches, manages their own org teams."""
|
|
from app.models.user_model.user import User
|
|
|
|
|
|
class Coach(User):
|
|
"""Coach — evaluates, schedules matches, manages their own org teams.
|
|
|
|
Every question about *which* teams or tryouts belong to this coach is
|
|
delegated to ``app.permissions``. Two of the three methods below used to
|
|
answer it themselves, each considering a different subset of the two
|
|
ways a coach can be attached to a team: ``can_manage_this_tryout``
|
|
ignored the legacy ``coach_id`` column when checking the target team,
|
|
and ``get_visible_tryouts`` ignored it entirely. A coach attached only
|
|
by that column therefore saw an empty calendar (ARCH-002).
|
|
"""
|
|
__mapper_args__ = {'polymorphic_identity': 'coach'}
|
|
|
|
def can_evaluate(self):
|
|
return True
|
|
|
|
def can_schedule_matches(self):
|
|
return True
|
|
|
|
def can_manage_tryouts(self):
|
|
return True
|
|
|
|
def can_manage_this_tryout(self, tryout):
|
|
from app.permissions import coach_manages_tryout
|
|
return coach_manages_tryout(self, tryout)
|
|
|
|
def can_manage_this_org_team(self, org_team):
|
|
if org_team.coaches.filter_by(id=self.id).first():
|
|
return True
|
|
return org_team.coach_id == self.id
|
|
|
|
def get_visible_tryouts(self):
|
|
from app.permissions import coach_tryouts
|
|
return coach_tryouts(self)
|