Skip to main content

Berichten, communicatie en notificaties

13.1 Doel

OefenHub kent meerdere communicatievormen die functioneel op elkaar kunnen lijken, maar als afzonderlijke domeinen worden behandeld.

Dit hoofdstuk beschrijft de samenhang en grenzen tussen:

  • mailbox-systeemberichten;
  • privéberichtthreads;
  • privéberichten;
  • threaddeelnemers;
  • thread-events binnen privéthreads;
  • ongelezenstatus en badges;
  • systeemnotificaties boven frontpages;
  • popupfeedback via popupregisterkeys;
  • realtime updates via SignalR of gelijkwaardige techniek.

Deze communicatievormen mogen in de gebruikersinterface gecombineerd zichtbaar zijn, maar blijven verschillende domeinen met eigen brondata, lifecycle, autorisatieregels en beheerbaarheid.

13.2 Communicatievormen

CommunicatievormBron / hoofdobjectFunctionele betekenis
Mailbox-systeemberichtSystemMessagesDoor het systeem aangemaakt bericht voor één gebruiker, vaak met verwijzing naar een domeinobject.
PrivéberichtthreadPrivateMessageThreadsConversatiecontainer voor privéberichten tussen toegestane deelnemers.
ThreaddeelnemerPrivateMessageThreadParticipantsParticipantgebonden zichtbaarheid, leesstatus en mailboxstatus.
PrivéberichtPrivateMessagesInhoudelijk bericht binnen een privéthread.
Thread-eventPrivateMessageThreadEventsSysteemachtige gebeurtenis binnen een privéthread, zoals onderwerpwijziging.
SysteemnotificatieSiteNotificationsTijdelijke of geplande sitebrede/doelgroepgerichte overlay boven een frontpage.
PopupfeedbackPopupregister / popupdetailsActie- of foutfeedback via popupkeys en centrale popupdefinities.
Realtime signaalSignalR / readmodelupdateTransportmechanisme voor snelle UI-updates; geen zelfstandige bron van waarheid.

13.3 Mailboxweergave

Het berichtenoverzicht combineert systeemberichten en privéberichtthreads in één gebruikergebonden mailboxweergave.

Deze mailboxweergave is een afgeleid readmodel en geen aparte bron van waarheid.

Per mailboxitem zijn minimaal zichtbaar:

  • type: Systeem of Privé;
  • afzender of systeembron;
  • verzenddatum, ontvangstmoment of laatste activiteit;
  • onderwerp;
  • preview;
  • gelezen/ongelezenstatus;
  • toegestane acties.

De mailbox ondersteunt:

  • typefilter;
  • statusfilter;
  • zoeken;
  • paginering met configureerbare paginagroottes;
  • samenvattingsblokken;
  • openen van een item;
  • markeren als gelezen of ongelezen;
  • verwijderen van privéthreads waar toegestaan.

Alle tellingen, badges, zoekresultaten en paginering worden server-side afgeleid uit de geautoriseerde mailboxdataset van de ingelogde gebruiker.

Een gebruiker mag via zoeken, filters, paginering, badges of directe routes geen mailboxitems van andere gebruikers zien.

Zoektermen, filterwaarden, statuswaarden, paginanummers en paginagroottes zijn user input. Zij worden server-side genormaliseerd en begrensd voordat zij invloed hebben op query's, readmodels of rendering.

Voor privéberichten toont het overzicht één mailboxitem per zichtbare privéthread. Meerdere berichten of replies binnen dezelfde thread leiden niet tot meerdere losse overzichtregels. Een nieuw privébericht buiten reply-context start een nieuwe thread en wordt daardoor een eigen overzichtregel. De mailboxweergave moet private threads kunnen samenvatten met meer dan twee deelnemers; een één-op-één-aanname is niet toegestaan.

Voor privéthreads toont de preview bij voorkeur het eerste voor de ingelogde gebruiker nieuwe bericht of de eerste nieuwe threadgebeurtenis. Als er geen nieuwe activiteit is, toont de preview de laatste zichtbare activiteit. Daarmee geeft het overzicht bij ongelezen threads het begin van wat de gebruiker nog niet heeft gelezen, en bij gelezen threads de meest recente context.

