Architecture technique¶
État au moment de la lecture
Cette page décrit l’état réellement construit (v0.1 et extensions), pas seulement le plan initial – voir User stories & points ouverts pour le détail incrément par incrément et les décisions prises en cours de route.
Stack¶
Structure src layout, setuptools_scm pour le versioning,
PyInstaller pour le packaging.
Fichier local, pas de serveur distant, pas d’écriture concurrente à gérer (poste unique organisateur).
GUI organisateur : 6 écrans (Accueil, Compétitions, Compétiteurs, Saisie des scores, Classement, Aide).
Export Excel et PDF du classement – CSV via la stdlib.
Note
CI/CD : reprise telle quelle de la configuration FletchTime
(test.yml, docs.yml, build.yml ; dédup GitHub Pages
restreinte aux tags/Release/workflow_dispatch). Voir
User stories & points ouverts pour les deux bugs de déclencheur rencontrés et
corrigés sur la première vraie Release.
Vue d’ensemble des flux (v0.1 + v0.2)¶
flowchart TB
subgraph "Poste organisateur (construit, v0.1)"
GUI["gui/ (10 écrans)"]
SERVICES[services.py]
DB[(SQLite local)]
SCORING[scoring/]
GUI --> SERVICES
SERVICES --> SCORING
SERVICES --> DB
end
DB --> EXPORT["io/export/"]
EXPORT --> XLSX[Excel]
EXPORT --> PDF[PDF]
EXPORT --> CSV[CSV]
subgraph "Vue compétiteur (construite, v0.2)"
WEB["api/competiteur.py\n(http.server, thread séparé)"]
NAVIGATEUR["Navigateur du compétiteur\n(même wifi que le club)"]
NAVIGATEUR -->|GET/POST, token optionnel| WEB
end
DB -.connexion SQLite dédiée, lecture seule (mode=ro) pour la\nconsultation, écriture pour rattachement/messages.-> WEB
Vue compétiteur + token/rattachement construits (v0.2)
api/competiteur.py sert le classement live (lecture seule), la
demande/confirmation de rattachement, la confirmation d’un code
d’accès, et une messagerie organisateur → compétiteur (ciblée ou
diffusée, via un cookie de session signé HMAC). api/organisateur.py
reste un fichier vide – la proposition de score par le compétiteur
et sa validation restent prévues v0.3, voir User stories & points ouverts.
Arborescence réelle (v0.1)¶
fletchscore/
├── src/fletchscore/
│ ├── models/ # Club, Style, Competiteur, Competition,
│ │ # Epreuve, EpreuveTemplate, Bareme,
│ │ # Inscription, Score, Token,
│ │ # DemandeRattachement
│ ├── storage/
│ │ ├── db.py # schéma SQLite + CRUD, seuls fonctions
│ │ │ # publiques -- pas d'ORM
│ │ └── migrations/ # vide -- pas de vrai système de migration
│ │ # pour l'instant (voir dépannage utilisateur)
│ ├── referentiels/ # chargement/validation du référentiel styles
│ ├── scoring/
│ │ └── classement.py # classement par catégorie + classement
│ │ # global multi-épreuves, départage au X,
│ │ # podium -- isolé, testable sans DB ni GUI
│ ├── io/
│ │ ├── import_csv.py # import ET export CSV des référentiels
│ │ └── export/ # classement : par épreuve et global
│ │ ├── csv.py
│ │ ├── excel.py
│ │ └── pdf.py
│ ├── services.py # TOUS les cas d'usage organisateur --
│ │ # seule couche connue à la fois de gui/ et
│ │ # des tests ; ErreurMetier pour les messages
│ │ # lisibles par l'organisateur
│ ├── gui/
│ │ ├── app.py # fenêtre principale, navigation
│ │ ├── config.py # préférences GUI (thème), atomique
│ │ ├── robustesse.py # absence d'affichage, Ctrl+C/kill
│ │ ├── dialogue_fichier.py # sélecteur de chemin maison (pas
│ │ │ # tkinter.filedialog -- bug Pydroid)
│ │ └── ecran_*.py # un fichier par écran
│ ├── api/
│ │ ├── competiteur.py # serveur HTTP (v0.2 -- classement,
│ │ │ # rattachement, messagerie)
│ │ └── organisateur.py # squelette vide -- v0.3
│ └── __main__.py # argparse (-h, -V, -v, -d, --db, --http-port)
├── tests/ # ~250 tests -- voir :doc:`roadmap`
├── exemples/ # CSV d'exemple pour tests manuels
├── branding/ # logo (svg, png, ico)
├── docs/ # Sphinx (ce site) + sphinx-design + mermaid
└── .github/workflows/ # test.yml, docs.yml, build.yml
Tip
Pourquoi services.py et pas un module par écran ?
Toute la logique métier (créer une compétition, saisir un score,
calculer un classement…) vit dans services.py, jamais dans
gui/. Conséquence directe : chaque écran GUI reste un simple
assemblage de widgets, et l’intégralité des règles métier est
testable sans jamais avoir besoin d’un affichage – ce qui a permis
de développer et tester tout FletchScore dans un environnement sans
tkinter ni customtkinter installés (voir User stories & points ouverts).