<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Devine Nyaenya</title>
    <description>The latest articles on DEV Community by Devine Nyaenya (@pubg_elitemaster_6e3596b).</description>
    <link>https://dev.to/pubg_elitemaster_6e3596b</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4130366%2Ffdb98d2f-a0c5-41a6-9186-ed7362b884d6.png</url>
      <title>DEV Community: Devine Nyaenya</title>
      <link>https://dev.to/pubg_elitemaster_6e3596b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pubg_elitemaster_6e3596b"/>
    <language>en</language>
    <item>
      <title>orbitdesk-modern-workplace-operations-lab-webrtc-team-calls</title>
      <dc:creator>Devine Nyaenya</dc:creator>
      <pubDate>Thu, 17 Sep 2026 18:50:09 +0000</pubDate>
      <link>https://dev.to/pubg_elitemaster_6e3596b/orbitdesk-modern-workplace-operations-lab-webrtc-team-calls-4mdg</link>
      <guid>https://dev.to/pubg_elitemaster_6e3596b/orbitdesk-modern-workplace-operations-lab-webrtc-team-calls-4mdg</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhb97iokikemheuf1khfc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhb97iokikemheuf1khfc.png" alt=" " width="799" height="422"&gt;&lt;/a&gt;&lt;br&gt;
title: "OrbitDesk — How I Built a Modern Workplace Operations Lab with WebRTC Team Calls and No Backend"&lt;br&gt;
published: true&lt;br&gt;
tags: nextjs, webrtc, typescript, pwa, microsoft365, entraid, intune, msp, helpdesk&lt;/p&gt;

&lt;h2&gt;
  
  
  cover_image: &lt;a href="https://orbitdesk-gamma.vercel.app/og-image.png" rel="noopener noreferrer"&gt;https://orbitdesk-gamma.vercel.app/og-image.png&lt;/a&gt;
&lt;/h2&gt;

&lt;h1&gt;
  
  
  OrbitDesk — How I Built a Modern Workplace Operations Lab with WebRTC Team Calls and No Backend
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://orbitdesk-gamma.vercel.app" rel="noopener noreferrer"&gt;https://orbitdesk-gamma.vercel.app&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Case Study:&lt;/strong&gt; &lt;a href="https://devine-nyaenya-portfolio.vercel.app/projects/orbitdesk" rel="noopener noreferrer"&gt;https://devine-nyaenya-portfolio.vercel.app/projects/orbitdesk&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/Nyaenya-Devine/orbitdesk" rel="noopener noreferrer"&gt;https://github.com/Nyaenya-Devine/orbitdesk&lt;/a&gt; (source-available noncommercial)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Portfolio:&lt;/strong&gt; &lt;a href="https://devine-nyaenya-portfolio.vercel.app" rel="noopener noreferrer"&gt;https://devine-nyaenya-portfolio.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I build security systems that prove they are secure — with tests, audit logs, and verifiable controls. OrbitDesk is my flagship training lab for Modern Workplace operations — Entra ID, Intune, Exchange, Teams — built in Nairobi, Kenya.&lt;/p&gt;

&lt;p&gt;This is not a replacement for production systems. It's a safe, audited simulator for IT support professionals, MSP team leads, and interview prep.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;MSP work is high-pressure: P1 payroll blocked by Conditional Access 53000, shared mailbox not showing in Outlook, BitLocker required per policy. You triage tickets, check sign-in logs CA tab, run dsregcmd, verify Company Portal sync, and communicate with appropriate language for client profile (enterprise vs SMB vs regulated).&lt;/p&gt;

&lt;p&gt;Existing training is either theoretical or requires real tenant credentials. I wanted a lab that runs entirely in the browser, no backend required for core training, with realistic policies, SLAs, and voice communication — like a real shift.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Is (High-Level)
&lt;/h2&gt;

