transfer from private server/git server
This commit is contained in:
75
docs/08_partie5_retrodocumentation.md
Normal file
75
docs/08_partie5_retrodocumentation.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Partie 5 — Rétro-documentation
|
||||
|
||||
Cette rétro-documentation a été produite par analyse du code source réel de
|
||||
`gesthub-v2` (et non rédigée en amont du code), selon la démarche
|
||||
décrite au Bloc 4 — C1 : 1) analyse de l'arborescence, 2) lecture du code
|
||||
pour comprendre le rôle de chaque fonction, 3) reconstruction des flux à
|
||||
partir des appels de fonctions, 4) production du dictionnaire de données.
|
||||
|
||||
## RD-1 — Architecture en 5 couches
|
||||
|
||||
| Couche | Répertoire | Responsabilité |
|
||||
|---|---|---|
|
||||
| Présentation | `templates/`, `static/` | Rendu HTML (Jinja2), CSS, JS (SortableJS pour le drag & drop) |
|
||||
| Contrôleur | `routes/` | Orchestration HTTP : authentifie, délègue, répond en JSON/HTML |
|
||||
| Service | `services/` | Logique métier, validation, journalisation dans `audit_log` |
|
||||
| Accès données | `models/` | Repository Pattern, seules requêtes SQL de tout le projet |
|
||||
| Infrastructure | `db.py`, `config.py`, `docker-compose.yml` | Connexion MariaDB, configuration par variables d'environnement, orchestration des conteneurs |
|
||||
|
||||
## RD-2 — Flux de données détaillés
|
||||
|
||||
**Consultation des annonces :**
|
||||
`Navigateur → GET /api/annonces → routes/annonces.py (vérifie la session)
|
||||
→ services/annonce_service.list_annonces → models/annonce_model.fetch_all
|
||||
→ MariaDB (SELECT paramétré) → JSON → Navigateur`
|
||||
|
||||
**Upload de fichier :**
|
||||
`Navigateur (multipart/form-data) → routes/fichiers.py → services/
|
||||
fichier_service.handle_upload (8 étapes : présence → taille → MIME →
|
||||
extension → nom UUID → écriture disque → INSERT métadonnées → INSERT
|
||||
audit_log) → réponse JSON {id}`
|
||||
|
||||
**Téléchargement de fichier :**
|
||||
`Navigateur → GET /api/fichiers/{id}/download → vérification des droits
|
||||
(propriétaire ou admin) → audit_log (SUCCESS ou REFUSED) → send_file (si
|
||||
autorisé) ou 403`
|
||||
|
||||
## RD-3 — Flux d'authentification OIDC (annoté, 7 étapes)
|
||||
|
||||
| Étape | Description | Code |
|
||||
|---|---|---|
|
||||
| 1 | Détection de l'absence de session | `routes/dashboard.py::index` (`is_authenticated()`) |
|
||||
| 2 | Génération de l'URL d'autorisation + nonce anti-rejeu | `routes/auth.py::login` |
|
||||
| 3 | Redirection vers Keycloak | `keycloak.authorize_redirect(...)` |
|
||||
| 4 | Retour sur `/auth` avec le code d'autorisation | Géré automatiquement par Authlib |
|
||||
| 5 | Échange du code contre un token | `keycloak.authorize_access_token()` |
|
||||
| 6 | Vérification du token (signature + nonce) | `keycloak.parse_id_token(token, nonce=nonce)` |
|
||||
| 7 | Création de la session applicative | `session["user"] = userinfo` |
|
||||
|
||||
## RD-4 — Dictionnaire de données
|
||||
|
||||
| Champ | Table | Type SQL | Source | Description |
|
||||
|---|---|---|---|---|
|
||||
| `id` | toutes | `INT UNSIGNED AUTO_INCREMENT` | MariaDB | Clé primaire |
|
||||
| `titre` | annonces, evenements | `VARCHAR(150)` | Saisie admin | Titre affiché |
|
||||
| `epinglee` | annonces | `TINYINT(1)` | Saisie admin | Priorité d'affichage |
|
||||
| `auteur_sub` / `uploader_sub` / `createur_sub` | annonces, fichiers, evenements | `VARCHAR(64)` | Claim `sub` du token OIDC | Référence utilisateur (pas de doublon des données Keycloak) |
|
||||
| `nom_stocke` | fichiers | `VARCHAR(64)` | Généré (UUID4) | Nom réel sur disque, anti path-traversal |
|
||||
| `taille_octets` | fichiers | `BIGINT UNSIGNED` | Calculé à l'upload | Taille du fichier |
|
||||
| `action` / `statut` | audit_log | `VARCHAR(50)` / `VARCHAR(20)` | Généré par les services | Traçabilité (ex. `CREATE_ANNONCE` / `SUCCESS`) |
|
||||
|
||||
## RD-5 — Table de correspondance claims JWT ↔ champs applicatifs
|
||||
|
||||
| Claim JWT (Keycloak) | Champ applicatif | Utilisation |
|
||||
|---|---|---|
|
||||
| `sub` | `session["user"]["sub"]`, colonnes `*_sub` en base | Identifiant utilisateur unique et stable |
|
||||
| `preferred_username` | `session["user"]["preferred_username"]` | Affichage du nom d'utilisateur (template `index.html`) |
|
||||
| `email` | `session["user"]["email"]` | Non utilisé actuellement (disponible pour évolutions, ex. notifications) |
|
||||
| `groups` | `session["user"]["groups"]` | Contrôle d'accès (`/admin` → `is_admin()`) |
|
||||
| `iat`, `exp`, `iss` | Vérifiés automatiquement par Authlib | Validité temporelle et émetteur du token |
|
||||
|
||||
En spécialité Robotique & Systèmes Embarqués, cette même logique de table de
|
||||
correspondance s'applique au mapping entre formats de données capteurs
|
||||
(ex. trame UART) et structures Python applicatives — la compétence
|
||||
transférée est la même : documenter précisément la correspondance entre un
|
||||
format source externe et le modèle interne de l'application.
|
||||
Reference in New Issue
Block a user