Commit Graph
151 Commits
Author SHA1 Message Date
Johan LEROYandGitHub 5394257855 Merge pull request #90 from ineszang/feat/password-policy-forgot-password
feat(auth): politique de complexité du mot de passe et flux de réinitialisation
2026-09-17 15:34:26 +02:00
Johan LEROY c741ffc827 fix(auth): corrige la CI cassee par le nouvel endpoint de validation
Backend / Lint, typage et tests (push) Successful in 1m19s
/auth/reset-password/validate manquait a la liste explicite des routes
publiques (test_route_protection) et n'avait pas le modele de reponse
422 declare (openapi.json desynchronise du contrat genere).
2026-09-17 15:31:14 +02:00
Johan LEROY d7f775f9f7 feat(auth): verifie le lien de reset des le chargement, sans le consommer
Ajoute GET /auth/reset-password/validate (lecture seule, sans rate
limit : le jeton est un secret de 256 bits non brute-forcable) pour que
la page reset-password redirige immediatement vers /login si le lien
est invalide ou expire, plutot que d'attendre la soumission du
formulaire. La verification a la soumission (confirm_password_reset)
reste la seule source de verite atomique.
2026-09-17 15:28:50 +02:00
Johan LEROY e381e0de09 feat(frontend): checklist de complexite du mot de passe sur reset-password
Remplace l'indice statique sous le champ nouveau mot de passe par une
checklist qui coche chaque regle (longueur, majuscule, minuscule,
chiffre, caractere special) au fur et a mesure de la saisie. Les regles
individuelles (PASSWORD_REQUIREMENTS) sont exposees depuis le meme
validateur que PASSWORD_PATTERN pour rester la seule source de verite.
2026-09-17 14:57:05 +02:00
Johan LEROY 7674955637 fix(frontend): un lien de reset absent ou expire renvoie vers login avec un message standard
Avant, un token absent affichait un message inline sur /reset-password, et
un token invalide/expire ne se voyait qu'apres soumission du formulaire.
Les deux cas redirigent maintenant vers /login avec le motif
"lien-expire", qui y affiche le message standard "Ce lien de
reinitialisation est invalide ou a expire. Connectez-vous ou
redemandez-en un."
2026-09-17 14:49:46 +02:00
Johan LEROY 063092f2c7 fix(frontend): le rafraichissement de session au demarrage ne doit pas ecraser un lien de reset
Le refresh de session lance par provideAppInitializer echoue silencieusement
sans cookie valide, mais l'intercepteur forcait quand meme un
router.navigate(['/login']) sur le 401 resultant, ecrasant la navigation
vers /reset-password?token=... venue de l'email. L'intercepteur ne
redirige plus quand on est deja sur une route invitee (login,
forgot-password, reset-password).
2026-09-17 14:40:53 +02:00
Johan LEROY 921da48eb1 fix(auth): corrige 4 failles de la revue de securite sur la PR #90
Anti-enumeration cassee sur /auth/forgot-password : l'envoi SMTP etait
synchrone dans le chemin de reponse, donc un email existant prenait plus
de temps qu'un email inconnu (et pouvait renvoyer 500 si le relais SMTP
echouait, contre 202 sinon). L'envoi part desormais en BackgroundTasks,
apres que la reponse 202 a ete envoyee au client, avec un try/except qui
logue plutot que de laisser une exception SMTP remonter.

confirm_password_reset() ne revalidait pas is_active/kind du compte avant
de changer le mot de passe : un compte desactive dans les 15 minutes
suivant l'emission du lien pouvait quand meme voir son mot de passe
change et son must_change_password efface.

Les plages [A-ZA-Y]/[a-za-y] de la regle de complexite incluaient par
erreur x et / (U+00D7, U+00F7), donc un mot de passe sans aucune
majuscule ou minuscule pouvait passer la validation.

