Realtime samenwerking bouwen in je AI-gebouwde app (zonder andermans werk te breken)

Realtime samenwerking gaat mis zodra twee mensen tegelijk een app bewerken — de wijzigingen van de een verdwijnen stilletjes, worden overschreven, of spreken tegen wat de ander ziet. Drie foutpatronen en drie oplossingen, stap voor stap, lossen het op.

Wat gebeurt er als twee mensen tegelijk dezelfde app bewerken?

Realtime samenwerking voorkomt dat twee mensen elkaars werk overschrijven wanneer ze tegelijk dezelfde appdata bewerken — sla je dit over, dan kan de opslagactie van de tweede persoon die van de eerste stilletjes wissen. Zo zag dat eruit voor één team.

Een gebruiker bouwde samen met zijn team een gedeelde takenlijst. Vrijdagmiddag openden twee teamgenoten de lijst tegelijkertijd. Beiden zagen:

  • Taak 1: Boodschappen
  • Taak 2: Mama bellen
  • Taak 3: Vergadering plannen

Teamgenoot A vinkte “Boodschappen” af. Teamgenoot B voegde “Router repareren” toe. Beiden klikten op opslaan.

Toen Teamgenoot A ververste, zag die:

  • Taak 1: Boodschappen (afgevinkt)
  • Taak 2: Mama bellen
  • Taak 3: Vergadering plannen

“Router repareren” was verdwenen. Het werk van Teamgenoot B was weg.

Dit is een botsing: gelijktijdige schrijfacties, en het werk van één persoon verdwijnt. Het klinkt als een functie — het is eigenlijk een fix voor dataverlies. Zonder die fix breekt je app zodra twee mensen er tegelijk aan zitten.

Wat zijn de meest voorkomende bugs in realtime samenwerking?

Realtime samenwerking gaat op drie manieren stuk: een wijziging gaat stilletjes verloren, een scherm toont verouderde data, of twee mensen kijken uiteindelijk naar tegenstrijdige feiten. Elk uit zich anders, en elk heeft zijn eigen oplossing nodig.

Fout 1: De verloren wijziging (stille dataverlies)

Twee mensen slaan tegelijk op. De tweede opslagactie overschrijft de eerste. De tweede persoon ziet zijn wijziging landen, de eerste persoon ziet… niets. Of ze verversen en vragen zich af waar hun werk is gebleven.

Waargebeurd verhaal: Een bruiloftsplanner en haar assistente werken aan de gastenlijst. De assistente voegt drie RSVP’s toe terwijl de planner er twee als “definitief” markeert. De markeringen van de planner verdwijnen. Niemand merkt het totdat de planner tijdens vervolgtelefoontjes dubbel telt — en nu mensen uitnodigt die al hadden bevestigd.

De meeste echte apps lossen dit op door elke toetsaanslag op te slaan, niet alleen bij een klik op “Opslaan”. Google Sheets, Notion, Figma — ze doen het allemaal. Jouw app heeft dat gedrag ook nodig.

Fout 2: De verouderde ververing (oude data zien)

Persoon A bewerkt een taak. Persoon B heeft de pagina open en ziet de oude versie. Ze maken een wijziging op basis van de verouderde data. Nu is er een conflict dat voor hen onzichtbaar is.

Waargebeurd verhaal: Een schade-expert en een aannemer werken aan een claim. De expert past “geschatte reparatiekosten: $3K” aan naar “$5K” op basis van nieuwe foto’s. De pagina van de aannemer toont nog steeds $3K. Hij dient een goedkeuringsformulier in voor $3K. Later ontdekken ze het conflict.

Zonder realtime updates denken beide mensen dat ze aan dezelfde versie werken. Dat is niet zo.

Fout 3: De kettingreactie van tegenstrijdigheid (twee waarheden)

Een gebruiker verwijdert een record. Een andere gebruiker bekijkt op dat moment de details van dat record. De een ziet “verwijderd”, de ander ziet nog steeds het volledige record. Ze werken nu vanuit verschillende feiten.

Waargebeurd verhaal: Een vrijwilligerscoördinator markeert een dienst als “geannuleerd”. De vrijwilliger heeft nog niet ververst en ziet de dienst nog als “open”. Hij begint mensen te werven voor die dienst. Uren later staan er twee mensen klaar voor een dienst die nooit echt bestond.

Hoe los je bugs in realtime samenwerking op?

Los ze op in volgorde, één voor één: detecteer schrijfconflicten met incrementeel opslaan, voeg verversingen samen zonder lokale wijzigingen te verliezen, en laat conflicten daarna zien in plaats van ze te verbergen. Je hoeft realtime samenwerking niet meteen op dag één perfect op te lossen.

Oplossing 1: Detecteer schrijfconflicten (incrementeel opslaan)

Zorg dat elke wijziging direct wordt opgeslagen, niet pas bij een klik op “opslaan”. Dit is de belangrijkste fix.

Als de gebruiker een veld bewerkt, stuur die wijziging meteen naar je database. Toon een klein “opgeslagen”-icoontje of een puntje dat verdwijnt zodra de synchronisatie voltooid is. Als een tweede persoon op hetzelfde moment opslaat, zou je database dat zo moeten zien:

  • De wijziging van Persoon A komt als eerste binnen.
  • De wijziging van Persoon B komt als tweede binnen.
  • Persoon B wint (laatste wijziging telt).

Dit is bot maar eerlijk: minstens één persoon zal zien dat zijn wijziging niet is blijven staan, en die kan hem opnieuw doorvoeren.