&lt;p&gt;OrbitDesk simulates a Modern Workplace support shift:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Queue:&lt;/strong&gt; Tickets with priorities, SLA timers, client context (Enterprise 24/7, SMB business hours, Regulated strict)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investigate:&lt;/strong&gt; Sign-in logs with Conditional Access What-If, Audit Logs, Service Health, Message Trace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediate:&lt;/strong&gt; Fixes in admin portal simulations, verify via remote desktop (dsregcmd /status, Get-BitLockerVolume, Company Portal sync)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communicate:&lt;/strong&gt; Team and client messaging with quality feedback (empathy, clarity, technical, fluency, client language)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaborate:&lt;/strong&gt; Class-based workforce — team lead can call agents in same class, presence (online, in-call, offline)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All data simulated locally — no real credentials, no external API calls for core. Progress saves locally for interview stats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture — Local-First
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Next.js 16 App Router, React 19, TypeScript strict, Tailwind CSS, Framer Motion, Web Speech API, Web Audio API, WebRTC.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;State:&lt;/strong&gt; React hooks, localStorage for progress and class code, BroadcastChannel for cross-tab signaling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Voice:&lt;/strong&gt; Web Speech API for STT (SpeechRecognition) and TTS (speechSynthesis), Web Audio for ringtone (440Hz + 480Hz) and hold music (C4 E4 G4 C5)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PWA:&lt;/strong&gt; Offline support, installable, background sync — works offline after first load&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desktop:&lt;/strong&gt; Electron 32 with hardening (contextIsolation, sandbox), auto-update, NSIS installer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Packaging:&lt;/strong&gt; Play Store via TWA (PWABuilder), Microsoft Store via MSIX — packagable from PWA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No backend required for core training. Team calls use BroadcastChannel for signaling — same origin cross-tab, no server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Voice &amp;amp; Team Calls — The Hard Part
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Client Calls (VoiceCallCenter)
&lt;/h3&gt;

&lt;p&gt;Level-based frequency to avoid spam — Lvl 1 no auto calls (focus tickets), Lvl 2 P1 critical only, scales to realistic MSP volume. Manual Call Now button always allowed.&lt;/p&gt;

&lt;p&gt;When incoming: ringtone via AudioContext oscillators (440Hz + 480Hz bandpass), vibration via navigator.vibrate, browser Notification if granted. Accept creates active call with transcript, Web Speech for client voice, hold music via oscillators.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crash I fixed:&lt;/strong&gt; &lt;code&gt;acceptCall&lt;/code&gt; had no try-catch around &lt;code&gt;speechSynthesis&lt;/code&gt; and &lt;code&gt;AudioContext&lt;/code&gt; — if browser blocks audio, page crashed with "This page couldn't load". Now wrapped in try-catch with fallback text mode, defensive &lt;code&gt;id?.[0]&lt;/code&gt; and &lt;code&gt;(transcript || []).map&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Team Calls (ClassCallDock + ClassCallCenter + classCallEngine)
&lt;/h3&gt;

&lt;p&gt;This is the flagship collaboration feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirement:&lt;/strong&gt; Team Lead can call agents in same class/workforce — like Teams/Slack. Same class code only (INFLUX-2026-A), presence, coaching, escalation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation:&lt;/strong&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
ts
// Signaling — no backend
const channel = new BroadcastChannel('orbitdesk-class-calls');
channel.postMessage({ type: 'call-offer', callId, classCode, from, to, payload });

// WebRTC — peer-to-peer audio
const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream.getTracks().forEach(track =&amp;gt; pc.addTrack(track, stream));
pc.onicecandidate = e =&amp;gt; {
  if (e.candidate) channel.postMessage({ type: 'ice-candidate', callId, candidate: e.candidate });
};

// Mock auto-answer 80% for demo (students s1-s4)
if (mockStudents.includes(to.id) &amp;amp;&amp;amp; Math.random() &amp;lt; 0.8) {
  setTimeout(() =&amp;gt; answerCall(callId), 1500 + Math.random() * 2000);
}
![ ](https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/9komhtg6ic7cmj8thr84.png)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>nextjs</category>
      <category>softwaredevelopment</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>OrbitDesk — How I Built a Modern Workplace Operations Lab with WebRTC Team Calls and No Backend</title>
      <dc:creator>Devine Nyaenya</dc:creator>
      <pubDate>Thu, 17 Sep 2026 18:37:38 +0000</pubDate>
      <link>https://dev.to/pubg_elitemaster_6e3596b/orbitdesk-how-i-built-a-modern-workplace-operations-lab-with-webrtc-team-calls-and-no-backend-2oj2</link>
      <guid>https://dev.to/pubg_elitemaster_6e3596b/orbitdesk-how-i-built-a-modern-workplace-operations-lab-with-webrtc-team-calls-and-no-backend-2oj2</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdwrtv30pm3ek29c1sqtd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdwrtv30pm3ek29c1sqtd.png" alt=" " width="799" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>microsoft365</category>
      <category>entraid</category>
      <category>intune</category>
      <category>helpdesk</category>
    </item>
  </channel>
</rss>
