This commit is contained in:
@@ -128,3 +128,18 @@ Générer la migration initiale depuis les modèles « pour avancer en
|
||||
attendant ». Ça produit un dépôt qui a l'air d'avoir des migrations, une
|
||||
production estampillée sur un état qu'elle n'a pas, et la dérive préservée
|
||||
sous une couche de plus.
|
||||
|
||||
## Ajouts de colonnes faits à la main
|
||||
|
||||
En attendant Alembic, une colonne ajoutée à un modèle doit être rattrapée sur
|
||||
les bases existantes par un script, en plus du modèle (pour les installations
|
||||
neuves, via `create_all()`). `migrations/add_tryout_coaches.py` a ouvert la
|
||||
voie ; `migrations/add_team_representative.py` ajoute
|
||||
`team_players.is_team_representative` de la même façon : lecture du catalogue,
|
||||
`ALTER TABLE ... ADD COLUMN` idempotent, rien si la colonne est déjà là.
|
||||
|
||||
Le script trouve sa base tout seul : `DATABASE_URL` s'il est défini (production,
|
||||
CI), sinon les valeurs `LOCAL_PG*` de `app/.env` — le serveur de développement
|
||||
est réutilisé s'il répond, sinon (re)démarré puis arrêté à la fin du script :
|
||||
|
||||
python migrations/add_team_representative.py
|
||||
|
||||
@@ -64,6 +64,31 @@ voulue, elle n'est écrite nulle part ailleurs qu'ici.
|
||||
| Coach | rattaché à l'équipe, par la relation m2m **ou** par la colonne héritée |
|
||||
| Recruteur, Joueur | toujours faux |
|
||||
|
||||
### `can_manage_team_matches(team)`
|
||||
|
||||
Plus étroite que `can_manage_this_org_team`, et c'est voulu : elle répond à
|
||||
« peut-on gérer les matchs et les entraînements de cette équipe ? ».
|
||||
|
||||
| Rôle | Règle |
|
||||
|---|---|
|
||||
| Président, Gérant | toujours vrai |
|
||||
| Coach | rattaché à l'équipe (m2m **ou** colonne héritée) |
|
||||
| Joueur responsable | vrai pour **sa seule** équipe |
|
||||
| Recruteur, Joueur | faux |
|
||||
|
||||
### Le joueur responsable
|
||||
|
||||
Un **joueur responsable** est un joueur qu'un **président** désigne, depuis la
|
||||
page Équipes, sur la ligne de son équipe (étoile à côté du bouton de retrait).
|
||||
Il peut planifier, modifier et supprimer les **matchs et entraînements** de
|
||||
cette équipe, et rien d'autre : ni l'effectif, ni les notes, ni le statut
|
||||
partant/remplaçant, qui restent réservés au personnel.
|
||||
|
||||
Le drapeau vit sur `team_players.is_team_representative` (voir
|
||||
`docs/database-schema.md`). La désignation est la décision du président —
|
||||
`can_designate_team_representative()`, vrai seulement pour `Admin` — pour
|
||||
qu'un responsable ne puisse pas se reproduire lui-même.
|
||||
|
||||
## Le piège : deux façons d'être rattaché
|
||||
|
||||
C'est le point le plus coûteux de tout le modèle d'autorisation, et il est
|
||||
@@ -117,6 +142,9 @@ contexte de requête.
|
||||
| `attached_org_teams(user)` | Les équipes auxquelles cette personne est rattachée, quel que soit son rôle |
|
||||
| `visible_org_teams(user)` | Ce qu'elle a le droit de voir |
|
||||
| `can_manage_org_team(user, team)` | Peut-elle administrer cette équipe |
|
||||
| `can_manage_team_matches(user, team)` | Peut-elle gérer les matchs et entraînements de cette équipe |
|
||||
| `is_team_representative(user, team)` | Est-elle le responsable désigné de cette équipe |
|
||||
| `representative_org_teams(user)` | Les équipes dont elle est le responsable |
|
||||
| `coach_player_ids(coach)` | Les joueurs qu'il encadre |
|
||||
| `coach_can_access_player(coach, id)` | Peut-il lire la fiche de ce joueur |
|
||||
| `can_manage_player_contract(user, id)` | Peut-elle déposer un contrat pour lui |
|
||||
|
||||
Reference in New Issue
Block a user