Le validateur frontend (JS, \w ASCII) et le validateur backend (Python,
\w Unicode) divergeaient sur les caracteres accentues : un mot de passe
comme "Securite1" passait cote front puis se faisait rejeter en 422 cote
back. Les deux cotes utilisent maintenant le meme jeu explicite de
caracteres speciaux (SPECIAL_CHARACTERS, partage aussi avec cli.py).
2026-09-17 14:35:14 +02:00
Johan LEROYandGitHub ec1c05ad54 Merge pull request #102 from ineszang/feat/ml
feat(ml): initialise le pipeline d'entrainement LightGBM (ADR 0005)
2026-09-17 14:29:10 +02:00
Dorian 4f69199734 feat(ml): initialise le pipeline d'entrainement LightGBM (ADR 0005)
ML / Lint, typage et tests (push) Successful in 2m2s
2026-09-17 14:12:26 +02:00
ValentinDeFariaandGitHub 016f226fdb Merge pull request #98 from ineszang/feat/scan-dépendances-dependabot
feat: ajout dependances dependabot
2026-09-17 13:43:25 +02:00
ValentinDeFariaandGitHub 88f4f9a601 chore(ci): ajoute la surveillance docker du frontend a dependabot 2026-09-17 13:42:02 +02:00
Johan LEROY 916b5d246a Merge remote-tracking branch 'origin/dev' into feat/password-policy-forgot-password
# Conflicts:
#	apps/backend/app/api/deps.py
#	apps/backend/pyproject.toml
2026-09-17 12:18:48 +02:00
Johan LEROYandGitHub 7913518c4b Merge pull request #94 from ineszang/feat/get-readings
feat(backend): expose GET /api/v1/readings avec fenetre bornee et pag…
2026-09-17 12:12:55 +02:00
Valentin 2ad7692f1c Ajoute la configuration Dependabot (npm, uv, github-actions, docker) 2026-09-17 12:12:48 +02:00
Dorian a158d6f84c Merge remote-tracking branch 'origin/dev' into feat/get-readings 2026-09-17 11:58:27 +02:00
ineszangandGitHub 7dfd7a7e74 Merge pull request #88 from ineszang/feat/data-import
Ajout du pipeline d'import des données historiques
2026-09-17 11:57:58 +02:00
Dorian 8d28113f03 feat(backend): expose GET /api/v1/readings avec fenetre bornee et pagination 2026-09-17 11:50:20 +02:00
Johan LEROY 62932e57c3 style(backend): formatage ruff de cli.py 2026-09-17 11:42:44 +02:00
Johan LEROY 9161b74874 feat(auth): politique de complexite du mot de passe et flux de reinitialisation
Remplace la regle de longueur seule (12 caracteres) par une exigence de
composition (8 caracteres minimum, majuscule, minuscule, chiffre, caractere
special), non documentee dans les exigences officielles du projet, par une
regle explicite partagee entre le backend (validateur Pydantic) et le
frontend.

Ajoute un flux "mot de passe oublie" en libre-service, absent jusqu'ici :
jeton a usage unique hache en base (meme principe que les refresh tokens),
expirant a 15 minutes, envoye par email via un service SMTP (aiosmtplib,
Mailpit en dev), avec limitation de debit dediee et reponse generique pour
eviter l'enumeration des comptes.

