162 lines
7.1 KiB
Python
162 lines
7.1 KiB
Python
from extensions import db, login_manager
|
|
from flask_login import UserMixin
|
|
from datetime import datetime
|
|
|
|
ROLES = ['president', 'manager', 'coach', 'player', 'scout']
|
|
|
|
# Popular E-Sports games list
|
|
ESPORT_GAMES = [
|
|
'Valorant',
|
|
'League of Legends',
|
|
'Counter-Strike 2',
|
|
'Apex Legends',
|
|
'Overwatch 2',
|
|
'Rainbow Six Siege',
|
|
'Fortnite',
|
|
'Rocket League',
|
|
'Call of Duty',
|
|
'Dota 2',
|
|
'Super Smash Bros.',
|
|
'Street Fighter 6',
|
|
]
|
|
|
|
class User(UserMixin, db.Model):
|
|
__tablename__ = 'users'
|
|
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')
|
|
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)
|
|
team_id = db.Column(db.Integer, db.ForeignKey('org_teams.id'), nullable=True)
|
|
is_active_account = db.Column(db.Boolean, default=True)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
|
|
# E-Sports specific fields
|
|
games = db.Column(db.Text, nullable=True) # Comma-separated list of games
|
|
trn_username = db.Column(db.String(120), nullable=True) # Tracker Network username
|
|
discord_username = db.Column(db.String(100), nullable=True) # Discord handle
|
|
league_os_profile = db.Column(db.String(255), nullable=True) # League OS profile URL or ID
|
|
|
|
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')
|
|
|
|
def get_games_list(self):
|
|
"""Return games as a list."""
|
|
if self.games:
|
|
return [g.strip() for g in self.games.split(',') if g.strip()]
|
|
return []
|
|
|
|
def has_role(self, *roles):
|
|
return self.role in roles
|
|
|
|
def can_evaluate(self):
|
|
return self.role in ['president', 'manager', 'coach']
|
|
|
|
def can_manage_users(self):
|
|
return self.role == 'president'
|
|
|
|
def can_manage_tryouts(self):
|
|
return self.role in ['president', 'manager']
|
|
|
|
def can_manage_teams(self):
|
|
return self.role in ['president', 'manager']
|
|
|
|
|
|
@login_manager.user_loader
|
|
def load_user(user_id):
|
|
return User.query.get(int(user_id))
|
|
|
|
|
|
class OrgTeam(db.Model):
|
|
"""Persistent organization teams (e.g., Varsity, JV) that exist across tryouts."""
|
|
__tablename__ = 'org_teams'
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(100), nullable=False, unique=True)
|
|
coach_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
|
|
created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
|
|
coach = db.relationship('User', foreign_keys=[coach_id], backref='coached_org_team', uselist=False)
|
|
creator = db.relationship('User', foreign_keys=[created_by])
|
|
players = db.relationship('User', foreign_keys='User.team_id', backref='org_team', lazy='dynamic')
|
|
|
|
|
|
class Tryout(db.Model):
|
|
__tablename__ = 'tryouts'
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
title = db.Column(db.String(200), nullable=False)
|
|
description = db.Column(db.Text, nullable=True)
|
|
date = db.Column(db.Date, nullable=False)
|
|
location = db.Column(db.String(200), nullable=True)
|
|
status = db.Column(db.String(20), default='upcoming') # upcoming, in_progress, completed
|
|
max_players = db.Column(db.Integer, nullable=True)
|
|
created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
target_org_team_id = db.Column(db.Integer, db.ForeignKey('org_teams.id'), nullable=True)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
|
|
creator = db.relationship('User', backref='created_tryouts')
|
|
registrations = db.relationship('TryoutRegistration', backref='tryout', lazy='dynamic')
|
|
evaluations = db.relationship('Evaluation', backref='tryout', lazy='dynamic')
|
|
teams = db.relationship('Team', backref='tryout', lazy='dynamic')
|
|
target_org_team = db.relationship('OrgTeam', backref='tryouts', foreign_keys=[target_org_team_id])
|
|
|
|
|
|
class TryoutRegistration(db.Model):
|
|
__tablename__ = 'tryout_registrations'
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
tryout_id = db.Column(db.Integer, db.ForeignKey('tryouts.id'), nullable=False)
|
|
player_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
registered_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
status = db.Column(db.String(20), default='registered') # registered, attended, no_show
|
|
notes = db.Column(db.Text, nullable=True)
|
|
|
|
|
|
class Evaluation(db.Model):
|
|
__tablename__ = 'evaluations'
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
tryout_id = db.Column(db.Integer, db.ForeignKey('tryouts.id'), nullable=False)
|
|
player_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
evaluator_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
speed_score = db.Column(db.Integer, nullable=True)
|
|
agility_score = db.Column(db.Integer, nullable=True)
|
|
technique_score = db.Column(db.Integer, nullable=True)
|
|
teamwork_score = db.Column(db.Integer, nullable=True)
|
|
attitude_score = db.Column(db.Integer, nullable=True)
|
|
overall_score = db.Column(db.Float, nullable=True)
|
|
comments = db.Column(db.Text, nullable=True)
|
|
position_recommendation = db.Column(db.String(50), nullable=True)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
__table_args__ = (
|
|
db.UniqueConstraint('tryout_id', 'player_id', 'evaluator_id', name='unique_evaluation'),
|
|
)
|
|
|
|
|
|
class Team(db.Model):
|
|
"""Tryout-specific teams (e.g., Alpha, Bravo within a single tryout)."""
|
|
__tablename__ = 'teams'
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
tryout_id = db.Column(db.Integer, db.ForeignKey('tryouts.id'), nullable=False)
|
|
name = db.Column(db.String(100), nullable=False)
|
|
created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
|
|
creator = db.relationship('User', backref='created_teams')
|
|
members = db.relationship('TeamMember', backref='team', lazy='dynamic')
|
|
|
|
|
|
class TeamMember(db.Model):
|
|
__tablename__ = 'team_members'
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
team_id = db.Column(db.Integer, db.ForeignKey('teams.id'), nullable=False)
|
|
player_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
position = db.Column(db.String(50), nullable=True)
|
|
added_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
|
|
player = db.relationship('User', overlaps="player_ref,team_assignments") # Many-to-one, no dynamic loader
|