13.4 Systeemberichten

Systeemberichten zijn gebruikergebonden mailboxitems die door OefenHub worden aangemaakt.

Zij worden onder meer gebruikt voor:

  • relatie-uitnodigingen;
  • acceptatie of afwijzing van uitnodigingen;
  • ontkoppelingen;
  • meldingen en ticketupdates;
  • vragen om aanvullende informatie;
  • oplossing of sluiting van meldingen;
  • gedeelde oefeningen;
  • niveauautorisaties;
  • collaborator- of eigenaarschapswijzigingen;
  • beheerterugkoppelingen waar functioneel nodig.

Een systeembericht kan functioneel verwijzen naar een onderliggend domeinobject via:

  • EntityType;
  • EntityId.

De toegestane verwijstypen zijn functioneel afgebakend. Minimaal ondersteund zijn:

EntityTypeBetekenis
RelationshipInvitationVerwijzing naar een relatie-uitnodiging.
TicketVerwijzing naar een melding/ticket.
PrivateMessageThreadVerwijzing naar een privéberichtthread.

De frontend bepaalt op basis van EntityType, EntityId en actuele server-side autorisatie welke vervolgactie mogelijk is.

Losse database-URL’s zijn niet leidend voor systeemberichten. De combinatie EntityType + EntityId is een functionele domeinverwijzing, geen vrij te volgen URL.

Het openen van een systeembericht mag het bericht als gelezen markeren, maar verwerkt het onderliggende domeinobject niet automatisch.

Voorbeelden:

  • een relatie-uitnodiging wordt niet automatisch geaccepteerd door het bericht te openen;
  • een melding wordt niet automatisch heropend of geaccepteerd door het bericht te openen;
  • een gedeelde oefening wordt niet automatisch gestart door het bericht te openen.

Systeemberichten zijn niet door de gebruiker verwijderbaar. Zij blijven beschikbaar als gebruikergerichte systeemcommunicatie en lichte logging, tenzij later een afzonderlijke retentieregel wordt vastgesteld.

Systeemberichtinhoud wordt bij aanmaak als gerenderde tekst opgeslagen. De inhoud voor nieuwe systeemberichten komt uit codegedreven SystemMessageTemplates wanneer voor het scenario een template bestaat. Nieuwe flows voegen geen hardcoded systeemberichttitels of -body's in Web-services toe. Templatewijzigingen gelden alleen voor toekomstige berichten en herschrijven bestaande mailboxberichten niet. Runtime SystemMessages hoeven geen template- of templateversie-FK te bewaren.

Voor relatie-uitnodigingsfeedback aan de uitnodiger geldt een privacygrens: zolang de terugkoppeling gaat over de oorspronkelijke uitnodiging, gebruikt de melding primair het uitgenodigde e-mailadres en niet automatisch de profielnaam van de ontvanger. Na acceptatie mag de relatiepagina relatiepartnergegevens tonen volgens de normale relatie- en privacyregels.

13.5 Privéberichtthreads

Privéberichten worden georganiseerd in threads.

Een privéthread bestaat minimaal uit:

  • threadmetadata;
  • deelnemers;
  • privéberichten;
  • thread-events;
  • participantgebonden zichtbaarheid;
  • participantgebonden readstate.

Een privéberichtthread mag alleen worden gestart wanneer er op verzendmoment een geldige relatie-, vriendschaps- of systeemrelatiecontext bestaat die privécommunicatie toestaat.

Voorbeelden van toegestane contexten:

  • vrienden onder leerlingen;
  • ouder-/voogdrelatie waar privécommunicatie functioneel is toegestaan;
  • docentrelatie waar communicatie functioneel is toegestaan;
  • docent-docentrelatie;
  • beheerder-beheerderrelatie;
  • expliciet ondersteunde systeemflow, zoals doorzetten van een melding naar een docent namens een gebruiker.

Een zichtbare ontvanger in de UI is geen autorisatiebewijs. Bij verzenden controleert de backend opnieuw:

  • actor;
  • actieve accountstatus;
  • rolcontext;
  • relatie- of systeemrelatiecontext;
  • featurestatus;
  • ontvangerstatus;
  • thread- of participantcontext;
  • berichtvalidatie;
  • sanitizing van rich text.

