# Vue d'ensemble
EnerVision collecte, stocke, analyse et restitue des séries temporelles énergétiques, sur une
machine on-premise.
## Cadre du projet
Quatre jalons ont été posés à l'ouverture du projet. Ils ont disparu du `README.md` lors de la
réécriture de l'arborescence (`2670483`) et ne subsistaient que sur `main`. Ils sont repris ici
parce qu'ils disent ce que le projet doit prouver, et donc à quoi sert chaque décision technique.
| Jalon | Intitulé | Ce que la documentation apporte |
|---|---|---|
| J1 | Valider la préparation de l'environnement et du repo | `10-infra.md` décrit la stack du poste de développement et la commande qui la démarre |
| J2 | Valider le périmètre retenu et les choix technologiques | Les ADR (`../adr/`) portent les choix ; `40-data.md` liste les questions de périmètre encore ouvertes |
| J3 | Valider l'architecture et la gestion de la sécurité | Les cinq vues, et la section « Sécurité » ci-dessous qui consolide les surfaces exposées |
| J4 | Valider la robustesse et assurer les livrables | `20-backend.md` et `30-frontend.md` renvoient aux conventions de tests de chaque application |
## Contexte
Statut : `Cible`. Les acteurs et les sources de mesures ne sont pas arrêtés, c'est l'objet du
jalon J2.
```mermaid
flowchart LR
exploitant["Exploitant
consulte les courbes"]
admin["Administrateur
exploite la plateforme"]
sources["Sources de mesures
à définir en J2"]
subgraph systeme["EnerVision"]
plateforme["Collecte, stockage,
analyse et restitution
de séries temporelles"]
end
sources -.-> plateforme
exploitant -.-> plateforme
admin -.-> plateforme
```
## Conteneurs
Trait plein pour ce qui tourne, pointillé pour ce qui est cible.
```mermaid
flowchart TB
navigateur["Navigateur"]
subgraph machine["Machine on-premise"]
front["Frontend Angular 22
apps/frontend"]
api["API FastAPI
apps/backend"]
db[("PostgreSQL 17
TimescaleDB")]
airflow["Airflow
etl/airflow"]
prom["Prometheus"]
grafana["Grafana"]
end
navigateur --> front
front -.-> api
api --> db
airflow -.-> db
prom -.-> api
grafana -.-> db
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 `prom -.-> api` de même : l'API expose bien `/metrics` au format Prometheus, mais aucun
collecteur ne vient le lire.
## État de la stack
| 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 |
| 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 |
| ETL | Apache Airflow | `etl/airflow` | `Cible` | Rien |
| CI/CD | GitHub Actions | `.github/workflows` | `Cible` | Rien |
## Flux bout en bout
Statut : `Cible`. Aucun maillon de cette chaîne n'existe aujourd'hui, à l'exception de la base.
```mermaid
sequenceDiagram
participant S as Source de mesures
participant A as Airflow
participant T as TimescaleDB
participant API as FastAPI
participant U as Angular
S->>A: mesures horodatées
A->>T: insertion dans l'hypertable
T->>T: rafraîchissement de l'agrégat continu
U->>API: GET /api/v1/...
API->>T: agrégation sur la fenêtre demandée
T-->>API: lignes
API-->>U: JSON
```
## Sécurité
Section rattachée au jalon J3. Le détail par brique est dans chaque document ; voici la vue
consolidée.
### En place
- **Les secrets n'ont pas de valeur par défaut.** `APP_SECRET_KEY` et `DATABASE_URL` sont requis
sans repli : l'application refuse de démarrer si l'un manque, plutôt que de tourner avec une
valeur de démonstration. `.env` reste hors dépôt, `.env.example` est versionné.
- **CORS conditionnel** : le middleware n'est ajouté que si `APP_CORS_ORIGINS` est renseigné.
- **Documentation interactive fermée en production** : `/docs`, `/redoc` et `/openapi.json` sont
désactivés dès que `APP_ENV=prod`.
- **Conteneur backend non-root**, déclaré dans `apps/backend/Dockerfile`.
- **Côté infrastructure** : la clé SSH est marquée `sensitive`, le kubeconfig reste en `600/root`
sur la machine cible et n'est lu que par `sudo`, `*.tfvars` est ignoré par git sauf les
`.example`.
### Absent
- **Aucune authentification ni autorisation.** Les deux endpoints exposés sont publics. Rien
n'est encore décidé sur ce point.
- Pas de TLS, pas de limitation de débit, pas de journalisation des accès, pas de rotation des
secrets.
- Aucune analyse de dépendances ni de conteneur, faute de CI.
## Décisions structurantes
Elles vivent dans `../adr/`, pas ici.
| ADR | Objet |
|---|---|
| [0001](../adr/0001-postgresql-timescaledb.md) | PostgreSQL 17 avec l'extension TimescaleDB, et la frontière `db/` vs `alembic/` |