197 lines
6.9 KiB
Typst
197 lines
6.9 KiB
Typst
#import "/metadata.typ": *
|
|
#import "/tail/bibliography.typ": *
|
|
#import "/tail/glossary.typ": *
|
|
#import "/main/architecture/description.typ": *
|
|
|
|
#import "/resources/slides.typ": *
|
|
|
|
// Chemin racine des images — adapter selon ta structure de projet
|
|
#let img-root = "../../resources/img/ui_images/images/"
|
|
|
|
// ── Palette ───────────────────────────────────────────────────────────────────
|
|
#let c-dark = rgb("#0F172A")
|
|
#let c-teal = rgb("#0EA5E9")
|
|
#let c-text = rgb("#1E293B")
|
|
#let c-muted = rgb("#64748B")
|
|
#let c-white = rgb("#FFFFFF")
|
|
#let c-border = rgb("#E2E8F0")
|
|
|
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
|
|
#let icon-circle(img-path, size: 38pt, bg: rgb("#0EA5E9")) = {
|
|
box(
|
|
width: size, height: size,
|
|
fill: bg, radius: (size / 2),
|
|
inset: 0pt, clip: true,
|
|
)[
|
|
#align(center + horizon)[
|
|
#image(img-path, width: (size * 0.62), height: (size * 0.62), fit: "contain")
|
|
]
|
|
]
|
|
}
|
|
|
|
#let badge(label, fill: rgb("#EF4444")) = {
|
|
box(fill: fill, radius: 3pt, inset: (x: 5pt, y: 2pt))[
|
|
#text(size: 6.5pt, weight: "bold", fill: rgb("#FFFFFF"))[#label]
|
|
]
|
|
}
|
|
|
|
#let devsec-col(phase-title, items) = {
|
|
block(width: 100%)[
|
|
#block(
|
|
width: 100%, height: 28pt,
|
|
fill: c-dark,
|
|
radius: (top-left: 5pt, top-right: 5pt, bottom-left: 0pt, bottom-right: 0pt),
|
|
inset: 0pt,
|
|
)[
|
|
#pad(x: 7pt)[
|
|
#align(horizon + center)[
|
|
#text(size: 8.5pt, weight: "bold", fill: rgb("#FFFFFF"))[#phase-title]
|
|
]
|
|
]
|
|
]
|
|
#block(
|
|
width: 100%,
|
|
fill: rgb("#F1F5F9"),
|
|
radius: (top-left: 0pt, top-right: 0pt, bottom-left: 5pt, bottom-right: 5pt),
|
|
inset: 8pt,
|
|
)[
|
|
#for item in items {
|
|
grid(columns: (30pt, 1fr), gutter: 6pt,
|
|
icon-circle(item.at("icon"), size: 28pt, bg: item.at("bg", default: c-teal)),
|
|
align(left + horizon)[
|
|
#text(size: 8pt, weight: "bold", fill: c-text)[#item.at("name")]
|
|
#linebreak()
|
|
#item.at("extra", default: [])
|
|
],
|
|
)
|
|
v(5pt)
|
|
}
|
|
]
|
|
]
|
|
}
|
|
|
|
== Cycle DevSecOps
|
|
|
|
#slide[
|
|
#grid(columns: (1fr, 1fr, 1fr, 1fr), gutter: 8pt,
|
|
devsec-col("① Code & PR Gate", (
|
|
(icon: img-root + "image10.png", bg: rgb("#3178C6"), name: "TypeScript",
|
|
extra: [#text(size: 6.5pt, fill: c-muted)[tsc / ESLint]]),
|
|
(icon: img-root + "image11.png", bg: rgb("#DD0031"), name: "Angular CI",
|
|
extra: [#text(size: 6.5pt, fill: c-muted)[Build check]]),
|
|
(icon: img-root + "image19.png", bg: rgb("#1F2328"), name: "GitHub Actions",
|
|
extra: [#text(size: 6.5pt, fill: c-muted)[Coverage]]),
|
|
)),pause,
|
|
devsec-col("② SAST · SCA", (
|
|
(icon: img-root + "image7.png", bg: rgb("#000000"), name: "SpotBugs",
|
|
extra: [#badge("BLOCKING")]),
|
|
(icon: img-root + "image13.png", bg: rgb("#1F2328"), name: "CodeQL",
|
|
extra: [#badge("BLOCKING")]),
|
|
(icon: img-root + "image14.png", bg: rgb("#F97316"), name: "Dep. Check",
|
|
extra: [#badge("NON-BLOCK", fill: rgb("#F97316"))]),
|
|
)),pause,
|
|
devsec-col("③ DAST · Tests", (
|
|
(icon: img-root + "image15.png", bg: rgb("#00549E"), name: "OWASP ZAP",
|
|
extra: [#badge("BLOCKING")]),
|
|
(icon: img-root + "image16.png", bg: rgb("#DD0031"), name: "Karma Tests",
|
|
extra: [#badge("BLOCKING")]),
|
|
(icon: img-root + "image17.png", bg: rgb("#64748B"), name: "Runtime check",
|
|
extra: [#text(size: 6.5pt, fill: c-muted)[HTTP headers]]),
|
|
)),pause,
|
|
devsec-col("④ Build · Deploy", (
|
|
(icon: img-root + "image18.png", bg: rgb("#0DB7ED"), name: "Docker",
|
|
extra: [#text(size: 6.5pt, fill: c-muted)[SHA-tagged]]),
|
|
(icon: img-root + "image19.png", bg: rgb("#1F2328"), name: "GHCR Push",
|
|
extra: [#text(size: 6.5pt, fill: c-muted)[main only]]),
|
|
(icon: img-root + "image17.png", bg: rgb("#10B981"), name: "SSH Deploy",
|
|
extra: [#text(size: 6.5pt, fill: c-muted)[cert-auth]]),
|
|
)),pause,
|
|
)
|
|
|
|
#v(7pt)
|
|
|
|
#rect(width: 100%, height: 26pt, fill: c-dark, radius: 4pt, inset: 0pt)[
|
|
#pad(x: 20pt)[
|
|
#align(horizon)[
|
|
#grid(columns: (1fr, 1fr, 1fr),
|
|
align(center + horizon)[#text(size: 8pt, fill: rgb("#FFFFFF"))[🔐 #h(2pt) Shift-left security]],
|
|
align(center + horizon)[#text(size: 8pt, fill: rgb("#FFFFFF"))[🔑 #h(2pt) Zero secret in code]],
|
|
align(center + horizon)[#text(size: 8pt, fill: rgb("#FFFFFF"))[🔄 #h(2pt) Automated Deployment]],
|
|
)
|
|
]
|
|
]
|
|
]
|
|
|
|
#v(6pt)
|
|
]
|
|
|
|
|
|
// ── SLIDE 3 — Dashboard ───────────────────────────────────────────────────────
|
|
== Dashboard
|
|
|
|
#slide[
|
|
#align(center + horizon)[
|
|
#figure(
|
|
image(img-root + "image20.png", width: 100%, fit: "contain"),
|
|
caption: [Dashboard]
|
|
)
|
|
]
|
|
]
|
|
|
|
// ── SLIDE 4 — Details Page ────────────────────────────────────────────────────
|
|
== Details Page
|
|
|
|
#slide[
|
|
#align(center + horizon)[
|
|
#figure(
|
|
image(img-root + "image21.png", width: 100%, fit: "contain"),
|
|
caption: [Details page]
|
|
)
|
|
]
|
|
]
|
|
|
|
// ── SLIDE 5 — Notification ────────────────────────────────────────────────────
|
|
== Notification
|
|
|
|
#slide[
|
|
#grid(columns: (1fr, 1fr), gutter: 16pt,
|
|
// Screenshot Telegram
|
|
align(center + horizon)[
|
|
|
|
#figure(
|
|
image(img-root + "image22.png", height: 300pt, fit: "contain"),
|
|
caption: [Telegram notification]
|
|
)
|
|
],
|
|
// Carte descriptive
|
|
rect(width: 100%, radius: 6pt, stroke: 0.5pt + c-border, fill: rgb("#FFFFFF"), inset: 12pt)[
|
|
#text(size: 10pt, weight: "bold", fill: c-text)[CO₂ Alerts System]
|
|
#v(5pt)
|
|
#line(length: 100%, stroke: 0.5pt + c-border)
|
|
#v(6pt)
|
|
|
|
#let alert-row(col, level, desc) = {
|
|
grid(columns: (10pt, 52pt, 1fr), gutter: 5pt,
|
|
box(width: 8pt, height: 8pt, fill: col, radius: 4pt),
|
|
text(size: 8.5pt, weight: "bold")[#level],
|
|
text(size: 8pt, fill: c-muted)[#desc],
|
|
)
|
|
v(4pt)
|
|
}
|
|
#alert-row(rgb("#f44336"), "Critical", "> 2000 ppm")
|
|
#alert-row(rgb("#F97316"), "Very Poor", "1500-2000 ppm")
|
|
#alert-row(rgb("#ff9800"), "Poor", "1200-1500 ppm")
|
|
#alert-row(rgb("#ffc107"), "Moderate", "1000-1200 ppm")
|
|
#alert-row(rgb("#8bc34a"), "Good", "800-1000 ppm")
|
|
#alert-row(rgb("#4caf50"), "Excellent", "< 800 ppm")
|
|
|
|
#v(6pt)
|
|
#line(length: 100%, stroke: 0.5pt + c-border)
|
|
#v(6pt)
|
|
|
|
#v(6pt)
|
|
|
|
],
|
|
)
|
|
] |