Wanneer de relatie- of deelnemerscontext intussen vervallen is, wordt verzenden of beantwoorden geblokkeerd.

Privéthreads zijn niet beperkt tot één-op-één-gesprekken. De eerste UI mag klein beginnen, maar het functionele model, de readstate en de deelnemersweergave moeten 2+ deelnemers ondersteunen.

Een privéthread heeft een stabiele threadpresentatie: threadkleur en icon key worden bij aanmaak bepaald en door alle deelnemers gelijk gezien. Deelnemeraccenten zijn threadspecifiek en horen bij de participantregel, zodat deelnemers in groepsgesprekken herkenbaar blijven zonder de globale profielavatar te wijzigen.

Threadweergave als één tijdlijn

De detailweergave van een privéthread wordt functioneel behandeld als een gesprek en niet als een los ontvangen bericht met daaronder een aparte geschiedenis. De privéthreaddetailpagina toont daarom één chronologische tijdlijn van oud naar nieuw binnen het geladen venster.

De pagina mag automatisch naar het relevante punt in de tijdlijn springen:

  • naar de marker Nieuwe berichten wanneer er voor de ingelogde participant ongelezen activiteit bestaat;
  • naar het laatste zichtbare timeline-item wanneer er geen ongelezen activiteit bestaat.

Deze sprong gebruikt een pagina-anker zoals #new of #latest, omdat dit naar een echte locatie op de pagina verwijst. Dit is iets anders dan technische status-querystrings voor mutatiefeedback; die blijven ongewenst.

De tijdlijn bevat:

  • berichtballonnen voor privéberichten;
  • eigen berichten rechts, met de eigen participantkleur binnen de thread;
  • berichten van andere deelnemers links, met hun participantkleur binnen de thread;
  • compacte gecentreerde systeemachtige thread-events, zonder titelbalk of avatar;
  • een visuele marker Nieuwe berichten op de plek waar voor de gebruiker de nieuwe activiteit begint.

Wanneer een thread wordt geopend, wordt de relevante threadactiviteit voor de gebruiker als gelezen beschouwd. Het systeem probeert in de initiële scope niet te modelleren of de gebruiker binnen een lange thread elk individueel nieuw bericht daadwerkelijk heeft gezien. Eigen berichten of eigen thread-events tellen nooit als nieuw voor de actor zelf.

Threadpresentatie en deelnemeraccenten

Een privéthread krijgt bij aanmaak een stabiele visuele presentatie:

  • een threadkleur;
  • een icon key uit een beperkte, beheerde set;
  • optioneel later een gebruikersinstelbare afbeelding of aangepast icoon.

Deze waarden zijn threadeigenschappen. Alle deelnemers zien dus hetzelfde threadicoon en dezelfde threadkleur in het berichtenoverzicht en op de threaddetailpagina.

Daarnaast krijgt iedere deelnemer binnen een thread een threadspecifieke accentkleur. Die kleur hoort bij de participantregel, niet bij het globale gebruikersprofiel. Daardoor kan dezelfde gebruiker in verschillende threads een andere herkenningskleur krijgen zonder de centrale avatar- of profielkleur te wijzigen.

Voor groepsthreads wordt het mailboxlabel dynamisch bepaald:

  • twee actieve zichtbare deelnemers: Privégesprek;
  • meer dan twee actieve zichtbare deelnemers: Groepsgesprek.

Wanneer een groepsgesprek functioneel terugvalt naar twee actieve zichtbare deelnemers, mag het label weer Privégesprek worden. Het label is dus een readmodelwaarde, geen vaste threadtypekolom.

Oudere berichten laden zonder volledige refresh

Voor lange privé- en groepsthreads laadt de detailpagina niet onbeperkt alle historie. Initieel wordt een configureerbaar venster geladen. Oudere items worden via Eerdere berichten laden toegevoegd zonder volledige page refresh.

