Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e06b08546 | ||
|
|
931ec9e527 | ||
|
|
c8eddbc02b | ||
|
|
0a7dd2e692 |
@@ -258,43 +258,7 @@ imparti, et **RPA avancé**, au-delà de l'orchestration Airflow.
|
||||
|
||||
---
|
||||
|
||||
## 6. Écarts entre conception (EC01) et réalisation
|
||||
|
||||
Le guide d'évaluation le dit : **les écarts entre conception et réalisation font partie du
|
||||
compte rendu d'activité**. Chaque écart ci-dessous porte sa trace.
|
||||
|
||||
| # | Choix du dossier EC01 (14/09) | Réalisé au gel | Verdict |
|
||||
|---|---|---|---|
|
||||
| 1 | FastAPI / Python pour l'API | FastAPI, contrat OpenAPI versionné et testé | ✅ Tenu |
|
||||
| 2 | PostgreSQL 17 + TimescaleDB | Identique, relevés en hypertable (ADR 0001) | ✅ Tenu |
|
||||
| 3 | JWT + Argon2id, RBAC à 3 rôles | Identique, plus rotation du jeton de rafraîchissement (ADR 0002, 0003) | ✅ Tenu |
|
||||
| 4 | Une valeur nulle n'est jamais effacée | Qualité de donnée et imputation tracées, gravées par une contrainte `CHECK` | ✅ Tenu |
|
||||
| 5 | Contrats d'interface figés | Contrat OpenAPI testé, table `prediction` comme frontière ML | ✅ Tenu |
|
||||
| 6 | Docker Compose plutôt que Kubernetes | Compose, un projet par environnement (ADR 0009, 0017) | ✅ Tenu |
|
||||
| 7 | On-premise plutôt que cloud public | Machine de l'école, aucune ressource cloud | ✅ Tenu |
|
||||
| 8 | Traefik en terminaison TLS | Nginx par stack (ADR 0007) et frontal SNI (ADR 0018) | 🔁 Substitué |
|
||||
| 9 | Prophet + IsolationForest | LightGBM, un modèle global (ADR 0005), alertes internes par règles, dérive surveillée (ADR 0013) | 🔁 Substitué |
|
||||
| 10 | APScheduler pour l'ETL | Airflow, 7 DAGs : imports, entraînement, scoring, alertes, dérive, rétention | 🔁 Substitué |
|
||||
| 11 | MinIO, couche bronze | Garage par environnement (ADR 0019) | 🔁 Substitué |
|
||||
| 12 | Ansible, durcissement et déploiement | Terraform et script rejouable (ADR 0010) ; durcissement non automatisé | ⚠️ Partiel |
|
||||
| 13 | SOPS + age pour les secrets | Secrets générés sur la machine, hors de Git | ❌ Non fait |
|
||||
| 14 | Trivy, Bandit, gitleaks en CI | Bandit (#121) et un DAST ZAP non prévu (#140) ; Trivy et gitleaks hors CI | ⚠️ Partiel |
|
||||
| 15 | Prometheus, Grafana, Loki | Prometheus, Alertmanager, Grafana actifs en production (ADR 0016) ; pas de Loki | ⚠️ Partiel |
|
||||
| 16 | Runner auto-hébergé, déploiement automatique | `deploy.yml` sur runner auto-hébergé, sept déploiements de production | ✅ Tenu |
|
||||
| 17 | Deux réseaux Docker, données jamais exposées | Un seul composant exposé, le frontal ; tout le reste sur la boucle locale | 🔁 Intention tenue, autre moyen |
|
||||
|
||||
**Décompte sur les 17 choix du dossier : 8 tenus, 5 substitués, 3 partiels, 1 non fait.** Au
|
||||
23/09, il était de 8 tenus, 4 substitués, 3 partiels et 2 non faits : MinIO est passé de « non
|
||||
fait » à « substitué » par Garage.
|
||||
|
||||
**Hors de cette liste**, le dashboard était prévu en React / Vite ; il est en **Angular 22**
|
||||
depuis son initialisation le 14/09 (commit `49f4697`, PR #52). Sans effet sur le reste de
|
||||
l'architecture, puisque le frontend ne connaît que le contrat d'API. Motif : choix de Valentin, développeur
|
||||
full stack de l'équipe, qui maîtrisait Angular ; aucune objection dans le cadre du projet.
|
||||
|
||||
---
|
||||
|
||||
## 7. Usage de l'intelligence artificielle
|
||||
## 6. Usage de l'intelligence artificielle
|
||||
|
||||
Déclaration exigée par le formateur : outils utilisés, tâches réalisées, valeur ajoutée,
|
||||
limites constatées, vérifications humaines.
|
||||
@@ -316,7 +280,7 @@ tâches, valeur ajoutée, limites, vérifications.
|
||||
|
||||
---
|
||||
|
||||
## 8. Licences logicielles
|
||||
## 7. Licences logicielles
|
||||
|
||||
**Licence du dépôt** : aucun fichier `LICENSE` au gel. Faute de licence explicite, le code reste
|
||||
sous le régime par défaut : tous droits réservés à ses auteurs, aucune réutilisation accordée.
|
||||
@@ -348,7 +312,7 @@ notamment sa licence AGPL, que Garage partage ; les autres raisons de l'ADR rest
|
||||
|
||||
---
|
||||
|
||||
## 9. Anonymisation et conformité RGPD
|
||||
## 8. Anonymisation et conformité RGPD
|
||||
|
||||
- **Les données du projet sont synthétiques.** Les séries de consommation proviennent des CSV
|
||||
fournis par l'organisme de formation et de l'API Mock simulée. Aucune donnée de consommation
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,70 @@
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 17mm 16mm 19mm 16mm;
|
||||
@bottom-left {
|
||||
content: string(doctitle);
|
||||
font: 8pt Lato, "Liberation Sans", Arial, sans-serif;
|
||||
color: #6b7280;
|
||||
}
|
||||
@bottom-right {
|
||||
content: counter(page) " / " counter(pages);
|
||||
font: 8pt Lato, "Liberation Sans", Arial, sans-serif;
|
||||
color: #6b7280;
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--ink: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--label: #374151;
|
||||
--accent: #16a34a;
|
||||
--accent-dark: #15803d;
|
||||
--accent-light: #dcfce7;
|
||||
--rule: #e5e7eb;
|
||||
--border: #d1d5db;
|
||||
--soft: #f3f4f6;
|
||||
}
|
||||
|
||||
html { font: 10pt/1.48 Lato, "Liberation Sans", Arial, sans-serif; color: var(--ink); background: #fff; }
|
||||
body { margin: 0; }
|
||||
|
||||
.brand { display: flex; align-items: center; justify-content: space-between; padding-bottom: 3mm; margin-bottom: 5mm; border-bottom: 0.3mm solid var(--rule); }
|
||||
.brand .lockup { display: flex; align-items: center; gap: 3mm; }
|
||||
.brand img { height: 9mm; width: 9mm; }
|
||||
.brand .name { font-size: 14pt; font-weight: 700; color: var(--ink); }
|
||||
.brand .meta { font-size: 8pt; font-weight: 700; letter-spacing: 0.12em; color: var(--accent-dark); text-transform: uppercase; }
|
||||
|
||||
h1 { string-set: doctitle content(); font-size: 20pt; line-height: 1.2; color: var(--ink); margin: 0 0 5mm; }
|
||||
h1::after { content: ""; display: block; width: 14mm; height: 1mm; background: var(--accent); margin-top: 3mm; }
|
||||
h2 { font-size: 13.5pt; color: var(--ink); margin: 7mm 0 3mm; padding-bottom: 1.2mm; border-bottom: 0.3mm solid var(--rule); break-after: avoid; }
|
||||
h3 { font-size: 11pt; color: var(--label); margin: 5mm 0 2mm; break-after: avoid; }
|
||||
h4 { font-size: 10.2pt; margin: 4mm 0 1.5mm; break-after: avoid; }
|
||||
p, li { orphans: 3; widows: 3; }
|
||||
a { color: var(--accent-dark); text-decoration: none; }
|
||||
strong { font-weight: 700; }
|
||||
|
||||
code { font: 8.4pt "Noto Sans Mono", "DejaVu Sans Mono", monospace; background: var(--soft); padding: 0 1mm; border-radius: 1mm; }
|
||||
pre { background: var(--soft); padding: 3mm; border-radius: 0 2mm 2mm 0; border-left: 1mm solid var(--accent); overflow-wrap: anywhere; white-space: pre-wrap; break-inside: avoid; }
|
||||
pre code { background: none; padding: 0; }
|
||||
|
||||
table { border-collapse: collapse; width: 100%; margin: 3mm 0 4mm; font-size: 8.6pt; break-inside: auto; }
|
||||
thead { display: table-header-group; }
|
||||
tr { break-inside: avoid; }
|
||||
th, td { padding: 1.5mm 2.2mm; text-align: left; vertical-align: top; border-bottom: 0.25mm solid var(--rule); }
|
||||
th { font-size: 7.4pt; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); border-bottom: 0.4mm solid var(--border); }
|
||||
|
||||
thead:has(th:empty + th:empty) { display: none; }
|
||||
table:has(thead th:empty + th:empty) { border-collapse: separate; border-spacing: 0 0.6mm; margin-top: 0; }
|
||||
table:has(thead th:empty + th:empty) td { background: var(--soft); border: none; padding: 1.8mm 2.5mm; }
|
||||
table:has(thead th:empty + th:empty) td:first-child { border-radius: 2mm 0 0 2mm; width: 24mm; font-size: 7.4pt; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); padding-top: 2.2mm; }
|
||||
table:has(thead th:empty + th:empty) td:first-child strong { color: var(--muted); }
|
||||
table:has(thead th:empty + th:empty) td:last-child { border-radius: 0 2mm 2mm 0; }
|
||||
|
||||
blockquote { margin: 3mm 0; padding: 2mm 4mm; border-left: 1mm solid var(--accent); background: var(--soft); border-radius: 0 2mm 2mm 0; }
|
||||
hr { border: none; border-top: 0.3mm solid var(--rule); margin: 6mm 0; }
|
||||
img { max-width: 100%; }
|
||||
|
||||
.badge { display: inline-block; font-size: 6.8pt; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; border-radius: 99mm; padding: 0.3mm 1.8mm; line-height: 1.5; vertical-align: 0.3mm; white-space: nowrap; }
|
||||
.badge.ok { background: var(--accent); color: #fff; }
|
||||
.badge.warn { background: #fef9e7; color: #92400e; border: 0.25mm solid #f9a825; }
|
||||
.badge.no { background: #fef2f2; color: #b91c1c; border: 0.25mm solid #dc2626; }
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Réf : consigne formateur, version figée d'un livrable = Markdown -> HTML -> CSS de pagination -> PDF.
|
||||
# Usage : md2pdf.sh "fichier.md" [sortie.pdf]. Sans sortie, le PDF est écrit à côté du .md.
|
||||
set -euo pipefail
|
||||
|
||||
src="$1"
|
||||
out="${2:-${src%.md}.pdf}"
|
||||
here="$(cd "$(dirname "$0")" && pwd)"
|
||||
work="$(mktemp -d)"
|
||||
trap 'rm -rf "$work"' EXIT
|
||||
|
||||
title="$(grep -m1 '^# ' "$src" | sed 's/^# //; s/&/\&/g; s/</\</g')"
|
||||
css_title="$(grep -m1 '^# ' "$src" | sed 's/^# //; s/\\/\\\\/g; s/"/\\"/g')"
|
||||
logo="$(base64 -w0 "$here/logo-icon.png")"
|
||||
|
||||
npx --yes marked@18 --gfm -i "$src" -o "$work/body.html"
|
||||
sed -i 's/ \([:;?!»]\)/\xc2\xa0\1/g; s/« /«\xc2\xa0/g' "$work/body.html"
|
||||
# Les marqueurs de preuve du rapport EC04 deviennent des pastilles, comme les badges d'état de l'application.
|
||||
sed -i -E 's#\[Prouvé\]#<span class="badge ok">Prouvé</span>#g; s#\[Constaté\]#<span class="badge warn">Constaté</span>#g; s#\[Absent\]#<span class="badge no">Absent</span>#g; s#<strong>((<span class="badge[^"]*">[^<]*</span> ?)+)</strong>#\1#g' "$work/body.html"
|
||||
|
||||
{
|
||||
printf '<!doctype html>\n<html lang="fr"><head><meta charset="utf-8"><title>%s</title><style>\n' "$title"
|
||||
cat "$here/md2pdf.css"
|
||||
# Piège : Chromium ignore `string-set`, le titre du pied de page est donc écrit en dur ici.
|
||||
printf '\n@page { @bottom-left { content: "%s"; } }\n' "$css_title"
|
||||
printf '\n</style></head><body>\n'
|
||||
printf '<div class="brand"><div class="lockup"><img src="data:image/png;base64,%s" alt=""><span class="name">EnerVision</span></div><div class="meta">EADL 2026 · Groupe 3</div></div>\n' "$logo"
|
||||
cat "$work/body.html"
|
||||
printf '\n</body></html>\n'
|
||||
} > "$work/doc.html"
|
||||
|
||||
chromium --headless --disable-gpu --no-pdf-header-footer \
|
||||
--print-to-pdf="$out" "file://$work/doc.html" 2>/dev/null
|
||||
|
||||
echo "PDF écrit : $out"
|
||||
Reference in New Issue
Block a user