From 580da72effe88610b32e58cc72ba59373e795a8a Mon Sep 17 00:00:00 2001 From: Johan LEROY Date: Wed, 16 Sep 2026 09:23:15 +0200 Subject: [PATCH] docs(architecture): acte le tableau de bord dans les vues frontend 30-frontend.md decrivait encore un ng new intact : routes vides, provideHttpClient absent, app.html par defaut, aucune bibliotheque de graphiques. Les sections Arborescence et Flux HTTP passent de Cible a realisees, et le diagramme de sequence montre ou l'intercepteur se place. La section Securite affirmait que l'authentification n'existe pas cote API : elle existe depuis la PR #70, c'est cote interface qu'il n'y a rien. Ajout verifie sur le poste : l'Angular CLI refuse de demarrer en dessous de Node 22.22.3, 24.15.0 ou 26.0.0. --- README.md | 7 +-- docs/architecture/00-vue-ensemble.md | 7 +-- docs/architecture/30-frontend.md | 65 ++++++++++++++++++---------- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 7a8147f..75a1ab6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Ce que la documentation apporte à chacun : [docs/architecture/00-vue-ensemble.m | Domaine | Technologie | Emplacement | Etat | |------------|-------------------------------------|---------------------|---------------| | Backend | FastAPI, Python 3.14 | `apps/backend` | Initialise | -| Frontend | Angular 22, Node 24 LTS | `apps/frontend` | Squelette | +| Frontend | Angular 22, Node 24 LTS | `apps/frontend` | Tableau de bord | | Base | PostgreSQL 17 + TimescaleDB | `db` | Initialise | | ETL | Apache Airflow | `etl/airflow` | A initialiser | | Infra | Terraform (k3s single-node) | `infra/terraform` | Initialise | @@ -27,8 +27,9 @@ Ce que la documentation apporte à chacun : [docs/architecture/00-vue-ensemble.m | Monitoring | Prometheus, Grafana, Alertmanager | `monitoring` | A initialiser | Le backend, la base et l'infrastructure (Terraform/k3s) sont initialises a ce stade. Le frontend -porte le squelette Angular, sans code metier : aucune route, aucun appel d'API. Les autres dossiers -portent l'arborescence et un README de cadrage, leur contenu fait l'objet d'un ticket dedie. +sert un tableau de bord sur `/dashboard`, dont les données proviennent de fixtures : les endpoints +correspondants restent à écrire côté API. Les autres dossiers portent l'arborescence et un README +de cadrage, leur contenu fait l'objet d'un ticket dedie. L'etat detaille de chaque brique et les vues d'architecture sont dans [docs/architecture](docs/architecture/README.md). diff --git a/docs/architecture/00-vue-ensemble.md b/docs/architecture/00-vue-ensemble.md index 15a54c0..d083985 100644 --- a/docs/architecture/00-vue-ensemble.md +++ b/docs/architecture/00-vue-ensemble.md @@ -63,8 +63,9 @@ flowchart TB grafana -.-> prom ``` -Le lien `front -.-> api` est en pointillé à dessein : le frontend n'appelle aujourd'hui aucune -API, `provideHttpClient` n'est pas encore installé. Voir [30-frontend.md](30-frontend.md). +Le lien `front -.-> api` reste en pointillé : le frontend appelle bien une API, mais un +intercepteur répond à sa place tant que les endpoints n'existent pas. Voir +[30-frontend.md](30-frontend.md). Le lien `prom -.-> api` de même : l'API expose bien `/metrics` au format Prometheus, mais aucun collecteur ne vient le lire. @@ -74,7 +75,7 @@ collecteur ne vient le lire. | Domaine | Technologie | Emplacement | Statut | Ce qui existe réellement | |---|---|---|---|---| | Backend | FastAPI, Python 3.14 | `apps/backend` | `En cours` | Factory, configuration, journalisation, 2 sondes de santé, `/metrics`. Aucune couche métier | -| Frontend | Angular 22, Node 24 | `apps/frontend` | `En cours` | Squelette `ng new` standalone, routes vides, aucun service HTTP | +| Frontend | Angular 22, Node 24 | `apps/frontend` | `En cours` | Tableau de bord sur route `/dashboard`, deux services HTTP, graphiques Chart.js, données servies par des fixtures | | Base | PostgreSQL 17 + TimescaleDB | `db` | `Fait` | Bootstrap de l'extension, base de test, chaîne Alembic. Aucune table applicative | | Infra | Terraform, k3s single-node | `infra/terraform` | `En cours` | Module d'installation du cluster. Jamais appliqué, aucune ressource Kubernetes déclarée | | Monitoring | Prometheus, Grafana, Alertmanager | `monitoring` | `Cible` | Rien, hors le `/metrics` exposé par l'API | diff --git a/docs/architecture/30-frontend.md b/docs/architecture/30-frontend.md index 98da40a..baea451 100644 --- a/docs/architecture/30-frontend.md +++ b/docs/architecture/30-frontend.md @@ -4,30 +4,36 @@ Application Angular 22, 100 % standalone, testée avec Vitest. Source dans `apps ## État actuel -Statut : `En cours`. Le projet est un `ng new` intact. Le tableau de la -[vue d'ensemble](00-vue-ensemble.md) le classe désormais correctement, le `README.md` racine le -disait encore « à initialiser » alors que le squelette existe depuis `49f4697`. +Statut : `En cours`. L'application sert une première page métier, le tableau de bord, alimentée +par des fixtures : les endpoints qu'elle appelle n'existent pas encore côté API. Ce qui est en place : - Bootstrap par `bootstrapApplication(App, appConfig)`, **aucun `NgModule`** dans le dépôt. -- `app.config.ts` fournit `provideBrowserGlobalErrorListeners()` et `provideRouter(routes)`. -- Vitest via le builder `@angular/build:unit-test`, couverture activée, un fichier de test. +- `app.config.ts` fournit `provideBrowserGlobalErrorListeners()`, `provideRouter(routes)` et + `provideHttpClient(withInterceptors([mockApiInterceptor]))`. +- Une route `/dashboard` en composant différé, et une redirection depuis la racine. +- `core/services` porte `StatsService` et `AlertsService`, `core/interceptors` l'intercepteur de + fixtures, `features/dashboard` la page, `shared/components` la jauge de consommation et le + graphique de charge par site, tous deux construits sur Chart.js. +- L'état vit dans des signaux, sans bibliothèque dédiée. +- Vitest via le builder `@angular/build:unit-test`, couverture activée, sept fichiers de test. - Prettier configuré, parser `angular` pour les gabarits HTML. Ce qui n'existe pas encore : -- `routes` est un tableau vide. Aucune page, aucune navigation. -- **`provideHttpClient` n'est pas fourni** et `@angular/common/http` n'est importé nulle part : - l'application n'appelle aucune API. -- `app.html` est la page d'accueil Angular par défaut, commentaires de remplacement compris. -- Aucune bibliothèque de graphiques, aucun kit d'interface, aucune gestion d'état. +- **Aucun endpoint réel derrière l'écran.** `GET /api/v1/stats/summary` et `GET /api/v1/alerts` + sont servis par l'intercepteur ; l'API expose `/health`, `/auth` et `/users`, rien d'autre. +- Aucune authentification côté interface : ni garde de route, ni intercepteur de jeton, alors que + les routes métier de l'API en exigent un. Voir + [31-contrat-authentification.md](31-contrat-authentification.md). +- Aucun état de chargement : tant que la première réponse n'est pas arrivée, la page reste vide. - Aucun lint : ESLint n'est pas installé. -## Arborescence cible +## Arborescence -Statut : `Cible`. Elle n'est pas inventée ici : [`TESTING.md`](../../apps/frontend/TESTING.md) la -prescrit déjà dans ses gabarits de tests. +Statut : `Fait`. Elle suit ce que [`TESTING.md`](../../apps/frontend/TESTING.md) prescrit dans ses +gabarits de tests. ```mermaid flowchart TB @@ -48,22 +54,33 @@ directement : ils passent par un service, ce qui rend le double de test trivial. ## Flux HTTP -Statut : `Cible`. Le chemin est câblé, rien ne l'emprunte encore. +Statut : `En cours`. Le chemin complet est câblé, mais un intercepteur se place devant et répond +lui-même tant que les endpoints n'existent pas. ```mermaid sequenceDiagram participant C as Composant participant S as Service Angular + participant I as mockApiInterceptor participant P as ng serve, proxy participant A as FastAPI C->>S: appel de méthode - S->>P: GET /api/v1/... - P->>A: http://localhost:8000/api/v1/... - A-->>S: JSON + S->>I: GET /api/v1/... + alt useMockFixtures actif et route connue + I-->>S: fixture locale + else + I->>P: la requête poursuit + P->>A: http://localhost:8000/api/v1/... + A-->>S: JSON + end S-->>C: modèle typé ``` +`mockApiInterceptor` n'intercepte que `/stats/summary` et `/alerts`, et seulement si +`environment.useMockFixtures` est vrai. Le drapeau est à `true` en développement, à `false` en +production : toute autre requête, et toutes les requêtes en production, suivent le chemin réel. + En développement, `proxy.conf.json` redirige tout `/api` vers `http://localhost:8000`. C'est ce qui évite le CORS sur le poste, et c'est pourquoi `environment.development.ts` se contente d'un `apiUrl` relatif, `/api/v1`. @@ -87,6 +104,10 @@ déploiement, en même temps que sera tranchée la question de l'ingress dans | `npm run test` | Vitest en mode observateur | | `npm run test:ci` | Vitest en une passe | +**Version de Node.** L'Angular CLI refuse de démarrer en dessous de 22.22.3, 24.15.0 ou 26.0.0, et +le message d'erreur arrive avant toute compilation. Un poste en 22.21 ou en 24.12 ne peut donc ni +tester ni construire le frontend. + Le frontend **n'a pas de cible dans le `Makefile` racine** et **aucun service dans `docker-compose.yml`** : il se pilote uniquement par `npm`, depuis `apps/frontend`. Le port 4200 n'apparaît dans le compose que comme valeur par défaut d'`APP_CORS_ORIGINS`, côté backend. @@ -98,8 +119,9 @@ avec un service statique, il reste à écrire. ## Sécurité - Le frontend ne détient aucun secret : `environment.ts` ne porte qu'une URL. -- L'authentification n'existe pas côté API, donc pas de garde ni d'intercepteur de jeton à ce - stade. `core/guards` et `core/interceptors` sont prévus pour cela. +- L'authentification existe côté API mais pas côté interface : aucune garde de route, aucun + intercepteur de jeton. `core/guards` reste à créer, `core/interceptors` n'héberge aujourd'hui + que les fixtures. ## Tests @@ -107,8 +129,7 @@ Conventions et gabarits : [`apps/frontend/TESTING.md`](../../apps/frontend/TESTI ## Questions ouvertes -- **Quelle bibliothèque de graphiques** pour les séries temporelles, et si Grafana en couvre déjà - une partie du besoin. -- **Gestion d'état** : signaux seuls, ou une bibliothèque dédiée. +- **Gestion d'état** : les signaux suffisent aujourd'hui, la question se reposera quand plusieurs + pages partageront le même état. - **Comment `apiUrl` est injecté en production** : build par environnement, ou configuration lue au démarrage.