C1 · Context
Wie gebruikt het systeem? Waarmee communiceert het?
Het dashboard in relatie tot externe systemen en eindgebruikers.
Zones:
External
Processing
Storage
Frontend
Users
↑ Klik op een component voor details
External
Systeem (in scope)
Users
Extern systeem
🌐
Microsoft CSV API
aka.ms/MSRoadmapCSV · publiek · geen auth
CSV fetch
Softwaresysteem
📋
M365 Roadmap Dashboard
Vertaalt en visualiseert Microsoft 365 roadmap-updates voor Nederlandse medewerkers. Gratis gehost op GitHub Pages + Actions. Workflow: maandag 06:00 UTC.
leest roadmap
Gebruiker
👤
Medewerker
Bekijkt updates · filtert op actie-type
Extern systeem
🔤
Google Translate
EN → NL via deep_translator
EN→NL
Teams-tab
Gebruiker
🔧
IT-beheerder
Beoordeelt acties · beheert Teams-tab
External
Processing
Storage
Frontend
Users
Extern
🌐
Microsoft CSV API
Publiek · geen auth
CSV
CI/CD
⚙️
GitHub Actions
Maandag 06:00 UTC
opslaan
JSON
📦
data.json
Snapshot + cache
deploy
Hosting
🌍
GitHub Pages
CDN · HTTPS · gratis
serveert
Browser
🌐
Browser / Teams
Medewerkers & IT
Extern
🔤
Google Translate
deep_translator · gratis
EN→NL
Script
🐍
fetch_roadmap.py
Ophalen · vertalen · opslaan
JSON
🗄️
archive/
Weekbestanden · max 3 mnd
archief
UI
🖥️
HTML-pagina's
index · kalender · archief · presentatie · architectuur + shared.css
Processing — fetch_roadmap.py (GitHub Actions · maandag 06:00 UTC)
📥
CSV Fetcher
curl + browser-headers
💾
Vertaalcache
Hash-vergelijking · delta · opgeslagen in data.json
🔤
Vertaalmodule
deep_translator → Google EN→NL
🔍
Product- & statusdetectie
DETECT_PATTERNS · 30 producten
✍️
Data Writer
data.json + archive/ + index.json · removed[] · git push
Storage
📦
data.json
items[] · removed[] · count
🗄️
archive/YYYY-MM-DD.json
Weekarchief · auto · max 3 maanden
📇
archive/index.json
Gesorteerde lijst van archiefdatums
Frontend — GitHub Pages · Vanilla HTML/CSS/JS · app-meta.js + shared.js · WCAG 2.2 AA · 5 CSS-bestanden
🏠
index.html
Filters · statistieken · SessionStorage · URL-params · periode: vorige week standaard
📅
kalender.html
Kort (6 mnd) + lang (kwartaal) · periodfilter · ?id= deep-link
📚
archief.html
loadIndex() + loadWeek() · lazy loading · productfilter
📊
presentatie.html
Klantpresentatie generator · product selectie · .pptx via PptxGenJS
🗺️
architectuur.html
C4-diagram · interactieve nodes · detail panel · C1–C4 niveaus
🎨
CSS-bestanden (5x)
shared.css + kalender · archief · presentatie · architectuur
fetch_roadmap.py — Sleutelfuncties
📥 fetch_csv()
# Haalt CSV op van Microsoft
def fetch_csv() → list[dict]:
url = "aka.ms/MSRoadmapCSV"
headers = {
"User-Agent": "Mozilla/5.0",
"Accept-Language": "en-US"
}
raw = curl(url, headers)
return csv.DictReader(raw)🔤 translate_items()
# Vertaalt alleen nieuwe/gewijzigde items
def translate_items(
items: list[dict], cache: dict
) → list[dict]:
translator = GoogleTranslator(
source="en", target="nl")
for item in items:
h = hash(item["Title"])
if cache.get(item["id"]) != h:
item["title_nl"] = translator
.translate(item["Title"])🔍 detect_product()
# Matcht CSV-rij op dashboardproduct
DETECT_PATTERNS = {
"Teams": ["teams", "meeting"],
"SharePoint":["sharepoint"],
... # 30 producten totaal
}
def detect_product(
row: dict) → str:
pf = row["ProductFamily"].lower()
return next(k for k,v
in DETECT_PATTERNS
if pf in v, "other")data.json — Schema
📦 RoadmapItem (één item in items[])
{
"id": number # Microsoft ID (uniek)
"title": string # Vertaalde Nederlandse titel
"desc": string # Vertaalde Nederlandse beschrijving
"benefit": string # AI-gegenereerde organisatie-impact (NL)
"app": string # bijv. "teams", "copilot"
"tags": string[] # aanvullende product-keys
"prodLabel": string # weergavelabel bijv. "OneDrive"
"status": enum # "rolling" | "dev"
"action": enum # "none" | "admin" | "user"
"actionLabel": string # leesbare actie-omschrijving (NL)
"release": string # bijv. "June CY2026"
"preview": string # preview-datum indien van toepassing
"added": string # ISO-datum toegevoegd
"modified": string # ISO-datum laatste wijziging
}🗂️ data.json (root object)
{
"generated": string
# ISO-timestamp van laatste run
"count": number
# Totaal aantal actuele items
"items": RoadmapItem[]
# Alle actuele roadmap-items
"removed": RoadmapItem[]
# Verdwenen/gelanceerde items deze run
# bevat ook: statusNl ("Beschikbaar" | "Geannuleerd" | ...)
}index.html — Sleutel-JavaScript
📡 loadData()
# CACHE_KEY = 'm365_data_v1' · TTL 30 min
function loadData():
cached = sessionStorage
.get("m365_data_v1")
if cached && !expired(cached):
return handleData(cached)
ctrl = new AbortController()
setTimeout(abort, 12000)
url = "data.json?v="+Date.now()
fetch(url, {signal: ctrl.signal})🔎 render() — Periodefilter
# fA: "all" | "pw" | "am"
# pw = vorige kalenderweek (standaard)
# am = afgelopen 31 dagen
function matchPeriod(item):
prevWkStart = weekStart(now) - 7d
prevWkEnd = weekEnd(now) - 7d
if fA === "pw":
return inRange(item.added,
prevWkStart, prevWkEnd)
|| inRange(item.modified, ...)🖼️ appIconHTML() — gedeeld via shared.js + app-meta.js
# base64 PNG's in APP_ICONS (per product)
# Inline in elke pagina — geen extern bestand
APP_ICONS = {
copilot: "data:image/png;base64,...",
teams: "data:image/png;base64,...",
... # 16 producten
}
function appIconHTML(key):
return '<img class="app-icon"'
+ ' src="'+APP_ICONS[key]+'"'
+ ' aria-hidden="true">'Functie
Logica / Werking
Technische details