Vraag aan de bouwer: Laat opslaan triggeren bij elke toetsaanslag, of nadat de gebruiker 2 seconden gestopt is met typen — niet via een “Opslaan”-knop. Toon een synchronisatie-indicator. Test het: open je app in twee browservensters en bewerk hetzelfde veld. De ene wijziging moet zichtbaar de andere overschrijven.

Oplossing 2: Verversen zonder lokale wijzigingen te verliezen

Als je elke 5 seconden de database polt (of updates pusht via WebSocket), voeg dan nieuwe data samen zonder de actuele bewerkingen van de gebruiker te verpletteren.

De verkeerde manier: De hele pagina herladen. Alle lokale wijzigingen zijn dan weg.

De juiste manier: Werk alleen velden bij waar de gebruiker niet actief mee bezig is. Typt iemand in de titel? Raak die dan niet aan. Raakt iemand de einddatum niet aan? Werk die dan bij vanaf de server.

Vraag aan de bouwer: Wanneer je verse data uit je database ophaalt, voeg die samen: behoud lokale wijzigingen, werk de rest bij. In een echt framework is dit meestal maar twee regels code. Test het: bewerk één veld in het ene venster, bewerk tegelijkertijd een ander veld in een tweede venster. Beide wijzigingen moeten overleven.

Oplossing 3: Toon de waarheid duidelijk

Als er een conflict is of verouderde data, laat dat zien. Verberg het niet.

Voorbeelden:

  • “Deze taak is door iemand anders verwijderd. Ongedaan maken?”
  • “Iemand heeft drie items aan deze lijst toegevoegd terwijl je aan het typen was. [Bekijk wat er nieuw is]”
  • “Je bekijkt een versie van 2 minuten geleden. Ververs om de nieuwste te zien.”

Vraag aan de bouwer: Controleer bij het laden of de data die je toont een tijdstempel heeft. Is die ouder dan 30 seconden en probeert de gebruiker te bewerken, toon dan een waarschuwing en haal de data opnieuw op. Toon je een lijst, geef dan een “Ververs”-knop die aanvoelt als een zinvolle actie van de gebruiker, niet als een foutmelding.

Hoe ziet realtime samenwerking eruit wanneer het volledig is opgelost?

De gouden standaard: jij en ik bewerken een gedeeld document, ik typ, jij ziet mijn cursor bewegen, en de tekst verschijnt direct op beide schermen zonder dat een van ons werk verliest. Daarvoor moeten drie dingen samenwerken:

  1. Elke toetsaanslag slaat direct op — wacht niet op een knop.
  2. Conflicten worden opgelost volgens een vaste regel — bewerken we allebei hetzelfde woord, dan kiest het systeem een winnaar (meestal telt de laatste wijziging, of je krijgt een conflictmelding).
  3. Updates komen direct binnen — WebSocket, Server-Sent Events, of een database die pusht (zoals Firebase).

De meeste apps hebben dit niet meteen op dag één nodig. Begin met incrementeel opslaan (Oplossing 1). Voeg polling + samenvoegen toe (Oplossing 2) zodra twee mensen de app tegelijk gebruiken. Voeg directe push alleen toe als conflicten echte pijn veroorzaken.

Hoe test je realtime samenwerking voordat je live gaat?

Draai drie tests in twee browservensters voordat je live gaat: een test voor gelijktijdig opslaan, een test voor verouderde data, en een verversingstest. Elke test heeft een duidelijke geslaagd-of-mislukt-uitslag.

Test 1: De test voor gelijktijdig opslaan

  • Open je app in twee browservensters.
  • Bewerk in venster 1 veld X en sla op.
  • Bewerk in venster 2 direct daarna veld Y en sla op.
  • Ververs beide vensters.
  • Geslaagd: Beide wijzigingen zijn aanwezig. Mislukt: Eén wijziging is verdwenen.

Test 2: De test voor verouderde data

  • Open de app in venster 1. Raak niets aan.
  • Verander in venster 2 iets groots (voeg een rij toe/verwijder er een, wijzig een titel).
  • Ga terug naar venster 1 (dat nog steeds de oude data toont).
  • Probeer de verouderde versie in venster 1 te bewerken.
  • Geslaagd: Je krijgt een waarschuwing of het wordt netjes samengevoegd. Mislukt: Je overschrijft de wijziging uit venster 2.

Test 3: De verversingstest

  • Heb betekenisvol werk in uitvoering (een half ingevuld formulier, een conceptbericht).
  • Ververs de pagina.
  • Geslaagd: Je werk staat er nog. Mislukt: Het is weg.

Moet je opslaan bij elke toetsaanslag, of wachten op een opslaanknop?

Sla op bij elke toetsaanslag. Die ene beslissing brengt je 80% van de weg naar realtime samenwerking — al het andere is het zichtbaar maken en het afhandelen van botsingen.

Gebruikers verwachten dit inmiddels. Gmail, Google Docs, Slack — elke moderne app doet het. Jouw app zou dat ook moeten doen.

Het eerste wat je moet doen: Zorg dat elke wijziging automatisch wordt opgeslagen. Toon een klein icoontje (“opslaan…” en dan weg). Kijk wat er gebeurt als twee mensen tegelijk bewerken. Verdwijnt de wijziging van iemand, dan is dat je volgende fix. Eén probleem tegelijk verslaat de poging om op dag één perfecte samenwerking te bouwen.