From 90ac3eb804e81116c2571b8f8227c61cf61de197 Mon Sep 17 00:00:00 2001 From: cedrick2711 Date: Tue, 28 Jul 2026 18:41:05 -0400 Subject: [PATCH] Uml et fonctionnel dans un document .html --- docs/architecture.html | 747 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 747 insertions(+) create mode 100644 docs/architecture.html diff --git a/docs/architecture.html b/docs/architecture.html new file mode 100644 index 0000000..822225b --- /dev/null +++ b/docs/architecture.html @@ -0,0 +1,747 @@ + + + + + + Team Tryouts β€” Architecture Documentation + + + + + +
+

πŸ† Team Tryouts β€” Architecture Documentation

+

UML Class Diagram & Functional System Architecture

+ +
+ +
+ + +
+

πŸ“Š Project Statistics

+
+
+
19
+
SQLAlchemy Model Classes
+
+
+
8
+
Route Blueprints
+
+
+
4
+
Flask Extensions
+
+
+
2
+
Association Tables (M2M)
+
+
+
50+
+
Route Endpoints
+
+
+
8
+
Utility Modules
+
+
+
+ + +
+

πŸ“ UML Class Diagram β€” All 19 Model Classes

+
+ +
+classDiagram + class User { + +int id + +str username + +str password_hash + +str role + +str full_name + +str email + +str phone + +bool is_active_account + +datetime created_at + +int failed_login_attempts + +datetime locked_until + +str games + +str discord_username + +str discord_user_id + +str league_os_profile + +get_games_list() + +has_role() + +can_evaluate() + +can_manage_users() + +can_manage_tryouts() + +can_manage_teams() + +can_schedule_matches() + +can_manage_this_tryout() + +can_manage_this_org_team() + +get_gamertags() + +get_org_teams() + } + class UserGamertag { + +int id + +int user_id + +str game + +str gamertag + +str platform + +get_trn_url() + } + class OrgTeam { + +int id + +str name + +int created_by + +datetime created_at + +int coach_id + +int manager_id + +get_coaches() + +get_managers() + +players() + +get_players_with_status() + } + class TeamPlayer { + +int id + +int player_id + +int org_team_id + +str status + +str position + +datetime added_at + } + class Tryout { + +int id + +str title + +str description + +str game + +date date + +str location + +str status + +int max_players + +int created_by + +int target_org_team_id + +int manager_id + +int coach_id + +datetime created_at + } + class TryoutRegistration { + +int id + +int tryout_id + +int player_id + +datetime registered_at + +str status + +str notes + } + class Evaluation { + +int id + +int tryout_id + +int player_id + +int evaluator_id + +int mecanics_score + +int cohesion_score + +int communication_score + +int gamesense_score + +int versatility_score + +int discipline_score + +int analysis_score + +int sport_ethics_score + +int mental_score + +float overall_score + +str comments + +str position_recommendation + +datetime created_at + +datetime updated_at + } + class Team { + +int id + +int tryout_id + +str name + +int created_by + +datetime created_at + } + class TeamMember { + +int id + +int team_id + +int player_id + +str position + +datetime added_at + } + class Match { + +int id + +int tryout_id + +str title + +str description + +date date + +time start_time + +time end_time + +str location + +str status + +str match_type + +int created_by + +datetime created_at + +int team1_id + +int team2_id + +get_participating_players() + } + class PlayerDisponibility { + +int id + +int player_id + +int day_of_week + +time start_time + +time end_time + +datetime created_at + +datetime updated_at + } + class MatchParticipant { + +int id + +int match_id + +int player_id + +int team_side + +str position + +bool attendance_confirmed + +datetime added_at + } + class Contract { + +int id + +int player_id + +int team_id + +int uploaded_by_id + +str original_filename + +str stored_filename + +str file_path + +str signed_filename + +str signed_file_path + +str status + +str notes + +datetime uploaded_at + +datetime signed_at + +can_view() + +can_upload_signed() + } + class CoachAvailability { + +int id + +int coach_id + +int day_of_week + +time start_time + +time end_time + +datetime created_at + +datetime updated_at + } + class TeamNote { + +int id + +int org_team_id + +int coach_id + +str content + +datetime created_at + +datetime updated_at + } + class PersonalNote { + +int id + +int player_id + +int coach_id + +str content + +datetime created_at + +datetime updated_at + +int match_id + +int team_id + +int tryout_id + } + class OneOnOneRequest { + +int id + +int player_id + +int coach_id + +int org_team_id + +date date + +time start_time + +time end_time + +str points + +str status + +datetime created_at + +datetime responded_at + +bigint discord_message_id + +str coach_rejection_message + } + class TeamMatch { + +int id + +int org_team_id + +str title + +str description + +str opponent + +date date + +time start_time + +time end_time + +str location + +str status + +int created_by + +datetime created_at + +get_confirmed_count() + } + class TeamMatchParticipant { + +int id + +int team_match_id + +int player_id + +bool is_confirmed + +datetime added_at + } + class load_user { + +load_user(user_id) + } + + User "1" --> "*" UserGamertag : gamertags + User "1" --> "*" Tryout : created_by + User "1" --> "*" Tryout : managed_tryouts + User "1" --> "*" Tryout : coached_tryouts + User "1" --> "*" Evaluation : evaluations_given + User "1" --> "*" Evaluation : evaluations_received + User "1" --> "*" TryoutRegistration : tryout_registrations + User "1" --> "*" TeamMember : team_assignments + User "1" --> "*" TeamPlayer : team_placements + User "1" --> "*" Match : created_matches + User "1" --> "*" TeamMatch : created_team_matches + User "1" --> "*" PlayerDisponibility : disponibilities + User "1" --> "*" CoachAvailability : coach_availabilities + User "1" --> "*" Team : created_teams + User "1" --> "*" Contract : contracts + User "1" --> "*" PersonalNote : personal_notes + User "1" --> "*" OneOnOneRequest : one_on_one_requests + + OrgTeam "1" --> "*" TeamPlayer : team_players + OrgTeam "1" --> "*" Tryout : tryouts + OrgTeam "1" --> "*" TeamNote : team_notes + OrgTeam "1" --> "*" TeamMatch : team_matches + OrgTeam "1" --> "*" OneOnOneRequest : requests + OrgTeam "1" --> "*" Contract : contracts + + Tryout "1" --> "*" TryoutRegistration : registrations + Tryout "1" --> "*" Evaluation : evaluations + Tryout "1" --> "*" Team : teams + Tryout "1" --> "*" Match : matches + Tryout "1" --> "*" PersonalNote : notes + + Team "1" --> "*" TeamMember : members + Team "1" --> "*" Match : matches_as_team1 + Team "1" --> "*" Match : matches_as_team2 + Match "1" --> "*" MatchParticipant : participants + Match "1" --> "*" PersonalNote : notes + + TeamMatch "1" --> "*" TeamMatchParticipant : participants + + User .. load_user : loads +
+ +
+
+ + +
+