De cursor voor oudere items is opaque: gebruikers zien of wijzigen geen datum, item-id of paginanummer. De cursor is gekoppeld aan de thread, de ingelogde gebruiker en het oudste reeds geladen timeline-item. De server beschermt deze context cryptografisch met Data Protection of een gelijkwaardig mechanisme en controleert bij elk verzoek opnieuw participanttoegang. Daardoor kan een gemanipuleerde cursor geen inhoud uit een andere thread of van een andere gebruiker ontsluiten.

De client voegt oudere berichten bovenaan de timeline toe en behoudt de scrollpositie, zodat de gebruiker niet onverwacht verspringt.

13.6 Privéberichten

Een privébericht is een individueel bericht binnen een privéthread.

Privéberichten ondersteunen beperkte veilige opmaak. Vrije HTML, JavaScript, scripts, actieve inhoud en onveilige markup zijn niet toegestaan.

Rich text wordt server-side gesanitized vóór opslag of rendering.

Voor V1.0 gelden begrensde berichtgroottes. Het onderwerp van een privébericht mag maximaal 120 tekens bevatten. De zichtbare berichttekst mag na sanitizing maximaal 4.000 tekens bevatten. Wanneer rich text technisch als veilige HTML wordt opgeslagen, mag de genormaliseerde opgeslagen body maximaal 12 KiB zijn. Bij overschrijding blokkeert het systeem verzenden met gebruikersgerichte validatiefeedback; de frontend mag teller- of waarschuwingstekst tonen, maar de server-side grens blijft leidend.

Bijlagen vallen buiten de initiële scope, tenzij later als aparte requirement uitgewerkt.

Een privébericht kan in expliciet ondersteunde beheerprocessen namens een andere gebruiker worden verstuurd. Dit is geen algemene functie voor gewone eindgebruikers.

Voorbeeld:

  • bij het doorzetten van een melding naar een docent kan een privébericht namens de melder worden aangemaakt;
  • de UI toont dan een afwijkende afzenderweergave zoals OefenHub Beheerder (namens <gebruiker>);
  • deze namens-weergave geldt alleen voor dat specifieke bericht;
  • latere reguliere antwoorden in dezelfde thread krijgen weer hun eigen normale afzendercontext.

Privéberichten worden niet hard verwijderd per berichtactie van een gebruiker. Zichtbaarheid en verwijdering worden participantgebonden verwerkt via de threaddeelnemerlaag.

13.7 Threaddeelnemers en verwijderen

De participantlaag bepaalt per gebruiker:

  • deelname aan de thread;
  • zichtbaarheid in de eigen mailbox;
  • gelezen/ongelezenstatus;
  • verwijdering uit de eigen mailboxweergave;
  • readpositie.

Wanneer een gebruiker een privéthread verlaat en uit de eigen mailbox verwijdert:

  • verdwijnt het gesprek alleen uit de mailboxweergave van die gebruiker;
  • de thread wordt niet voor andere deelnemers verwijderd;
  • bestaande berichten blijven voor andere deelnemers zichtbaar zolang hun eigen zichtbaarheid en retentie dat toestaan;
  • er wordt een thread-event vastgelegd, zodat achterblijvende deelnemers in de timeline zien wie het gesprek heeft verlaten;
  • andere deelnemers kunnen blijven antwoorden zolang er minimaal één andere actieve deelnemer beschikbaar is;
  • als iemand alleen overblijft, is beantwoorden en onderwerp wijzigen niet meer mogelijk binnen dat gesprek en toont de UI een kindvriendelijke toelichting;
  • de verwijderende gebruiker ziet de thread niet meer in filters, zoekresultaten, paginering of badges.

Wanneer uiteindelijk geen enkele deelnemer nog functioneel zichtbaar of actief aan de thread deelneemt, mag de thread administratief als gesloten of niet-verder-bewerkbaar worden beschouwd volgens de berichtregels.

13.8 Thread-events

Thread-events zijn systeemachtige gebeurtenissen binnen een privéthread.

Voorbeelden:

  • onderwerp gewijzigd;
  • deelnemer toegevoegd;
  • deelnemer heeft thread verlaten;
  • systeemmatige contextregel binnen een thread.

Thread-events zijn:

  • geen SystemMessages;
  • geen gewone PrivateMessages;
  • onderdeel van de privéthreadtijdlijn;
  • zichtbaar als neutrale systeemachtige regel of ballon binnen de thread;
  • mogelijk relevant voor ongelezenstatus.

