remodulation du projet en POO et changement de l'organisation des fichiers

This commit is contained in:
cedrick2711
2026-07-29 13:57:06 -04:00
parent 3feae80767
commit b69eaabbba
51 changed files with 970 additions and 873 deletions
+9
View File
@@ -0,0 +1,9 @@
"""User hierarchy — single-table polymorphic inheritance (User → Admin, Manager, Coach, Player, Scout)."""
from app.models.user_model.user import User
from app.models.user_model.admin import Admin
from app.models.user_model.manager import Manager
from app.models.user_model.coach import Coach
from app.models.user_model.player import Player
from app.models.user_model.scout import Scout
__all__ = ['User', 'Admin', 'Manager', 'Coach', 'Player', 'Scout']
+32
View File
@@ -0,0 +1,32 @@
"""Admin / President — full access to everything."""
from app.models.user_model.user import User
class Admin(User):
"""President / super-admin — full access to everything."""
__mapper_args__ = {'polymorphic_identity': 'admin'}
def can_evaluate(self):
return True
def can_manage_users(self):
return True
def can_manage_teams(self):
return True
def can_manage_tryouts(self):
return True
def can_schedule_matches(self):
return True
def can_manage_this_tryout(self, tryout):
return True
def can_manage_this_org_team(self, org_team):
return True
def get_visible_tryouts(self):
from app.models.tryout.tryout import Tryout
return Tryout.query.order_by(Tryout.date).all()
+45
View File
@@ -0,0 +1,45 @@
"""Coach — evaluates, schedules matches, manages their own org team."""
from app.models.user_model.user import User
class Coach(User):
"""Coach — evaluates, schedules matches, manages their own org team."""
__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.models.org_team.org_team import OrgTeam
if tryout.target_org_team_id:
is_coach_of_target = OrgTeam.query.filter(
OrgTeam.id == tryout.target_org_team_id,
OrgTeam.coaches.any(id=self.id),
).first() is not None
if is_coach_of_target:
return True
if tryout.coach_id == self.id:
return True
return False
def can_manage_this_org_team(self, org_team):
if org_team.coaches.filter_by(id=self.id).first():
return True
if org_team.coach_id == self.id:
return True
return False
def get_visible_tryouts(self):
from app.models.tryout.tryout import Tryout
team_ids = [t.id for t in self.coached_org_teams.all()]
if not team_ids:
return Tryout.query.filter(Tryout.id == -1).all() # empty
return Tryout.query.filter(
Tryout.target_org_team_id.in_(team_ids)
).order_by(Tryout.date).all()
+29
View File
@@ -0,0 +1,29 @@
"""Manager — manages own tryouts, all org teams, all contracts."""
from app.models.user_model.user import User
class Manager(User):
"""Manager — manages own tryouts, all org teams, all contracts."""
__mapper_args__ = {'polymorphic_identity': 'manager'}
def can_evaluate(self):
return True
def can_manage_teams(self):
return True
def can_manage_tryouts(self):
return True
def can_schedule_matches(self):
return True
def can_manage_this_tryout(self, tryout):
return tryout.created_by == self.id or tryout.manager_id == self.id
def can_manage_this_org_team(self, org_team):
return True
def get_visible_tryouts(self):
from app.models.tryout.tryout import Tryout
return Tryout.query.filter_by(created_by=self.id).order_by(Tryout.date).all()
+30
View File
@@ -0,0 +1,30 @@
"""Player — registers for tryouts, manages their own profile."""
from app.models.user_model.user import User
class Player(User):
"""Player — registers for tryouts, manages their own profile."""
__mapper_args__ = {'polymorphic_identity': 'player'}
def get_visible_tryouts(self):
from app.models.tryout.tryout import Tryout
from app.models.match_model.match import Match
from app.models.participant.match_participant import MatchParticipant
# tryouts they registered for
player_tryout_ids = [r.tryout_id for r in self.tryout_registrations.all()]
tryouts = Tryout.query.filter(
Tryout.id.in_(player_tryout_ids)
).order_by(Tryout.date).all() if player_tryout_ids else []
# plus tryouts where they participate in a match
player_matches = Match.query.join(MatchParticipant).filter(
MatchParticipant.player_id == self.id,
).all()
extra_ids = set(m.tryout_id for m in player_matches)
extra = Tryout.query.filter(
Tryout.id.in_(extra_ids),
).order_by(Tryout.date).all() if extra_ids else []
all_ids = {t.id for t in tryouts}
return tryouts + [t for t in extra if t.id not in all_ids]
+14
View File
@@ -0,0 +1,14 @@
"""Scout — view-only access to tryouts and evaluations."""
from app.models.user_model.user import User
class Scout(User):
"""Scout — view-only access to tryouts and evaluations."""
__mapper_args__ = {'polymorphic_identity': 'scout'}
def can_evaluate(self):
return True
def get_visible_tryouts(self):
from app.models.tryout.tryout import Tryout
return Tryout.query.order_by(Tryout.date).all()
+93
View File
@@ -0,0 +1,93 @@
"""Base User model — shared fields and polymorphic configuration."""
from app.extensions import db
from flask_login import UserMixin
from datetime import datetime
class User(UserMixin, db.Model):
"""Base user model — shared fields for every role.
Do not instantiate this class directly; use Admin, Manager, Coach, Player,
or Scout so that `polymorphic_identity` is set correctly.
"""
__tablename__ = 'users'
# --- columns -----------------------------------------------------------
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
role = db.Column(db.String(20), nullable=False, default='player') # polymorphic discriminator
full_name = db.Column(db.String(100), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
phone = db.Column(db.String(20), nullable=True)
is_active_account = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
failed_login_attempts = db.Column(db.Integer, default=0)
locked_until = db.Column(db.DateTime, nullable=True)
# E-Sports fields
games = db.Column(db.Text, nullable=True) # comma-separated (only meaningful for Player)
discord_username = db.Column(db.String(128), nullable=True)
discord_user_id = db.Column(db.String(64), nullable=True)
league_os_profile = db.Column(db.String(256), nullable=True)
# --- polymorphic configuration -----------------------------------------
__mapper_args__ = {
'polymorphic_identity': 'user',
'polymorphic_on': role,
}
# --- relationships (defined once on the base) --------------------------
evaluations_given = db.relationship(
'Evaluation', foreign_keys='Evaluation.evaluator_id',
backref='evaluator', lazy='dynamic')
evaluations_received = db.relationship(
'Evaluation', foreign_keys='Evaluation.player_id',
backref='player', lazy='dynamic')
tryout_registrations = db.relationship(
'TryoutRegistration', backref='player', lazy='dynamic')
team_assignments = db.relationship(
'TeamMember', foreign_keys='TeamMember.player_id',
backref='player_ref', lazy='dynamic')
# --- shared helper methods ---------------------------------------------
def get_games_list(self):
"""Return the user's games as a list."""
if self.games:
return [g.strip() for g in self.games.split(',') if g.strip()]
return []
def get_gamertags(self):
"""Return gamertags as a dict keyed by game."""
return {gt.game: {'gamertag': gt.gamertag, 'platform': gt.platform}
for gt in self.gamertags}
def get_org_teams(self):
"""Return all OrgTeams this player belongs to."""
return [tp.org_team for tp in self.team_placements]
# --- stubs (overridden in subclasses) ----------------------------------
def can_evaluate(self):
return False
def can_manage_users(self):
return False
def can_manage_teams(self):
return False
def can_manage_tryouts(self):
return False
def can_schedule_matches(self):
return False
def can_manage_this_tryout(self, tryout):
return False
def can_manage_this_org_team(self, org_team):
return False
def get_visible_tryouts(self):
return []