functionrenderCatalog(){view.innerHTML=`<div class="sc-eyebrow">Service Desk Simulation</div><h1 class="sc-title">Welche Schicht übernimmst du?</h1><p class="sc-intro">ServiceClash erklärt die Triage direkt im Spiel: Ordne jedes Ticket zuerst als <b>Störung</b> oder <b>Anfrage</b> ein, schätze seine Dringlichkeit ein und wähle dann die beste erste Maßnahme. Du darfst Fehler machen – bei Bedarf zeigt dir „Aufdecken“ die Begründung.</p><div class="sc-shifts">${catalog.map(s=>`<article class="sc-card"><div class="sc-eyebrow">${esc(s.difficulty)} · ${esc(s.examScope)}</div><h2>${esc(s.title)}</h2><p>${esc(s.description)}</p><div class="sc-meta"><span>${s.ticketCount} Tickets</span><span>${s.waves} Wellen</span></div><button class="sc-btn primary" data-shift="${esc(s.slug)}">SCHICHT BRIEFEN</button></article>`).join('')}</div>`;view.querySelectorAll('[data-shift]').forEach(b=>b.onclick=()=>brief(b.dataset.shift));}
asyncfunctionbrief(slug){try{session=awaitapi('/session/'+encodeURIComponent(slug));index=0;states={};view.innerHTML=`<article class="sc-panel sc-brief"><div class="sc-eyebrow">${esc(session.difficulty)} · ${session.tickets.length} Tickets</div><h1>${esc(session.title)}</h1><p class="sc-intro">${esc(session.description)}</p><p class="sc-tip"><b>So spielst du:</b> Eine <b>Störung</b> bedeutet, dass etwas bereits nicht funktioniert. Eine <b>Anfrage</b> wünscht eine geplante Leistung. Priorität <b>hoch</b> wählst du bei größerer Auswirkung, Sicherheitsrisiko oder Zeitkritik. Die Punkte berücksichtigen alle drei Entscheidungen.</p><button id="scStart" class="sc-btn primary">LEITSTAND ÖFFNEN →</button></article>`;document.getElementById('scStart').onclick=()=>{started=Date.now();renderRun()}}catch(error){fail(error)}}
functionchoiceMarkup(ticket,state){if(state.done.length===3)return'';if(state.step==='classify')return`<div class="sc-choices"><button class="sc-choice" data-value="incident"><b>Störung</b><br><small>Etwas funktioniert bereits nicht.</small></button><button class="sc-choice" data-value="request"><b>Anfrage</b><br><small>Eine Leistung soll geplant erbracht werden.</small></button></div>${revealButton()}`;if(state.step==='priority')return`<div class="sc-choices"><button class="sc-choice" data-value="high"><b>Hoch</b><br><small>Sicherheits-, Geschäfts- oder Zeitrisiko.</small></button><button class="sc-choice" data-value="medium"><b>Mittel</b><br><small>Spürbar, aber mit begrenzter Auswirkung.</small></button><button class="sc-choice" data-value="low"><b>Niedrig</b><br><small>Planbar, lokal oder ohne akute Auswirkung.</small></button></div>${revealButton()}`;return`<div class="sc-choices">${ticket.options.map(o=>`<button class="sc-choice" data-value="${esc(o.id)}">${esc(o.text)}</button>`).join('')}</div>${revealButton()}`}
constrevealButton=()=>`<button id="scReveal" class="sc-reveal">Antwort aufdecken (keine Punkte für diesen Schritt)</button>`;
asyncfunctioncheck(step,value,reveal=false){constticket=current();try{constresult=awaitpost('/check',{ticketId:ticket.ticketId,step,value,reveal});conststate=ticketState(ticket);states[ticket.ticketId]=state;if(result.resolved){state.done=[...state.done,step];state.step=step==='classify'?'priority':step==='priority'?'solve':'done'}state.bad=!result.correct;state.feedback=result.correct?'Richtig eingeordnet.':`${reveal?'Aufgedeckt':'Noch nicht passend.'}${result.answer?`Richtig wäre: <b>${esc(label(result.answer,ticket))}</b>.`:''}`;if(result.ticketDone){state.explanation=result.explanation;state.feedback='Ticket abgeschlossen. Prüfe kurz das Debrief und entscheide dann selbst, wann du weitergehst.'}renderRun()}catch(error){fail(error)}}
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.