Een onderwerpwijziging bij beantwoorden wordt vastgelegd als thread-event en niet als los systeembericht of gewoon privébericht.

Thread-events na de laatst bekende leespositie kunnen een thread opnieuw ongelezen maken.

13.9 Gelezen, ongelezen en badges

Gelezen/ongelezenstatus wordt per gebruiker of participant bepaald.

Voor systeemberichten gebeurt dit via het gelezenmoment van het systeembericht.

Voor privéthreads gebeurt dit via participantgebonden readstate en relevante berichten of thread-events na de laatst bekende leespositie.

Headerbadges en tellers zijn afgeleide readmodelwaarden. Zij worden niet als aparte tellerwaarheid opgeslagen.

Tellerupdates worden afgeleid uit onder meer:

  • ongelezen systeemberichten;
  • privéthread-readstate;
  • nieuwe privéberichten;
  • thread-events;
  • participantzichtbaarheid;
  • mailboxfilters;
  • relatie- en objecttoegang.

Een badge is nooit autorisatiebewijs. Het openen van de mailbox of een detailitem controleert opnieuw server-side de actuele toegang.

Mailboxsamenvatting en headerbadge gebruiken dezelfde user-scoped ongelezenlogica. Verborgen, verwijderde of niet-toegankelijke participantthreads tellen niet mee voor de eigen badge. Tijdens verplichte onboarding wordt het berichtenicoon niet getoond; dit verandert de onderliggende readstate niet.

Een expliciete markeer-als-gelezen/ongelezenactie is een normale verwachte actie. Bij succes keert de gebruiker terug naar het berichtenoverzicht zonder blijvende succesmelding of statusquery. Alleen fout- of blokkadestatussen krijgen zichtbare feedback.

Wanneer een gebruiker een ongelezen privéthread opent vanuit het overzicht, bepaalt de weblaag eerst op basis van de huidige participant-readstate waar de marker Nieuwe berichten hoort. Daarna mag de thread als gelezen worden gemarkeerd en naar de detailroute met een pagina-anker zoals #new of #latest worden genavigeerd. Daardoor blijft het relevante startpunt bekend, terwijl headerbadge en detailweergave na de render dezelfde server-side tellerstand gebruiken.

13.10 Leerling tijdens actieve oefening

Tijdens een actieve leerling-oefenrun mag de webapp de leerling niet afleiden met communicatie die niet nodig is voor de oefening zelf.

Wanneer tijdens een oefening berichten, systeemberichten, relatie-uitnodigingen, meldingsterugkoppelingen of andere communicatiesignalen binnenkomen:

  • wordt de onderliggende data normaal opgeslagen;
  • wordt de ongelezenstatus normaal bijgewerkt;
  • worden benodigde systeemberichten of privéberichten aangemaakt;
  • worden badges of popupachtige signalen visueel verborgen of uitgesteld;
  • worden meldingsterugkoppelingen niet opdringerig getoond;
  • worden systeemnotificatie-overlays niet boven de oefening geplaatst;
  • wordt na afronding, onderbreking of verlaten van de oefening opnieuw beoordeeld wat zichtbaar moet zijn.

Deze anti-afleidingsregel beïnvloedt alleen de presentatie aan de leerling tijdens de actieve oefencontext. Zij mag geen berichten, systeemberichten, meldingen, relatie-uitnodigingen, readstates of auditinformatie verliezen.

13.11 Relatie-afhankelijke communicatie

Relatiebeheer bepaalt in veel gevallen of privécommunicatie is toegestaan.

Voor privéberichten geldt:

  • een nieuw privébericht vereist een actuele relatie- of systeemrelatiecontext;
  • beantwoorden vereist een geldige thread- en participantcontext;
  • beëindiging van een relatie verwijdert bestaande threads niet automatisch;
  • beëindiging van een relatie kan nieuwe communicatie blokkeren wanneer geen andere geldige context bestaat;
  • frontend-zichtbaarheid van een ontvanger of thread is geen autorisatiebewijs.

