3 Commits
Author SHA1 Message Date
williamandClaude Sonnet 5 ccf836f2c5 Lot 4 modernisation JS (SonarLint) + restauration CI sonarqube non-bloquante
Build and deploy / test-python (push) Successful in 11m18s
Build and deploy / test-js (push) Successful in 1m16s
Build and deploy / lint-python (push) Successful in 4m24s
Build and deploy / lint-js (push) Successful in 2m51s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Successful in 5m30s
Corrige les findings SonarQube (via SonarLint IDE, fichier par fichier)
sur ~24 fichiers static/js/ : parseFloat/parseInt -> Number.*,
.replace(/x/g,y) -> .replaceAll, .indexOf() -> .includes()/.startsWith(),
getAttribute/setAttribute -> .dataset, tableaux -> Set, x && x.y -> x?.y
(verifie site par site), extraction de template litteraux imbriques,
ternaires imbriquees, refactors de complexite cognitive (S3776) via
tables de dispatch, Object.hasOwn, .at(), et deduplication de fonctions
identiques (S4144). Deux exceptions S2486 documentees/corrigees
(filter-repeater-rows.js) et un cas S2703 de partage inter-scripts
complete (_collisionWizard, trigger-editor.js <-> collision-rules-editor.js).
Details complets dans CODE_QUALITY.md section 5.

Restaure aussi le job CI "sonarqube" (non-bloquant) dans
.gitea/workflows/deploy.yml maintenant que l'instance prod est
operationnelle.

Suites vertes : 276/276 JS (node --test), 591/591 Python (pytest).

SKIP=djlint sur ce commit : hook djlint bloquant sur le backlog H021
(styles inline, 49 occurrences/6 templates) deja documente comme dette
assumee non traitee dans CODE_QUALITY.md section 6, aucun rapport avec
ce commit (aucun template touche ici) - valide explicitement avec
l'utilisateur avant de contourner ce hook.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-18 16:38:29 +02:00
williamandClaude Sonnet 5 c57420c8c9 Phase 3 : hardening qualite de code - typage strict, securite, dead code, a11y
Config strictement stricte partout (ruff, mypy --strict, bandit, vulture,
import-linter, eslint, stylelint), aucune regle desactivee "pour ne pas
casser le build" - l'existant a ete corrige pour la satisfaire plutot que
l'inverse. Hooks pre-commit locaux (language: system) bloquants.

- Typage mypy --strict propage a tout le moteur (db, screens, auth, core,
  ai, routes, puis publish/scripts/tests/app.py/build_css.py).
- Securite : fuite de handle fichier Windows corrigee dans l'export SCORM
  (routes/publish/export_scorm.py), CSRF/RNG non-crypto/xAPI documentes
  (# nosec, # NOSONAR justifies), nouveau db.json_for_script() (echappe
  "</script>" dans le JSON embarque en <script>, 25 sites).
- Architecture : imports circulaires/F811 nettoyes, contrats
  import-linter respectes, code mort retire (vulture).
- Accessibilite : 69 champs de formulaire sans label correctement
  associe corriges (for/id ou aria-label) sur 11 templates.
- ESLint/Stylelint : lot mecanique JS/CSS, regles ajustees puis
  appliquees (aucune desactivee sans verification individuelle).
- Tests : isolation du compte admin partage (nettoyage ponctuel +
  fixture de teardown automatique en filet de securite), suite complete
  verte (591 tests Python, 241 tests JS).
- SonarQube Community Build self-heberge (Docker + PostgreSQL) : rapport
  complet analyse point par point, faux positifs documentes.
- .gitattributes ajoute (LF force) : core.autocrlf=true sur cette machine
  faisait echouer ESLint (linebreak-style) via un bug connu de git
  (checkout "en place" qui ignore l'eol force sur un fichier deja
  present sur disque - contourne en supprimant puis recreant chaque
  fichier suivi).

djLint (H021, styles inline) volontairement saute pour ce commit -
backlog assume, deja documente, traite dans un lot separe.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 16:06:15 +02:00
williamandClaude Sonnet 5 9e076f8cf9 Refonte : vrai widget "Personnage" visuel (remplace l'UI de la Phase 7)
Build and deploy / test-python (push) Successful in 1m26s
Build and deploy / test-js (push) Successful in 6s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
L'utilisateur a testé la Phase 7 (sprites pilotés via un menu déroulant
+ zone de texte dans la logique de flow) et l'a rejetée à raison : ce
n'est pas comme ça qu'un moteur de jeu (Phaser, Unity) gère un
personnage. Cette refonte remplace tout le flux d'AUTEURING par un vrai
widget visuel — le moteur d'exécution de la Phase 7 (runSpriteAnimation,
activeSpriteAnimations, orientation, kind="sprite" de la Timeline) reste
inchangé.

Nouveau widget "personnage" (screens/widgets/registry.py) :
- Rendu serveur dédié (special_render, screens/rendering/render_personnage.py)
  qui affiche la pose "idle" dès le HTML généré — jamais une image
  cassée à configurer après coup.
- Toutes ses données (source Forge ou sprites propres au créateur, quel
  personnage/quelles animations) vivent dans une seule clé JSON
  _personnage_data (screens/rendering/personnage_data.py), sans aucune
  migration de schéma (même patron que c_clause_list).
- Nouvelle échappatoire "custom_panel", symétrique à "special_render" mais
  pour le panneau de propriétés : ce widget affiche une galerie/un import
  de sprites sur-mesure plutôt que les contrôles génériques.

Galerie visuelle de personnages Forge (VRAIES miniatures, pas un emoji) :
- Panneau gauche "🎭 Personnages" : pose un personnage déjà configuré,
  animé immédiatement.
- Panneau droit (propriétés) : change le personnage Forge de l'élément
  sélectionné, ou importe les animations d'un sprite personnalisé.
- static/js/screen_edit/personnage-preview.js : lance l'aperçu animé de
  CHAQUE personnage du canevas dès le chargement de la page et après
  toute sauvegarde — le cœur de la demande ("je dois voir ça bouger").

Sélecteur d'animation à miniatures (nœud de flow "Jouer une animation" et
clip de Timeline "sprite") : remplace le menu déroulant/la zone de texte
par une grille de vraies miniatures, scopée aux SEULES animations du
personnage réellement ciblé (ELEMENT_ANIMATIONS_MAP, résolu côté serveur
à partir des propriétés de cet élément précis) — jamais un catalogue
global. Le format stocké sur le nœud/le clip ({frames, fps, loop}) est
inchangé, seule l'UI d'édition change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 20:26:39 +02:00