πŸ”€ Functional Architecture β€” Request Flow & Component Graph

+
+ +
+graph TD + subgraph CLIENT["🌐 Client Layer"] + BROWSER["Browser / User"] + DISCORD_APP["Discord App"] + MONITOR["Monitoring / LB"] + end + + subgraph PROXY["πŸ”„ Reverse Proxy"] + NGINX["Nginx
(TLS termination,
static files,
rate limiting)"] + end + + subgraph APP["🐍 Flask Application (create_app)"] + direction TB + + subgraph INGRESS["Incoming"] + BEFORE_REQ["@before_request
force_https()"] + CSRF_CHECK["CSRF Validate"] + LIMITER_CHECK["Rate Limiter
200/day Β· 50/hr"] + LOGIN_CHECK["@login_required"] + end + + subgraph BLUEPRINTS["πŸ“¦ Route Blueprints (8 total)"] + AUTH_BP["auth_bp
━━━━━━━
⁕ /auth/login
⁕ /auth/register
⁕ /auth/logout
⁕ /auth/profile
⁕ /auth/change-password
⁕ /auth/delete-account"] + MAIN_BP["main_bp
━━━━━━━
⁕ /
⁕ /dashboard
⁕ /privacy
⁕ /terms"] + TRYOUTS_BP["tryouts_bp
━━━━━━━
⁕ /tryouts/
⁕ /tryouts/create
⁕ /tryouts/{id}
⁕ /tryouts/{id}/register
⁕ /tryouts/{id}/edit
⁕ /tryouts/{id}/delete"] + TEAMS_BP["teams_bp
━━━━━━━
⁕ /teams/
⁕ /teams/create
⁕ /teams/{id}
⁕ /teams/{id}/edit
⁕ /teams/{id}/delete
⁕ /teams/{id}/add-player"] + MATCHES_BP["matches_bp
━━━━━━━
⁕ /matches/
⁕ /matches/create
⁕ /matches/{id}
⁕ /matches/{id}/edit"] + TEAM_MATCHES_BP["team_matches_bp
━━━━━━━
⁕ /team-matches/
⁕ /team-matches/create
⁕ /team-matches/{id}
⁕ /team-matches/{id}/edit
⁕ /team-matches/{id}/delete"] + USERS_BP["users_bp
━━━━━━━
⁕ /users/
⁕ /users/create
⁕ /users/{id}
⁕ /users/{id}/delete
⁕ /users/disponibilities/
⁕ /users/coach-availability/
⁕ /users/api/gamertags"] + EVALS_BP["evaluations_bp
━━━━━━━
⁕ /evaluations/
⁕ /evaluations/create
⁕ /evaluations/{id}
⁕ /evaluations/{id}/edit
⁕ /evaluations/{id}/delete"] + end + + subgraph EGRESS["Outgoing"] + AFTER_REQ["@after_request
add_security_headers()"] + ERROR_HANDLERS["Error Handlers
400 Β· 401 Β· 403 Β· 404
429 Β· 500 Β· HTTPException"] + HEALTH["GET /health"] + end + end + + subgraph EXTENSIONS["πŸ”Œ Flask Extensions"] + DB_EXT["SQLAlchemy
(db)"] + LOGIN_EXT["Flask-Login
(login_manager)"] + CSRF_EXT["CSRFProtect
(csrf)"] + LIMITER_EXT["Flask-Limiter
(limiter)"] + end + + subgraph MODELS["πŸ—„οΈ SQLAlchemy Models (models.py)"] + direction LR + USER_M["User"] + TRYOUT_M["Tryout"] + EVAL_M["Evaluation"] + ORGTEAM_M["OrgTeam"] + TEAM_M["Team"] + MATCH_M["Match"] + TEAMMATCH_M["TeamMatch"] + OTHERS_M["...15 more classes"] + end + + subgraph DB["πŸ’Ύ Database"] + SQLITE["SQLite / PostgreSQL
(SQLALCHEMY_DATABASE_URI)"] + end + + subgraph UTILS["πŸ› οΈ Utility Modules"] + VALIDATORS["validators.py
Password/username validation"] + LOGGING["logging_config.py
Structured logging"] + DISCORD_BOT["discord_bot.py
Discord notifications
+ reaction handling"] + SECURITY["security_scan.py
Security audit tool"] + SEED["seed.py
Database seeding"] + BACKUP["backup.py
Database backup"] + MIGRATE["migrate_usernames.py
Username migration"] + end + + subgraph TEMPLATES["πŸ–ΌοΈ Jinja2 Templates"] + PAGES["templates/pages/
(~30 HTML pages)"] + LAYOUTS["templates/layouts/
(base, nav)"] + ERRORS_TPL["templates/errors/
(400, 401, 403, 404, 429, 500)"] + end + + subgraph STATIC["πŸ“ Static Assets"] + CSS_F["static/css/"] + JS_F["static/js/"] + end + + subgraph EXTERNAL["🌍 External APIs"] + TRN_API["TRN / Tracker.gg
(gamertag profiles)"] + DISCORD_API["Discord API
(bot notifications)"] + end + + %% ========== FLOW ========== + BROWSER --> NGINX + NGINX --> BEFORE_REQ + BEFORE_REQ --> CSRF_CHECK + CSRF_CHECK --> LIMITER_CHECK + LIMITER_CHECK --> LOGIN_CHECK + LOGIN_CHECK --> BLUEPRINTS + BLUEPRINTS --> AFTER_REQ + AFTER_REQ --> BROWSER + + %% Blueprint to models + AUTH_BP -.-> USER_M + TRYOUTS_BP -.-> TRYOUT_M + EVALS_BP -.-> EVAL_M + TEAMS_BP -.-> ORGTEAM_M + MATCHES_BP -.-> MATCH_M + TEAM_MATCHES_BP -.-> TEAMMATCH_M + USERS_BP -.-> USER_M + + %% Models to DB + MODELS --> DB + + %% Extensions + DB_EXT --> MODELS + LOGIN_EXT --> USER_M + CSRF_EXT --> BLUEPRINTS + LIMITER_EXT --> BLUEPRINTS + + %% Utilities + VALIDATORS -.-> AUTH_BP + VALIDATORS -.-> USERS_BP + LOGGING -.-> APP + DISCORD_BOT --> DISCORD_API + DISCORD_BOT -.-> MATCHES_BP + DISCORD_BOT -.-> TEAM_MATCHES_BP + DISCORD_BOT -.-> USERS_BP + SEED -.-> DB + BACKUP -.-> DB + + %% Templates & Static + BLUEPRINTS --> TEMPLATES + TEMPLATES --> STATIC + + %% External + USER_M -.-> TRN_API + MONITOR --> HEALTH + + %% Discord + DISCORD_APP --> DISCORD_BOT +
+ +
+
+ + +
+

πŸ—ΊοΈ Legend

+
+
+ + SQLAlchemy Models β€” Database entity classes +
+
+ + Route Blueprints β€” Flask route groups +
+
+ + Flask Extensions β€” SQLAlchemy, Login, CSRF, Limiter +
+
+ + Utility Modules β€” Logging, validators, seeding, backups +
+
+ + External APIs β€” Discord, TRN/Tracker.gg +
+
+ + Middleware β€” Security headers, HTTPS redirect, error handlers +
+
+ ─── Solid arrow + = HTTP request flow +
+
+ - - - Dashed arrow + = Data access / logical dependency +
+
+
+ +
+ + + + + + + \ No newline at end of file