Relatie-uitnodigingen zelf worden niet als privéberichtthread opgeslagen. Zij worden als systeemberichten aangeboden wanneer een interne ontvanger beschikbaar is.

13.12 Meldingen en tickets

Het meldingen- of ticketsysteem gebruikt systeemberichten als mailboxkanaal voor ticketgerelateerde communicatie.

Voorbeelden:

  • melding aangemaakt;
  • aanvullende informatie gevraagd;
  • externe reactie geplaatst;
  • oplossing aangeboden;
  • melding gesloten;
  • melding heropend;
  • melding doorgezet naar docent.

Voor ticketgerelateerde systeemberichten geldt:

  • EntityType = Ticket;
  • EntityId verwijst naar het ticket;
  • het openen van het systeembericht opent hoogstens de relevante ticketcontext;
  • reageren, accepteren, heropenen of sluiten blijven aparte domeinacties;
  • externe ticketdiscussie blijft opgeslagen in het ticketdomein;
  • interne ticketdiscussie blijft uitsluitend beheerinformatie;
  • ticketdiscussie wordt niet als privébericht opgeslagen.

Wanneer een melding wordt doorgezet naar een docent, kan daarnaast een privébericht namens de melder aan de docent ontstaan. Dat is een expliciet ondersteunde beheerflow en geen generieke doorstuurfunctie voor gewone gebruikers.

13.13 Gedeelde oefeningen

Wanneer een leerling een oefening deelt met een vriend, kan de ontvanger via systeemcommunicatie geïnformeerd worden.

De systeemcommunicatie is alleen een ingang naar de gedeelde-oefeningcontext. Het lezen van het bericht:

  • start de gedeelde oefening niet automatisch;
  • maakt geen nieuwe run aan;
  • accepteert geen relatie;
  • wijzigt geen resultaatdata.

De feitelijke gedeelde-oefeningflow blijft onderdeel van het leerling- en oefenrundomein.

Voor gedeelde oefeningen gebruikt systeemcommunicatie de expliciete verwijzing EntityType = SharedExercise met EntityId naar het betreffende SharedExercises-record. Het openen van zo’n bericht opent hoogstens de toegestane gedeelde-oefeningcontext en start geen oefening, maakt geen ontvangerrun aan en wijzigt geen resultaatdata.

13.14 Systeemnotificaties

Systeemnotificaties zijn beheerbare, tijdelijke of geplande frontpage-overlays.

Zij zijn niet hetzelfde als:

  • mailbox-systeemberichten;
  • privéberichten;
  • popupregister-popups;
  • ticketdiscussieberichten;
  • relatie-uitnodigingen;
  • frontpagecontentblokken.

Systeemnotificaties worden beheerd via Site Instellingen en opgeslagen als sitebrede of doelgroepgerichte notificaties.

Minimale eigenschappen zijn:

  • doelgroep (AudienceType);
  • notificatietype (NotificationType);
  • titel;
  • tekst;
  • startmoment in UTC;
  • optioneel eindmoment in UTC;
  • weergaveregel (DisplayRule);
  • aanmaak- en wijzigingsinformatie;
  • history op wijzigingsniveau.

Voor gebruikersweergave gelden de volgende regels:

  • de frontpage laadt eerst normaal;
  • pas daarna controleert de applicatie of actieve notificaties getoond moeten worden;
  • systeemnotificaties blokkeren het laden van de frontpage niet;
  • er wordt maximaal één notificatie tegelijk getoond;
  • bij meerdere actieve notificaties wordt de oudste aangemaakte relevante notificatie eerst getoond;
  • na sluiten wordt direct gecontroleerd of nog een volgende actieve notificatie beschikbaar is;
  • Always wordt niet permanent als gezien geregistreerd;
  • OncePerBrowser wordt clientside op notificatie-id onderdrukt;
  • er komt geen server-side gebruikergebonden gezien-tabel.

Systeemnotificaties respecteren de actuele doelgroepcontext. Wanneer de rolcontext niet betrouwbaar kan worden bepaald, mag het systeem niet terugvallen naar een ruimere doelgroep zonder expliciete regel.

13.15 OncePerBrowser en browserregistratie