Closes #87
2026-09-17 10:53:58 +02:00
Meryemel-gham 6798d35572 fix(data): corrige le typage de l'import historique
Backend / Lint, typage et tests (push) Successful in 1m16s
2026-09-17 10:41:18 +02:00
Meryemel-gham f03dce5fe3 style(data): applique le formatage Ruff 2026-09-17 10:06:54 +02:00
Meryemel-gham 74ac1b4577 docs(data): documente le pipeline d'import historique 2026-09-17 09:55:27 +02:00
Meryemel-gham ebb72fb399 test(data): couvre l'import historique 2026-09-17 09:34:30 +02:00
Meryemel-gham b2d52823ba fix(data): aligne l'import historique avec les contraintes BDD 2026-09-17 09:34:30 +02:00
Meryemel-gham fcbfcc8eb2 feat(data): ajoute l'import historique des donnees 2026-09-17 09:34:30 +02:00
Johan LEROYandGitHub 3692d486c6 Merge pull request #83 from ineszang/feat/endpoint-sensors-status
feat(backend): expose GET /api/v1/sensors/status
2026-09-17 09:16:24 +02:00
ValentinDeFariaandGitHub 24bf8bf4b9 Update apps/backend/tests/services/test_sensor.py
Backend / Lint, typage et tests (push) Successful in 1m11s
2026-09-17 09:10:04 +02:00
Johan LEROYandGitHub 9f465538bf Merge pull request #85 from ineszang/feat/auth-front
feat(frontend): authentification frontend
2026-09-17 09:09:59 +02:00
Johan LEROY 515a92b395 fix(frontend): isole les fichiers de tests vitest pour eviter la pollution de mocks
Le test site-load-chart.spec.ts echouait de facon intermittente en CI : sans
isolation, vitest partage le registre de modules entre fichiers de spec, donc
le mock chart.js d'un fichier pouvait ecraser celui d'un autre selon l'ordre
d'execution.
2026-09-17 09:02:53 +02:00
ValentinDeFariaandGitHub 0174272bdd Update dashboard.html 2026-09-16 17:00:52 +02:00
ineszangandGitHub c740b61b24 Merge pull request #80 from ineszang/feat/pipeline-ci
Feat/pipeline ci
2026-09-16 16:41:55 +02:00
Valentin 5669cd63ec feat(frontend): authentification frontend
ajout de la page login, changement de mot de passe forcé, rafraîchissement de session en mémoire, intercepteur, déconnexion, bouton logout sur le dashboard
2026-09-16 16:07:28 +02:00
ineszang44 06cb60463c fix(frontend): droit d'accès au fichier de config de nginx, réduction de code smells 2026-09-16 15:12:04 +02:00
ineszang44 1c6b6105bd chore(frontend): ajout de la configuration nginx 2026-09-16 14:54:12 +02:00
Johan LEROY 77440281f8 feat(backend): expose GET /api/v1/sensors/status pour l'issue #32
Dérive l'état de santé de 5 capteurs par site et un statut overall depuis
la dernière lecture (data_quality, null_reasons, nullité des colonnes),
sur le gabarit d'agrégation de StatsService. Route réservée au rôle admin.
2026-09-16 14:53:54 +02:00
Johan LEROYandGitHub 63ee79cf32 Merge pull request #81 from ineszang/feat/endpoint-alertes-predictives
feat(backend): expose GET /api/v1/alerts
2026-09-16 14:44:27 +02:00
Johan LEROY 76fa90dfcb test(backend): exerce AlertSeverity comme enum plutot qu'une chaine dans les tests alerts
Backend / Lint, typage et tests (push) Successful in 1m8s
Le filtre severity passait par une chaine brute dans les tests, sans jamais
exercer le trajet reel AlertSeverity (enum) -> SQLAlchemy -> PostgreSQL.
2026-09-16 14:43:27 +02:00
ineszang44 6ecec1afef chore(frontend): ajout du dockerignore et du dockerfile 2026-09-16 14:40:55 +02:00
Johan LEROY e13096c62a Fusionne dev dans feat/endpoint-alertes-predictives
Resout les conflits additifs entre les routes alerts, recommendations
et stats mergees sur dev (PR #79, PR #82) pendant le developpement de
cette branche : deps.py, router.py, openapi.py, openapi.json,
test_openapi.py et 20-backend.md conservent desormais les trois routes.
2026-09-16 14:25:49 +02:00
ineszang44 970a4a50b8 fix(frontend): suppression de dépendance dans le service frontend 2026-09-16 14:22:50 +02:00
Johan LEROYandGitHub 3fb907d6f6 Merge pull request #82 from ineszang/feat/endpoint-recommandations
feat(backend): ajoute GET /recommendations et GET /recommendations/{r…
2026-09-16 14:21:08 +02:00
Dorian PESCE c7490d01b3 Merge remote-tracking branch 'origin/dev' into feat/endpoint-recommandations 2026-09-16 14:03:24 +02:00
Johan LEROYandGitHub 523b623dc1 Merge pull request #79 from ineszang/feat/stats-summary
feat(backend): expose GET /api/v1/stats/summary
2026-09-16 13:37:47 +02:00
Johan LEROY 61e031fc16 Fusionne dev dans feat/stats-summary
Resout les conflits de deps.py, router.py, repositories/site.py et
test_site.py entre l'ajout de stats et le merge de sites/openapi-contrat
sur dev. Generalise ROUTES_A_ROLE dans test_openapi.py et documente la
checklist d'ajout d'une route metier, absentes de dev au moment du fork.
2026-09-16 13:37:03 +02:00
Dorian PESCE 781644b28e feat(backend): ajoute GET /recommendations et GET /recommendations/{recommendation_id} 2026-09-16 13:30:51 +02:00
Johan LEROY 1654e4dd81 docs(backend): documente la checklist d'ajout d'une route metier
La generalisation de ROUTES_A_ROLE (commit precedent) avait deja ete
approuvee sur feat/openapi-contrat mais poussee apres la fermeture de
la PR #76 : elle n'a donc jamais atteint dev, et sa documentation non
plus. Complete ce qui manquait pour que le passage a l'echelle du
contrat OpenAPI soit reellement utilisable par la prochaine route.
2026-09-16 13:27:41 +02:00
Johan LEROY e50921c907 feat(backend): expose GET /api/v1/alerts
Consultation des alertes de consommation, filtrable par site_id et
severity a l'identique du contrat GET /alerts de l'API Mock. Reprend
le gabarit endpoints -> services -> repositories -> models pose par
sites, sur la table alert deja creee par la revision Alembic
e6d2026091501.

Generalise aussi le garde-fou OpenAPI du 403 (ROUTES_A_ROLE) au-dela
du seul tag users, pour que l'ajout d'alerts a la liste des routes
protegees par role soit reellement verifie.

Closes #59
2026-09-16 13:06:37 +02:00
PhyriosandGitHub 56f7211f0b Merge pull request #77 from ineszang/feat/frontend-make-dev
feat(build): branche le frontend sur make dev
2026-09-16 12:34:41 +02:00
ineszang44 730adb69b1 chore(frontend): faux positifs cwe 2026-09-16 12:32:28 +02:00
ineszang44 f43c9f76a0 test(frontend): workflow 2026-09-16 12:29:54 +02:00