MySite

Hoe ik Teams niet maak (en ze toch ontstaan)

Het probleem is niet Teams maken

We wilden Teams voor lessen.

Dat klinkt simpel:

  • lees brondata
  • maak teams
  • voeg docenten en leerlingen toe
  • klaar

Maar in de praktijk werkt dat niet.

Want:

  • lessen zijn niet altijd volledig gepland
  • teams mogen niet direct zichtbaar zijn
  • Microsoft Graph is asynchroon
  • resources bestaan vaak nog niet of zijn niet klaar

Het echte probleem bleek niet te zijn:

“Hoe maak ik Teams?”

Maar:

“Hoe voorkom ik dat Teams te vroeg actief worden?”

Waarom standaard Teams niet werken

Als je een Team direct aanmaakt via de standaard Microsoft flows:

→ Team bestaat
→ Team is actief
→ gebruikers kunnen ermee werken

Voor onderwijs is dat ongewenst.

Een Team moet pas gebruikt worden als:

  • de docent er klaar voor is
  • de les daadwerkelijk gepland is

Dus het doel werd:

Teams bestaan, maar nog niet actief zijn

De truc: een Team niet direct maken

De oplossing zat niet in een instelling, maar in de volgorde van bouwen.

In plaats van direct een Team te maken:

  1. Maak een educationClass
  2. Laat Microsoft de onderliggende group creëren
  3. Voeg een owner toe
  4. Promoveer daarna pas naar een Team

Door deze volgorde ontstaat een Team dat niet meteen actief gebruikt wordt.

Het doel was dus niet:

Teams maken

Maar:

Controleren wanneer een Team “tot leven komt”

Van stappen naar state

De eerste aanpak was lineair:

maak → configureer → klaar

Maar dat werkt niet met een asynchrone API.

Dus ik ben het anders gaan bekijken:

Wat zou de situatie moeten zijn?

En:

Wat is de situatie nu?

Het verschil daartussen bepaalt de actie.

HelloID als intent engine

In mijn model doet HelloID slechts één ding:

Bepalen wat er moet gebeuren

Niet uitvoeren. Tenminste… niet altijd.

Het resultaat daarvan is een lijst acties:

CreateClass
AddOwnerToGroup
CreateTeamFromClass
Undelete

Azure Automation als uitvoerder

Kleine batches worden direct uitgevoerd in HelloID. Een HelloID script heeft een runtime van 30 seconden. Dat is prima — tot je bij de start van het schooljaar ineens 2500 teams moet maken.

Grotere batches worden offloaded naar Azure Automation.

Belangrijk detail:

Azure weet niet WAT er moet gebeuren

Alleen:

VOERT uit wat HelloID heeft bepaald

Deze scheiding maakt het systeem simpel en robuust.

Eerlijk is eerlijk: het idee om naar Azure te offloaden komt van Randolf, van Speyk. Ik sta hier letterlijk op de schouders van iemand anders.

De realiteit van Microsoft Graph

Microsoft Graph werkt niet synchroon.

Bijvoorbeeld:

Team creation → 202 Accepted

Dat betekent:

  • de resource bestaat nog niet volledig
  • volgende acties kunnen falen

Een lineair script kan daar niet mee omgaan.

Inactive Teams als uitgangspunt

Een belangrijk ontwerpdoel was:

Teams mogen niet direct actief zijn

Dit is geen bijeffect van de techniek. Dit is het doel van het ontwerp.

Deze aanpak zorgt daarvoor, maar introduceert een constraint:

  • Teams endpoint → kan geen members toevoegen
  • Groups endpoint → kan dat wel

Dus:

Group = primaire resource
Team  = laag erboven

Membership probleem

Dan volgt er nog een interessante situatie:

teams worden gemaakt vanuit docenten
een leerling kan in een team horen,
maar dat team bestaat alleen als er een docent is

De klassieke oplossing:

check eerst of team bestaat

Maar dat betekent:

  • extra calls
  • complexere logica
  • race conditions

De keuze: niet controleren

In plaats daarvan doe ik dit:

probeer toe te voegen
faalt het → volgende run probeert opnieuw

Dat voelt eerst fout.

Maar is het niet.

De fout is geen fout

De fout betekent:

desired state ≠ current state

En dus:

nog niet uitvoerbaar

Bij een volgende run:

state veranderd → actie lukt

Het systeem convergeert vanzelf.

En als een lesgroep nooit een docent krijgt, dan ontstaat er dus ook nooit een Team.

Waarom dit beter werkt

Door niet te controleren:

  • minder code
  • minder afhankelijkheden
  • minder timing issues

En belangrijker:

je blijft dicht bij het state model

Uiteindelijk inzicht

Veel systemen proberen fouten te voorkomen.

Maar in een asynchroon systeem kan dat niet.

Je kunt alleen zorgen dat fouten tijdelijk zijn.

Tot slot

Dit systeem maakt geen Teams.

Het bepaalt wanneer ze mogen bestaan.

En accepteert dat ze niet altijd meteen bestaan.

Soms zelfs dat ze nooit bestaan.

Dat voelt in het begin ongemakkelijk.

Maar levert uiteindelijk een systeem op dat zichzelf herstelt.

En dat is uiteindelijk robuuster dan elk perfect lineair script.

Als dit je nieuwsgierigheid triggert, vertel ik er graag meer over. De volledige documentatie en scripts deel ik liever niet publiek, maar in een 1‑op‑1 gesprek laat ik het graag zien. .