Voor notificaties met DisplayRule = OncePerBrowser gebruikt OefenHub een browserwaarde, cookie of vergelijkbare clientside opslag.

Deze browserwaarde:

  • bevat minimaal de notificatie-id of marker dat de notificatie in deze browser al is getoond of gesloten;
  • bevat geen persoonsgegevens;
  • bevat geen identity-providerinformatie;
  • bevat geen rol- of autorisatiedata;
  • is geen server-side bron van waarheid;
  • wordt niet gebruikt om rechten of doelgroepcontext te bepalen.

Een wijziging aan dezelfde notificatie doorbreekt de bestaande browsermarker niet automatisch. Wanneer gewijzigde of belangrijkere informatie opnieuw zichtbaar moet worden, publiceert beheer een nieuwe notificatie en beëindigt de oude.

13.16 Popups

Popups zijn gebruikersfeedback op concrete acties, validaties, bevestigingen of uitzonderingen.

Voor popupgedrag geldt:

  • usecases en schermdocumentatie verwijzen naar popupkeys;
  • popupteksten, knopteksten, inputlabels en themes worden niet per usecase gedupliceerd;
  • popupregister en popup-themes zijn leidend voor inhoud en presentatie;
  • autorisatiefouten mogen geen gevoelige inhoud lekken;
  • foutmeldingen tonen geen tokens, stacktraces, technische payloads of interne identifiers aan gewone gebruikers.

Systeemnotificaties gebruiken geen popupregister-popups. Zij worden weergegeven via een eigen frontpage-notificatiecomponent.

13.17 Realtime updates

Realtime updates verlopen via SignalR of een gelijkwaardige techniek wanneer deze invalidatielaag beschikbaar is.

Realtime transport kan worden gebruikt voor:

  • mailboxbadges;
  • ongelezenstatus;
  • systeemcommunicatie;
  • live meekijkupdates;
  • relatie- of berichtenfeedback;
  • notificatie van nieuwe relevante communicatie.

SignalR of realtime transport is geen bron van waarheid. De bron blijft:

  • SystemMessages;
  • privéberichtthreads en participants;
  • ticketdata;
  • relatiegegevens;
  • oefenrunvoortgang;
  • relevante readmodels.

Wanneer realtime updates niet aankomen, mag de brondata niet verloren gaan. Bij herladen, openen of opnieuw ophalen van de mailbox of betrokken pagina wordt de actuele server-side toestand opnieuw bepaald.

Voor de eerste Batch 4-baseline is navigatie/openen/opnieuw ophalen voldoende. User-scoped realtime invalidatie voor nieuw aangemaakte mailboxitems blijft een apart vervolgpunt en mag later niet de bestaande server-side readmodelwaarheid vervangen.

13.18 Retentie, cleanup en anonimisering

Privéberichten kennen binnen de initiële scope een bewaartermijn van drie maanden.

Deze bewaartermijn is een functionele hoofdlijn voor privéberichten en privéthreads. De exacte technische cleanup, jobplanning, backupretentie en fysieke verwijderstrategie horen in TO, SRS of beheerbeleid.

Voor berichtenretentie gelden functioneel minimaal de volgende regels:

OnderdeelFunctionele retentieregel
PrivéberichtinhoudValt onder de bewaartermijn van drie maanden, tenzij later documentatiebreed anders besloten wordt.
ThreadmetadataMag langer nodig zijn voor participantstatus, audit, verwijzingen of veilige cleanup, maar mag geen onnodige inhoud zichtbaar houden.
ParticipantzichtbaarheidVerwijderen door een gebruiker blijft participantgebonden. Cleanup mag zichtbaarheid voor een verwijderende deelnemer niet herstellen.
ReadstateGelezen/ongelezenstatus is participantgebonden en wordt niet gebruikt als zelfstandige retentiebron.
SysteemberichtenVolgen niet automatisch de privéberichtretentie. Zij blijven beschikbaar als systeemcommunicatie en gebruikersgerichte logging, tenzij later expliciet anders wordt vastgesteld.
Thread-eventsVolgen functioneel de threadlifecycle en kunnen meetellen voor ongelezenstatus zolang de thread zichtbaar is.
Namens-berichtenBlijven normale privéberichten binnen de thread, met extra afzenderweergave. Retentie volgt de privéberichtregels.

