Rollenuebersicht ausklappbar + Rollen-Glossar bereinigt

- Neuer ausklappbarer Block "Klicke fuer Rollenuebersicht" unter der RACI-Legende
  (in beiden RACI-Schritten); zeigt die gruppierten Rollen wie das linke Panel.
- Rollen-Glossar bereinigt:
  - "Betrieb (AL B&C / AL App)" -> "Operation Manager (AL B&C/App)"
  - "Architektur" -> "IT-Architekt" (inkl. betroffener Quiz-Optionen)
  - SOR aus der Rollenuebersicht entfernt (bleibt Gate-Keeper-Label)
  - AL Basis & Cloud / AL Applikationen entfernt
  - Gruppen-Ueberschrift "Management (operative Fuehrung)" -> "Operative Fuehrung"
  - SOR-Hinweis aus der Rollenuebersicht entfernt
- sw.js Cache hochgezaehlt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
breitenbach76 2026-06-10 11:03:18 +02:00
parent 795cfb5087
commit 47c8c9109e
2 changed files with 24 additions and 14 deletions

View file

@ -480,21 +480,20 @@ const TOUR = {
========================================================================= */ ========================================================================= */
const ROLLEN = { const ROLLEN = {
spm:"Service-Portfolio-Manager", sor:"Service Operations Runde (SOR)", spm:"Service-Portfolio-Manager", sor:"Service Operations Runde (SOR)",
service_owner:"Service Owner", al_basis_cloud:"AL Basis & Cloud", service_owner:"Service Owner", support_manager:"Support Manager",
al_applikationen:"AL Applikationen", support_manager:"Support Manager",
problem_manager:"Problem Manager", projektleitung:"Projektleitung", problem_manager:"Problem Manager", projektleitung:"Projektleitung",
betriebsteam:"Betriebsteam", service_support_team:"Service-Support Team", betriebsteam:"Betriebsteam", service_support_team:"Service-Support Team",
projektteam:"Projektteam", queue_koordinator:"Queue Koordinator", projektteam:"Projektteam", queue_koordinator:"Queue Koordinator",
first_level_agent:"1st Level Agent", second_level_agent:"2nd Level Agent", first_level_agent:"1st Level Agent", second_level_agent:"2nd Level Agent",
testmanagement:"Testmanagement", architektur:"Architektur", testmanagement:"Testmanagement", architektur:"IT-Architekt",
lieferant:"Lieferant", operations_manager:"Betrieb (AL B&C / AL App)", dpm:"Demand Portfolio Manager" lieferant:"Lieferant", operations_manager:"Operation Manager (AL B&C/App)", dpm:"Demand Portfolio Manager"
}; };
// Rollen-Glossar fuer das Overlay: gruppiert/eingefaerbt nach den 6 Figuren-Kategorien // Rollen-Glossar fuer das Overlay: gruppiert/eingefaerbt nach den 6 Figuren-Kategorien
// (Farbe = Filamentfarbe der Figuren). Deckt alle ROLLEN-Eintraege ab. // (Farbe = Filamentfarbe der Figuren). Deckt alle ROLLEN-Eintraege ab.
const ROLLEN_GRUPPEN = [ const ROLLEN_GRUPPEN = [
{ label:"Governance (Entscheider)", color:"#c9a227", roles:["spm","service_owner","sor"] }, { label:"Governance (Entscheider)", color:"#c9a227", roles:["spm","service_owner"] },
{ label:"Umfeld / Auftraggeber", color:"#7d2e3f", roles:["dpm"] }, { label:"Umfeld / Auftraggeber", color:"#7d2e3f", roles:["dpm"] },
{ label:"Management (operative Führung)", color:"#2f80c9", roles:["projektleitung","operations_manager","al_basis_cloud","al_applikationen","support_manager","problem_manager"] }, { label:"Operative Führung", color:"#2f80c9", roles:["projektleitung","operations_manager","support_manager","problem_manager"] },
{ label:"Operative / Fachexperten", color:"#6b7686", roles:["queue_koordinator","first_level_agent","second_level_agent","testmanagement","architektur"] }, { label:"Operative / Fachexperten", color:"#6b7686", roles:["queue_koordinator","first_level_agent","second_level_agent","testmanagement","architektur"] },
{ label:"Externe", color:"#cfd6df", roles:["lieferant"] }, { label:"Externe", color:"#cfd6df", roles:["lieferant"] },
{ label:"Teams (Sonderfiguren)", color:"#2f9e57", roles:["betriebsteam","service_support_team","projektteam"] } { label:"Teams (Sonderfiguren)", color:"#2f9e57", roles:["betriebsteam","service_support_team","projektteam"] }
@ -744,7 +743,7 @@ const STATIONEN = [
raci:[["service_owner","A"],["projektleitung","R"],["betriebsteam","C"],["architektur","C"],["spm","C"]], raci:[["service_owner","A"],["projektleitung","R"],["betriebsteam","C"],["architektur","C"],["spm","C"]],
quiz:[ quiz:[
{frage:"Wer trägt die Ergebnisverantwortung (A) für diese Aktivität?", {frage:"Wer trägt die Ergebnisverantwortung (A) für diese Aktivität?",
optionen:["Service Owner","Projektleitung","SPM","Architektur"], richtig:0, optionen:["Service Owner","Projektleitung","SPM","IT-Architekt"], richtig:0,
expl:"Der (designierte) Service Owner ist Accountable; die Projektleitung führt operativ aus (R)."}, expl:"Der (designierte) Service Owner ist Accountable; die Projektleitung führt operativ aus (R)."},
{frage:"Welches zentrale Artefakt entsteht hier?", {frage:"Welches zentrale Artefakt entsteht hier?",
optionen:["Betriebshandbuch","Service-Definition","Review-Bericht","Incident Record"], richtig:1, optionen:["Betriebshandbuch","Service-Definition","Review-Bericht","Incident Record"], richtig:1,
@ -758,8 +757,8 @@ const STATIONEN = [
raci:[["service_owner","A"],["architektur","R"],["projektteam","R"],["spm","I"]], raci:[["service_owner","A"],["architektur","R"],["projektteam","R"],["spm","I"]],
quiz:[ quiz:[
{frage:"Wer führt das Architektur-Design operativ aus (R)?", {frage:"Wer führt das Architektur-Design operativ aus (R)?",
optionen:["SPM","Service Owner","Architektur","Support Manager"], richtig:2, optionen:["SPM","Service Owner","IT-Architekt","Support Manager"], richtig:2,
expl:"Architektur und Projektteam sind Responsible; der Service Owner bleibt Accountable."} expl:"IT-Architekt und Projektteam sind Responsible; der Service Owner bleibt Accountable."}
]}, ]},
{ id:"ds_03", phase:"design", typ:"aktivitaet", { id:"ds_03", phase:"design", typ:"aktivitaet",
name:"Beschreiben des Vorgehens zur Implementierung", name:"Beschreiben des Vorgehens zur Implementierung",
@ -823,7 +822,7 @@ const STATIONEN = [
raci:[["projektleitung","A/R"],["architektur","C"],["service_owner","I"],["lieferant","C/I"]], raci:[["projektleitung","A/R"],["architektur","C"],["service_owner","I"],["lieferant","C/I"]],
quiz:[ quiz:[
{frage:"Wer trägt die Ergebnisverantwortung (A) für die Koordination der Entwicklung?", {frage:"Wer trägt die Ergebnisverantwortung (A) für die Koordination der Entwicklung?",
optionen:["Projektleitung","Architektur","Service Owner","Lieferant"], richtig:0, optionen:["Projektleitung","IT-Architekt","Service Owner","Lieferant"], richtig:0,
expl:"Die Projektleitung ist Accountable; Architektur berät (C), der Service Owner ist informiert (I)."} expl:"Die Projektleitung ist Accountable; Architektur berät (C), der Service Owner ist informiert (I)."}
]}, ]},
{ id:"tr_03", phase:"transition", typ:"aktivitaet", { id:"tr_03", phase:"transition", typ:"aktivitaet",
@ -1420,7 +1419,6 @@ function renderRollen(){
html += `<div class="rolleItem"><span class="rDot" style="background:${g.color}"></span><span>${ROLLEN[r]}</span></div>`; html += `<div class="rolleItem"><span class="rDot" style="background:${g.color}"></span><span>${ROLLEN[r]}</span></div>`;
}); });
} }
html += `<p class="akteCount" style="margin-top:14px;line-height:1.45">Hinweis: Die <b>SOR</b> ist ein <b>Gremium</b> (SPM · Betrieb · Support-Manager · Service Owner …), das am Gate-Puck zusammenkommt — keine Einzelfigur.</p>`;
$("#rollenList").innerHTML = html; $("#rollenList").innerHTML = html;
const c = $("#rollenClose"); if(c) c.onclick = ()=> document.body.classList.remove("rollenOpen"); const c = $("#rollenClose"); if(c) c.onclick = ()=> document.body.classList.remove("rollenOpen");
} }
@ -1876,6 +1874,18 @@ function raciLegendHtml(){
`<div class="rlGroup"><div class="rlGroupHead">ergänzend — nice-to-have</div>${erg.map(row).join("")}</div>` + `<div class="rlGroup"><div class="rlGroupHead">ergänzend — nice-to-have</div>${erg.map(row).join("")}</div>` +
`</div></details>`; `</div></details>`;
} }
/* Ausklappbare Rollenübersicht (gleiche Inhalte wie das linke Rollen-Panel),
direkt unter der RACI-Legende im Aktivitäts-Schritt. */
function rollenLegendHtml(){
let body = "";
for(const g of ROLLEN_GRUPPEN){
const items = g.roles.filter(r=>ROLLEN[r])
.map(r=>`<div class="rolleItem"><span class="rDot" style="background:${g.color}"></span><span>${ROLLEN[r]}</span></div>`).join("");
if(!items) continue;
body += `<div class="rlGroup"><div class="rlGroupHead">${g.label}</div>${items}</div>`;
}
return `<details class="raciLegend rollenLegend"><summary class="rlSummary">Klicke für Rollenübersicht</summary><div class="rlBody">${body}</div></details>`;
}
function renderRun(){ function renderRun(){
renderList(); renderList();
@ -1919,13 +1929,13 @@ function activitySteps(st){
auf:`<p style="margin:0 0 8px">${st.beschreibung}</p><h4 class="aufH">Das fällt darunter</h4><ul>${st.umfasst.map(u=>`<li>${u}</li>`).join("")}</ul>` }, auf:`<p style="margin:0 0 8px">${st.beschreibung}</p><h4 class="aufH">Das fällt darunter</h4><ul>${st.umfasst.map(u=>`<li>${u}</li>`).join("")}</ul>` },
{ label:"Verantwortung (R + A)", { label:"Verantwortung (R + A)",
frage:`Klärt die <b>zwei Pflicht-Rollen</b> dieser Aktivität: Wer setzt sie <b>operativ</b> um (<b>R</b>esponsible) und wer ist <b>rechenschaftspflichtig</b> (<b>A</b>ccountable — genau eine Rolle)? Stellt die Figuren auf die Spielfelder <b>R</b> und <b>A</b> im RACI-Kreis.`, frage:`Klärt die <b>zwei Pflicht-Rollen</b> dieser Aktivität: Wer setzt sie <b>operativ</b> um (<b>R</b>esponsible) und wer ist <b>rechenschaftspflichtig</b> (<b>A</b>ccountable — genau eine Rolle)? Stellt die Figuren auf die Spielfelder <b>R</b> und <b>A</b> im RACI-Kreis.`,
legend: raciLegendHtml(), legend: raciLegendHtml() + rollenLegendHtml(),
auf:`<h4 class="aufH">Operativ verantwortlich (R)</h4><div class="roleChips">${(st.raci.filter(([r,c])=>c.includes("R")).map(([r,c])=>`<span class="roleChip">${roleLabel(r)}${c.includes("A")?" (zugleich A)":""}</span>`).join("")) || '<span class="roleChip">— (keine eigene R-Rolle)</span>'}</div>` auf:`<h4 class="aufH">Operativ verantwortlich (R)</h4><div class="roleChips">${(st.raci.filter(([r,c])=>c.includes("R")).map(([r,c])=>`<span class="roleChip">${roleLabel(r)}${c.includes("A")?" (zugleich A)":""}</span>`).join("")) || '<span class="roleChip">— (keine eigene R-Rolle)</span>'}</div>`
+ `<h4 class="aufH">Rechenschaftspflichtig (A)</h4><div class="roleChips">${(st.raci.filter(([r,c])=>c.includes("A")).map(([r,c])=>`<span class="roleChip">${roleLabel(r)}</span>`).join("")) || '<span class="roleChip"></span>'}</div>` + `<h4 class="aufH">Rechenschaftspflichtig (A)</h4><div class="roleChips">${(st.raci.filter(([r,c])=>c.includes("A")).map(([r,c])=>`<span class="roleChip">${roleLabel(r)}</span>`).join("")) || '<span class="roleChip"></span>'}</div>`
+ `<p class="muted" style="margin:10px 0 0;font-size:13px">R und A sind die <b>Pflicht</b>. Beratend (C) bzw. informiert (I) klärt der nächste Schritt (ergänzend).</p>` }, + `<p class="muted" style="margin:10px 0 0;font-size:13px">R und A sind die <b>Pflicht</b>. Beratend (C) bzw. informiert (I) klärt der nächste Schritt (ergänzend).</p>` },
{ label:"Beteiligung (C + I)", { label:"Beteiligung (C + I)",
frage:`Ergänzt nun die <b>beteiligten</b> Rollen (ergänzend, nice-to-have): Wer wird <b>C</b>onsulted (vorab um Rat gefragt), wer nur <b>I</b>nformed (über das Ergebnis)? Stellt die Figuren auf die Spielfelder <b>C</b> und <b>I</b> im RACI-Kreis.`, frage:`Ergänzt nun die <b>beteiligten</b> Rollen (ergänzend, nice-to-have): Wer wird <b>C</b>onsulted (vorab um Rat gefragt), wer nur <b>I</b>nformed (über das Ergebnis)? Stellt die Figuren auf die Spielfelder <b>C</b> und <b>I</b> im RACI-Kreis.`,
legend: raciLegendHtml(), legend: raciLegendHtml() + rollenLegendHtml(),
auf:`<h4 class="aufH">Konsultiert (C) / Informiert (I)</h4><div class="roleChips">${(st.raci.filter(([r,c])=>c.includes("C")||c.includes("I")).map(([r,c])=>`<span class="roleChip">${roleLabel(r)} · ${c}</span>`).join("")) || '<span class="roleChip">— (keine C/I-Rolle)</span>'}</div>` auf:`<h4 class="aufH">Konsultiert (C) / Informiert (I)</h4><div class="roleChips">${(st.raci.filter(([r,c])=>c.includes("C")||c.includes("I")).map(([r,c])=>`<span class="roleChip">${roleLabel(r)} · ${c}</span>`).join("")) || '<span class="roleChip">— (keine C/I-Rolle)</span>'}</div>`
+ `<h4 class="aufH" style="margin-top:14px">RACI vollständig</h4>${raciTable(st)}` }, + `<h4 class="aufH" style="margin-top:14px">RACI vollständig</h4>${raciTable(st)}` },
{ label:"Artefakt", artefakt:true, { label:"Artefakt", artefakt:true,

View file

@ -1,5 +1,5 @@
/* Service Worker — SLC-Workshop Companion (App-Shell, offline-first) */ /* Service Worker — SLC-Workshop Companion (App-Shell, offline-first) */
const CACHE = "slc-companion-v36"; const CACHE = "slc-companion-v37";
const SHELL = ["./", "index.html", "manifest.webmanifest", "icon.svg"]; const SHELL = ["./", "index.html", "manifest.webmanifest", "icon.svg"];
// Action-Card-Grafiken (cards/s<service>-c<change>.png) fuer Offline vorab cachen (alle 24). // Action-Card-Grafiken (cards/s<service>-c<change>.png) fuer Offline vorab cachen (alle 24).
const CARDS = []; const CARDS = [];