Bij accountanonimisering geldt:

  • mailboxtoegang van het geanonimiseerde account wordt beëindigd;
  • actieve privéberichtdeelname wordt beëindigd of niet langer autoriserend gemaakt;
  • andere deelnemers behouden hun eigen zichtbaarheid zolang hun eigen participantcontext en retentieregels dat toestaan;
  • historische afzender- of deelnemerweergave wordt waar nodig vervangen door een geanonimiseerde weergave;
  • systeemcommunicatie mag geen actuele persoonsgegevens van het geanonimiseerde account blijven tonen wanneer die niet functioneel noodzakelijk zijn.

Cleanup en retentie mogen geen autorisatie omzeilen, geen verborgen thread weer zichtbaar maken en geen inhoud tonen buiten de actuele participant- of mailboxcontext.

13.19 Lege toestanden en fouttoestanden

Lege toestanden zijn geldig wanneer de gebruiker toegang heeft tot de mailbox of communicatiecontext, maar er geen items zijn.

Voorbeelden:

  • geen berichten;
  • geen ongelezen berichten;
  • geen privéberichten;
  • geen systeemberichten;
  • geen zoekresultaten binnen de actieve filter;
  • geen toegestane ontvangers voor nieuw privébericht;
  • geen relevante systeemnotificatie.

Fouttoestanden ontstaan wanneer:

  • een bericht of thread niet bestaat;
  • een item niet toegankelijk is;
  • een thread participantgebonden verwijderd is;
  • een onderliggend domeinobject niet meer beschikbaar is;
  • een relatiecontext bij verzenden ontbreekt;
  • een berichtvalidatie faalt;
  • rich text niet veilig verwerkt kan worden;
  • een systeemnotificatie incompleet of ongeldig is.

Bij fouttoestanden wordt geen gedeeltelijke inhoud getoond buiten de toegestane context.

13.20 Gerelateerde bronverwijzingen

BronLink
Technisch Ontwerp — communicatieBerichten, systeemberichten, notificaties en privéthreads
Technisch Ontwerp — readmodels en badgesReadmodels, tellers, badges, caching en materialisatie
Technisch Ontwerp — background jobsBackground jobs, TickerQ en periodieke verwerking
Usecases — berichtenBerichten
UC-GEN-MSG-001 — Berichtenoverzicht bekijkenBerichtenoverzicht bekijken
UC-GEN-MSG-002 — Privébericht opstellen en verzendenPrivébericht opstellen en verzenden
UC-GEN-MSG-003 — Bericht openenBericht openen
UC-GEN-MSG-004 — Bericht beantwoordenBericht beantwoorden
UC-GEN-MSG-005 — Privéberichtthread verwijderenPrivéberichtthread verwijderen
Usecases — systeemnotificatiesSysteemnotificaties
UC-GEN-NOT-001 — Systeemnotificatie tonenSysteemnotificatie tonen
UC-GEN-NOT-002 — Systeemnotificatie sluitenSysteemnotificatie sluiten
UC-GEN-NOT-003 — Eenmalige systeemnotificatie verwerkenEenmalige systeemnotificatie verwerken
Schermdocumentatie — berichtenoverzichtBerichtenoverzicht
Schermdocumentatie — nieuw privéberichtNieuw privébericht
Schermdocumentatie — open berichtOpen bericht
Schermdocumentatie — beantwoord berichtBeantwoord bericht
Database-informatie — communicatie en notificatiesCommunicatie en notificaties
Database-informatie — configuratie en contentbeheerConfiguratie en contentbeheer
Ontwerpbron — popup-registerPopup-register
Ontwerpbron — popup-themesPopup-themes
Ontwerpbron — header, footer en navigatieHeader, footer en navigatie
FO — applicatieschil, header, footer en navigatieApplicatieschil, header, footer en navigatie
FO — relatiebeheerRelatiebeheer
FO — meldingen en ticketafhandelingMeldingen en ticketafhandeling
FO — popups, templates, features en systeemnotificatiesPopups, templates, features en systeemnotificaties
FO — live meekijkenLive meekijken