UC-GEN-MSG-002 — Privébericht opstellen en verzenden
1. Kerngegevens
| Veld | Waarde |
|---|---|
| Usecase-ID | UC-GEN-MSG-002 |
| Naam | Privébericht opstellen en verzenden |
| Domein | Berichten |
| Primaire actor | Ingelogde gebruiker |
| Secundaire actor(en) | Systeem, beoogde ontvanger, relatie- en autorisatieservice, realtime notificatiecomponent |
| Rolcontext | Iedere ingelogde rolcontext waarvoor privéberichten beschikbaar zijn; verzenden wordt server-side beperkt tot ontvangers waarmee de gebruiker op verzendmoment een geldige relatie-, vriendschaps- of expliciet toegestane deelnemerscontext heeft |
| Betrokken schermen | SCH-GEN-02 — Berichtenoverzicht, SCH-GEN-03 — Nieuw privébericht, SCH-GEN-04 — Open bericht |
| Gerelateerde usecases | UC-GEN-MSG-001 — Berichtenoverzicht bekijken; UC-GEN-MSG-003 — Bericht openen; UC-GEN-MSG-004 — Bericht beantwoorden |
| Primaire entiteiten | PrivateMessageThreads, PrivateMessageThreadParticipants, PrivateMessages, participant-readstate |
| Secundaire entiteiten / events | Users, UserRelationships, SiteFeatureToggles, PrivateMessageCreated, PrivateThreadReadStateChanged, MessageUnreadCountChanged, PrivateMessageSendFailed |
| Gerelateerde popups | POP-GEN-MSG-NO-RELATION, POP-GEN-MSG-SEND-FAILED |
| Popupregister | Ontwerpbronnen — Popup-register |
| MoSCoW | Must have |
2. Omschrijving
De gebruiker stelt vanuit het berichtenoverzicht een nieuw privébericht op voor een ontvanger die binnen de actuele relatiecontext bereikbaar is. De gebruiker kiest een ontvanger, vult een onderwerp en berichtinhoud in en verzendt het bericht. Het systeem controleert zowel bij het openen van het opstelproces als opnieuw op verzendmoment of privéberichten sitebreed beschikbaar zijn, of de gebruiker de ontvanger mag berichten en of de ingevoerde inhoud geldig en veilig verwerkbaar is.
Na succesvol verzenden ontstaat een nieuwe privéberichtthread of wordt een door de berichtenservice bepaalde geldige threadcontext gebruikt. In beide gevallen wordt het eerste bericht als PrivateMessages-record opgeslagen, worden de deelnemers vastgelegd of bijgewerkt via PrivateMessageThreadParticipants, en wordt de readstate zo ingesteld dat het bericht voor de verzender gelezen is en voor de ontvanger als nieuwe ongelezen activiteit meetelt.
Wanneer de ontvanger vóór verzending geen ongelezen berichten had, wordt de ongelezenbadge bij de eerstvolgende toegestane UI-update zichtbaar. Wanneer de ontvanger al ongelezen berichten had, wordt de teller opnieuw bepaald of opgehoogd volgens dezelfde server-side ongelezenlogica als het berichtenoverzicht. Voor leerlingen geldt dat deze badge tijdens een actieve oefenrun visueel verborgen of uitgesteld blijft; de onderliggende ongelezenstatus wordt wel normaal geregistreerd en na afronden of verlaten van de oefenrun opnieuw zichtbaar gemaakt wanneer het aantal groter is dan nul.
3. Scope
Deze usecase beschrijft:
- het starten van de nieuw-privéberichtflow vanuit het berichtenoverzicht;
- het opbouwen van de lijst met toegestane ontvangers;
- het selecteren van één ontvanger binnen een geldige relatie-, vriendschaps- of deelnemerscontext;
- het invoeren van onderwerp en berichtinhoud;
- het annuleren van het opstellen zonder opslag;
- het server-side valideren van ontvanger, relatiecontext, featurestatus, onderwerp en berichtinhoud;
- het server-side sanitizen van rich-textinhoud;
- het transactioneel aanmaken of gebruiken van de juiste privéthreadcontext;
- het opslaan van het nieuwe privébericht;
- het vastleggen of bijwerken van threaddeelnemers en readstate;
- het actualiseren van de ongelezenstatus en teller voor de ontvanger;
- het tijdelijk verborgen blijven van de leerlingbadge tijdens een actieve oefenrun;
- foutpaden voor ontbrekende relatie, ongeldige invoer, vervallen ontvangercontext en technische verzendfouten;
- popupverwijzingen naar centrale popupkeys.
Deze usecase beschrijft niet:
- het beantwoorden van een bestaande privéberichtthread;
- het openen van een systeembericht of privéthreaddetail;
- het markeren als gelezen of ongelezen vanuit het berichtenoverzicht;
- het verwijderen van privéthreads uit de eigen mailbox;
- het aanmaken of verwerken van systeemberichten;
- het doorsturen of namens iemand versturen vanuit meldingenbeheer;
- conceptopslag, bijlagen, groepsgesprekken of uitgebreid bijlagenbeleid;
- het beheren van relaties, vriendschappen, featuretoggles, systeemberichtsjablonen of popupdefinities;
- retentie, cleanup of archivering van privéberichten.
4. Pre-condities
| ID | Voorwaarde |
|---|---|
| PRE-001 | De gebruiker is ingelogd. |
| PRE-002 | De privéberichtenfunctionaliteit is sitebreed beschikbaar. |
| PRE-003 | De gebruiker opent de nieuw-privéberichtflow vanuit het berichtenoverzicht of via een route die naar dezelfde opstelpagina leidt. |
| PRE-004 | De backend kan bepalen welke gebruikers de ingelogde gebruiker op dat moment mag berichten. |
| PRE-005 | De ontvangerlijst wordt uitsluitend opgebouwd uit actieve relatie-, vriendschaps- of expliciet toegestane deelnemerscontexten. |
| PRE-006 | De gebruiker heeft minimaal één toegestane ontvanger of krijgt een niet-verzendbare toestand te zien. |
| PRE-007 | Onderwerp en berichtinhoud kunnen server-side gevalideerd, gesanitized en veilig opgeslagen worden. |
| PRE-008 | De berichtenservice kan transactioneel een threadcontext, deelnemersregels, berichtrecord en readstate verwerken. |
| PRE-009 | De realtime notificatiecomponent of een gelijkwaardig readmodel kan de ongelezenstatus na succesvolle opslag opnieuw laten bepalen. |
5. Post-condities
| ID | Resultaat |
|---|---|
| POST-001 | Bij annuleren is geen nieuwe privéthread, geen nieuw privébericht en geen nieuwe readstate-mutatie aangemaakt. |
| POST-002 | Bij succesvol verzenden bestaat een geldige PrivateMessageThreads-context voor de verzender en ontvanger. |
| POST-003 | Bij succesvol verzenden zijn de relevante PrivateMessageThreadParticipants-regels aanwezig voor verzender en ontvanger. |
| POST-004 | Bij succesvol verzenden is precies één nieuw PrivateMessages-record opgeslagen met de ingelogde gebruiker als reguliere verzender. |
| POST-005 | De leespositie van de verzender is bijgewerkt zodat het eigen verzonden bericht niet ongelezen blijft voor de verzender. |
| POST-006 | De ontvanger krijgt de nieuwe threadactiviteit als ongelezen in de eigen participant-readstate of in het daarvan afgeleide readmodel. |
| POST-007 | De ongelezenteller van de ontvanger kan opnieuw worden bepaald en wordt zichtbaar of bijgewerkt wanneer UI-context dat toestaat. |
| POST-008 | Wanneer de ontvanger leerling is en actief in een oefenrun zit, blijft de badge/teller visueel verborgen terwijl de ongelezenstatus server-side bewaard blijft. |
| POST-009 | Er wordt geen systeembericht aangemaakt voor een regulier nieuw privébericht. |
| POST-010 | Bij ontbrekende, vervallen of onvoldoende relatiecontext wordt geen thread en geen bericht opgeslagen. |
| POST-011 | Bij validatiefout wordt geen thread en geen bericht opgeslagen. |
| POST-012 | Bij technische verzendfout blijft de ingevoerde berichtinhoud beschikbaar in het formulier, zodat de gebruiker opnieuw kan proberen. |
| POST-013 | Er worden geen gegevens van niet-geautoriseerde gebruikers of niet-betrokken threads gelezen, gewijzigd of getoond. |
6. Trigger
De gebruiker kiest in SCH-GEN-02 — Berichtenoverzicht de actie Nieuw privébericht of opent een gelijkwaardige route waarmee de opstelpagina voor een nieuw privébericht wordt gestart.
7. Normale processtroom
| Stap | Actor | Scherm / component | Actie | Systeemrespons | Data / regel |
|---|---|---|---|---|---|
| 1 | Gebruiker | SCH-GEN-02 — Berichtenoverzicht | Kiest Nieuw privébericht. | Het systeem start de nieuw-privéberichtflow. | Actie is alleen functioneel bruikbaar wanneer privéberichten beschikbaar zijn. |
| 2 | Systeem | Backend | Controleert authenticatie en featurestatus. | Alleen bij geldige sessie en actieve privéberichtenfeature wordt de opstelpagina voorbereid. | Frontendzichtbaarheid is geen autorisatiebewijs. |
| 3 | Systeem | Backend | Bepaalt de toegestane ontvangers voor de gebruiker. | Alleen gebruikers binnen geldige relatie-, vriendschaps- of deelnemerscontext komen beschikbaar. | UserRelationships, relatietype, rolcontext en active-status zijn server-side leidend. |
| 4 | Systeem | SCH-GEN-03 — Nieuw privébericht | Toont het formulier met ontvangerselectie, onderwerp, berichtveld en acties. | De gebruiker kan een ontvanger kiezen en inhoud invoeren. | Alle zichtbare namen en voorbeeldwaarden zijn dynamische data. |
| 5 | Gebruiker | SCH-GEN-03 — Nieuw privébericht | Selecteert een ontvanger. | Het systeem bewaart de selectie in de schermstaat. | Selectie wordt bij verzenden opnieuw server-side gecontroleerd. |
| 6 | Gebruiker | SCH-GEN-03 — Nieuw privébericht | Vult onderwerp en berichtinhoud in. | Het formulier bewaart de invoer client-side tot verzenden of annuleren. | Niet-verzonden berichten worden binnen deze flow niet tussentijds opgeslagen. |
| 7 | Gebruiker | SCH-GEN-03 — Nieuw privébericht | Kiest Verstuur bericht. | Het systeem start de server-side verzendactie. | Frontendvalidatie is ondersteunend maar niet leidend. |
| 8 | Systeem | Backend | Controleert opnieuw authenticatie, featurestatus, ontvanger, relatie-/deelnemerscontext en verzendrecht. | Alleen wanneer alle controles slagen gaat de mutatie door. | Controle vindt plaats op verzendmoment. |
| 9 | Systeem | Backend | Valideert onderwerp en berichtinhoud. | Lege of ongeldige invoer blokkeert verzenden. | Na sanitizing moet berichtinhoud overblijven. |
| 10 | Systeem | Backend | Sanitized rich text en encodeert displaywaarden veilig. | Actieve inhoud wordt verwijderd of geweigerd volgens de veilige invoerregels. | Vrije HTML, JavaScript en inline eventhandlers zijn niet toegestaan. |
| 11 | Systeem | Backend | Bepaalt de threadcontext voor het nieuwe privébericht. | Er wordt een nieuwe privéthread aangemaakt of een geldige bestaande context gebruikt volgens de berichtenservice. | Threadcontext bevat uitsluitend de verzender en toegestane ontvanger(s) binnen deze flow. |
| 12 | Systeem | Backend | Legt deelnemers vast of werkt de participantcontext bij. | De verzender en ontvanger hebben elk een eigen PrivateMessageThreadParticipants-regel. | Participantstatus bepaalt eigen mailboxzichtbaarheid en readstate. |
| 13 | Systeem | Backend | Slaat het privébericht op. | Nieuw PrivateMessages-record ontstaat binnen de threadcontext. | SenderUserId is de ingelogde gebruiker; geen namens-verzending in deze flow. |
| 14 | Systeem | Backend | Werkt threadmetadata en leespositie van de verzender bij. | Het bericht geldt niet als ongelezen voor de verzender. | LastMessageAtUtc, preview/readmodel en eigen participant-readstate worden bijgewerkt. |
| 15 | Systeem | Backend / readmodel | Bepaalt ongelezenstatus voor de ontvanger. | De ontvanger krijgt nieuwe activiteit als ongelezen. | De ongelezenlogica is gebruikergebonden. |
| 16 | Systeem | Realtime notificatiecomponent | Publiceert relevante update voor de ontvanger. | De ontvangerbadge wordt zichtbaar of de bestaande teller wordt opnieuw bepaald/opgehoogd wanneer UI-context dat toestaat. | Voor leerlingen tijdens actieve oefenrun blijft de badge visueel verborgen. |
| 17 | Systeem | SCH-GEN-04 — Open bericht of bevestigde navigatie | Toont de verzonden context of navigeert naar de geopende thread. | De verzender ziet dat het bericht succesvol is verzonden. | Vervolgweergave toont uitsluitend geautoriseerde threadinhoud. |
8. Alternatieve en exceptionele processtromen
| ID | Vanaf stap | Situatie | Systeemgedrag | Popup / melding | Datamutatie |
|---|---|---|---|---|---|
| ALT-001 | 1-2 | De gebruiker is niet ingelogd. | Het systeem weigert toegang of leidt naar de loginflow. | Generieke autorisatiemelding of loginflow. | Geen. |
| ALT-002 | 2 | Privéberichtenfunctionaliteit is sitebreed uitgeschakeld. | De opstelpagina wordt niet geopend of het formulier wordt niet verzendbaar gemaakt. | Functionele melding; geen specifieke popupkey in deze usecase. | Geen. |
| ALT-003 | 3 | Er zijn geen toegestane ontvangers. | Het systeem toont een niet-verzendbare toestand met uitleg dat er geen geldige ontvangers beschikbaar zijn. | Geen verzendpopup vereist. | Geen. |
| ALT-004 | 4-5 | De ontvangerlijst bevat door timing een gebruiker die inmiddels niet meer bereikbaar is. | De backend blokkeert definitief op verzendmoment. | POP-GEN-MSG-NO-RELATION. | Geen thread, geen bericht. |
| ALT-005 | 5 | De gebruiker selecteert geen ontvanger. | Verzenden wordt geblokkeerd met veldvalidatie. | Inline validatie. | Geen. |
| ALT-006 | 6-9 | Onderwerp is leeg of ongeldig. | Verzenden wordt geblokkeerd; invoer blijft zichtbaar. | Inline validatie. | Geen. |
| ALT-007 | 6-9 | Berichtinhoud is leeg of na sanitizing leeg. | Verzenden wordt geblokkeerd; invoer blijft zichtbaar. | Inline validatie. | Geen. |
| ALT-008 | 8 | De relatie, vriendschap of deelnemerscontext is vervallen sinds openen van het formulier. | Het systeem weigert verzenden. | POP-GEN-MSG-NO-RELATION. | Geen. |
| ALT-009 | 8 | De verzender mag de gekozen ontvanger niet meer berichten door gewijzigde rolcontext of autorisatie. | Het systeem weigert verzenden. | POP-GEN-MSG-NO-RELATION. | Geen. |
| ALT-010 | 10 | Berichtinhoud bevat niet-toegestane actieve inhoud. | De inhoud wordt veilig gesanitized; als geen geldige inhoud overblijft wordt verzenden geblokkeerd. | Inline validatie of functionele melding. | Geen bij blokkade. |
| ALT-011 | 11-14 | Databasefout tijdens thread-, participant-, bericht- of readstate-mutatie. | De volledige transactie wordt teruggedraaid. | POP-GEN-MSG-SEND-FAILED. | Geen gedeeltelijke mutatie. |
| ALT-012 | 16 | Realtime notificatie kan niet direct worden afgeleverd. | Het bericht blijft opgeslagen; ongelezenstatus blijft via database/readmodel correct. | Geen blocking popup voor verzender; technische logging. | Berichtmutatie blijft bestaan. |
| ALT-013 | 16 | Ontvanger is leerling en zit in een actieve oefenrun. | Het systeem registreert ongelezenstatus normaal, maar toont de badge visueel niet zolang de oefenrun actief is. | Geen popup. | Ongelezenstatus blijft bestaan. |
| ALT-014 | 17 | De verzender verlaat de pagina direct na succesvol verzenden. | Het verzonden bericht blijft opgeslagen. | Geen. | Geen aanvullende mutatie. |
| ALT-015 | 6 | De gebruiker kiest Annuleren. | De opstelpagina wordt verlaten zonder opslag. | Geen popup vereist. | Geen thread, geen bericht, geen readstate-mutatie. |
8.1 Threadpresentatie bij aanmaken
Bij het starten van een nieuwe privéthread genereert het systeem naast de thread en participants ook de vaste threadpresentatie:
- een threadkleur uit een veilige, beperkte palette;
- een
IconKeyuit een beheerde iconenset; - een threadspecifieke participantkleur voor iedere deelnemer.
De threadkleur en IconKey horen bij de thread en worden door alle deelnemers hetzelfde gezien. De participantkleur hoort bij de deelnemer binnen deze thread en mag verschillen van de globale profiel- of avatarkleur. De gebruiker kan deze waarden in Batch 6 nog niet zelf aanpassen; het threadmenu wordt wel voorbereid op latere opties zoals onderwerp wijzigen, mensen toevoegen en afbeelding/icoon aanpassen.
Het onderwerp aanpassen bij bestaande threads hoort niet als vrij veld in elke replyflow te blijven hangen. De detailpagina krijgt een threadmenu waarmee onderwerpwijziging als aparte actie kan worden uitgevoerd en als thread-event zichtbaar wordt in de timeline.
9. Business rules
| ID | Regel |
|---|---|
| BR-UC-GEN-MSG-002-001 | Een nieuw privébericht mag alleen worden opgesteld door een ingelogde gebruiker. |
| BR-UC-GEN-MSG-002-002 | Privéberichten moeten sitebreed beschikbaar zijn op het moment dat de opstelpagina wordt gebruikt en op het moment van verzenden. |
| BR-UC-GEN-MSG-002-003 | De ontvangerlijst mag alleen gebruikers bevatten die de verzender volgens actuele relatie-, vriendschaps- of deelnemersregels mag berichten. |
| BR-UC-GEN-MSG-002-004 | De backend controleert op verzendmoment opnieuw of de gekozen ontvanger nog geldig en bereikbaar is. |
| BR-UC-GEN-MSG-002-005 | Een gebruiker mag geen privébericht sturen aan een willekeurige gebruiker buiten een geldige relatiecontext. |
| BR-UC-GEN-MSG-002-006 | Verzenden mag niet slagen zonder gekozen ontvanger, onderwerp en geldige berichtinhoud. |
| BR-UC-GEN-MSG-002-007 | Rich-textinhoud wordt server-side gesanitized voordat deze wordt opgeslagen of gerenderd. |
| BR-UC-GEN-MSG-002-008 | Een regulier nieuw privébericht wordt opgeslagen als PrivateMessages-record binnen een privéthreadcontext. |
| BR-UC-GEN-MSG-002-009 | De verzender en ontvanger krijgen elk een eigen participantcontext voor mailboxzichtbaarheid en readstate. |
| BR-UC-GEN-MSG-002-010 | De leespositie van de verzender wordt na succesvol verzenden bijgewerkt zodat het eigen bericht niet ongelezen blijft voor de verzender. |
| BR-UC-GEN-MSG-002-011 | Het nieuwe bericht telt voor de ontvanger als ongelezen activiteit totdat de ontvanger de thread opent of expliciet als gelezen markeert. |
| BR-UC-GEN-MSG-002-012 | De ongelezenteller van de ontvanger wordt na succesvol verzenden opnieuw bepaald of geactualiseerd. |
| BR-UC-GEN-MSG-002-013 | Wanneer het ongelezenaantal van de ontvanger van nul naar groter dan nul gaat, moet de badge zichtbaar kunnen worden zodra de UI-context dat toestaat. |
| BR-UC-GEN-MSG-002-014 | Voor leerlingen tijdens een actieve oefenrun blijft de badge/teller visueel verborgen, terwijl de onderliggende ongelezenstatus server-side behouden blijft. |
| BR-UC-GEN-MSG-002-015 | Alle mutaties voor threadcontext, participants, bericht, threadmetadata en readstate worden transactioneel verwerkt. |
| BR-UC-GEN-MSG-002-016 | Annuleren maakt geen thread, bericht of readstate-mutatie aan. |
| BR-UC-GEN-MSG-002-017 | Gewone nieuwe privéberichten maken geen systeembericht aan. |
| BR-UC-GEN-MSG-002-018 | Technische identifiers, stacktraces en interne foutdetails worden niet zichtbaar getoond bij verzendfouten of autorisatieblokkades. |
| BR-UC-GEN-MSG-002-019 | Doorsturen, namens iemand versturen, bijlagen en conceptopslag vallen buiten deze reguliere nieuw-privéberichtflow. |
Centrale business rules die hierbij horen:
| BusinessRule-ID | Toepassing |
|---|---|
BR-GEN-SEC-001 | Alle berichtacties vereisen server-side rol-, relatie- of objectcontrole. |
BR-GEN-MSG-004 | Gelezen- en ongelezenstatus wordt gebruiker- of participantgebonden bepaald. |
BR-GEN-MSG-006 | Berichtinhoud en rich text worden veilig verwerkt voordat deze worden opgeslagen of weergegeven. |
BR-GEN-MSG-015 | Een verzendactie voor een privébericht wordt transactioneel verwerkt. |
BR-GEN-MSG-016 | Nieuwe privéberichten mogen alleen naar ontvangers binnen een geldige relatie-, vriendschaps- of deelnemerscontext worden verzonden. |
BR-GEN-MSG-017 | Nieuwe privéberichten actualiseren de ongelezenstatus van de ontvanger, maar de leerlingbadge blijft tijdens een actieve oefenrun visueel verborgen. |
10. Datavalidatie
| Veld / object | Validatie |
|---|---|
| Route naar nieuw privébericht | Mag nooit als autorisatiebewijs worden gebruikt; server-side controle blijft verplicht. |
SiteFeatureToggles.PrivateMessagingEnabled | Moet actief zijn bij openen en bij verzenden. |
| Ontvangerselectie | Verplicht; ontvanger moet bestaan en op verzendmoment bereikbaar zijn voor de verzender. |
ReceiverUserId | Mag niet willekeurig worden opgegeven; moet overeenkomen met een server-side toegestane ontvanger. |
| Relatie- of deelnemerscontext | Moet op verzendmoment privécommunicatie tussen verzender en ontvanger toestaan. |
| Rolcontext verzender | Moet passen bij de relatie- of deelnemerscontext waarmee de ontvanger bereikbaar is. |
| Onderwerp | Verplicht bij verzenden; veilig encoden bij weergave; lengtebegrenzing moet in TO/SRS technisch worden vastgelegd. |
| Berichtinhoud | Verplicht; na sanitizing moet inhoud overblijven. |
| Rich-text opmaak | Alleen veilige, beperkte opmaak is toegestaan; actieve inhoud wordt verwijderd of geweigerd. |
PrivateMessageThreads | Threadcontext mag alleen deelnemers bevatten die volgens deze flow betrokken zijn. |
PrivateMessageThreadParticipants | Moet per betrokken gebruiker een eigen participantregel hebben voor mailboxzichtbaarheid en readstate. |
PrivateMessages.ThreadId | Moet verwijzen naar de aangemaakte of gebruikte threadcontext. |
PrivateMessages.SenderUserId | Moet de ingelogde gebruiker zijn voor reguliere nieuwe privéberichten. |
PrivateMessages.Body | Wordt uitsluitend opgeslagen na server-side validatie en sanitizing. |
| Verzender-readstate | Mag alleen voor de eigen participantregel worden bijgewerkt. |
| Ontvanger-readstate | Mag nieuwe activiteit als ongelezen laten meetellen, maar niet namens de ontvanger als gelezen markeren. |
| Ongelezenteller | Wordt afgeleid uit dezelfde server-side ongelezenlogica als het berichtenoverzicht. |
| Leerlingbadge tijdens actieve oefenrun | Alleen de zichtbaarheid van de badge wordt onderdrukt; de readstate en tellerbron blijven intact. |
| Datum- en tijdwaarden | Worden in UTC opgeslagen en lokaal weergegeven. |
| Foutmeldingen | Mogen geen technische identifiers, stacktraces of interne databasenaamgeving bevatten. |
11. Datamutaties en events
| Stap | Type | Entiteit / event | Mutatie |
|---|---|---|---|
| 2-3 | Read | SiteFeatureToggles, Users, UserRelationships | Ophalen van featurestatus en toegestane ontvangers voor de ingelogde gebruiker. |
| 4-6 | Geen opslag | Formulierstaat | Invoer wordt alleen in de schermstaat bewaard tot verzenden of annuleren. |
| 8 | Read | UserRelationships, ontvangercontext, featurestatus | Controleren of verzenden op dit moment toegestaan is. |
| 11 | Database | PrivateMessageThreads | Nieuwe threadcontext aanmaken of geldige threadcontext bepalen volgens de berichtenservice. |
| 12 | Database | PrivateMessageThreadParticipants | Participantregels voor verzender en ontvanger aanmaken of actualiseren voor mailboxzichtbaarheid en readstate. |
| 13 | Database | PrivateMessages | Nieuw privébericht opslaan met verzender, thread, onderwerp-/threadcontext, body en verzendmoment. |
| 13 | Event | PrivateMessageCreated | Nieuw privébericht is succesvol opgeslagen. |
| 14 | Database | PrivateMessageThreads | Threadmetadata zoals laatste activiteit en preview/readmodelgegevens bijwerken. |
| 14 | Database | PrivateMessageThreadParticipants | Leespositie van de verzender bijwerken. |
| 14 | Event | PrivateThreadReadStateChanged | Verzender-readstate is bijgewerkt na verzenden. |
| 15 | Database / readmodel | PrivateMessageThreadParticipants of afgeleid readmodel | Ontvanger krijgt nieuwe activiteit als ongelezen. |
| 16 | Event | MessageUnreadCountChanged | Ongelezenteller van de ontvanger kan realtime worden geactualiseerd. |
| ALT-008 | Event / logging | PrivateMessageSendFailed | Verzending is functioneel geblokkeerd door vervallen relatie- of deelnemerscontext. |
| ALT-011 | Event / logging | PrivateMessageSendFailed | Verzending is technisch mislukt; transactie is teruggedraaid. |
12. Geen datamutaties
| Entiteit | Reden |
|---|---|
SystemMessages | Gewone nieuwe privéberichten maken of wijzigen geen systeemberichten. |
SystemMessageTemplates | De nieuw-privéberichtflow gebruikt geen systeemberichtsjabloon. |
PrivateMessageThreadEvents | In deze usecase wordt geen onderwerpwijziging binnen een bestaande thread verwerkt; thread-events horen bij andere flows zoals beantwoorden. |
PrivateMessages bestaande records | Bestaande berichten worden niet gewijzigd. |
PrivateMessageThreadParticipants van niet-betrokken gebruikers | Alleen deelnemers aan de nieuwe of gebruikte threadcontext worden geraakt. |
Users | Gebruikersgegevens worden alleen gelezen voor ontvangerselectie en display. |
UserRelationships | Relaties worden alleen gecontroleerd; deze usecase maakt, wijzigt of beëindigt geen relatie. |
Tickets | Een nieuw privébericht maakt geen melding of ticket aan. |
RelationshipInvitations | Een nieuw privébericht verwerkt geen relatie-uitnodiging. |
SiteFeatureToggles | Featurestatus wordt alleen gelezen. |
| Concept- of bijlage-entiteiten | Conceptopslag en bijlagen vallen buiten de eerste reguliere privéberichtflow. |
13. State diagram — nieuw privébericht en ongelezenstatus
14. Decision flow — privébericht opstellen en verzenden
15. Data lifecycle diagram — nieuw privébericht
16. Sequence diagrammen
16.1 Opstelpagina openen
16.2 Nieuw privébericht succesvol verzenden
16.3 Verzenden geblokkeerd door ontbrekende relatiecontext
16.4 Ontvanger is leerling tijdens actieve oefenrun
17. Popupverwijzingen
| PopupKey | Moment | Variant | Doel |
|---|---|---|---|
POP-GEN-MSG-NO-RELATION | Verzenden wordt geblokkeerd omdat de gekozen ontvanger niet langer binnen een geldige relatie- of deelnemerscontext valt. | InfoOnly | Uitleggen dat het bericht niet verstuurd kan worden omdat de gebruiker de gekozen persoon niet meer mag berichten. |
POP-GEN-MSG-SEND-FAILED | Verzenden mislukt door een technische of transactionele fout. | InfoOnly | Uitleggen dat het bericht niet is verzonden en dat de gebruiker opnieuw kan proberen zonder de ingevoerde tekst kwijt te raken. |
18. Afleiding naar Functioneel Ontwerp / Technisch Ontwerp / Software Requirements Specification
| Doeldocument | Afleiding |
|---|---|
| Functioneel Ontwerp | Beschrijft dat de actie Nieuw privébericht vanuit het berichtenoverzicht naar een zelfstandige opstelpagina leidt met ontvangerselectie, onderwerp, berichtinhoud, verzenden en annuleren. |
| Functioneel Ontwerp | Beschrijft dat de ontvangerlijst alleen toegestane gekoppelde gebruikers, vrienden of expliciet ondersteunde deelnemerscontexten bevat. |
| Functioneel Ontwerp | Beschrijft dat verzenden opnieuw server-side controleert of de ontvanger nog bereikbaar is en dat vervallen relatiecontext POP-GEN-MSG-NO-RELATION gebruikt. |
| Functioneel Ontwerp | Beschrijft dat de ongelezenteller bij de ontvanger zichtbaar wordt of wordt bijgewerkt, maar dat de leerlingbadge tijdens een actieve oefenrun tijdelijk verborgen blijft. |
| Technisch Ontwerp | Technisch Ontwerp: berichten, systeemberichten, notificaties en privéthreads beschrijft het command SendPrivateMessage uit met server-side controle op authenticatie, featuretoggle, ontvanger, relatie-/deelnemerscontext, onderwerp en berichtinhoud. |
| Technisch Ontwerp | Technisch Ontwerp: berichten, systeemberichten, notificaties en privéthreads beschrijft de transactionele verwerking voor threadcontext, participantregels, PrivateMessages, threadmetadata, readstate en eventpublicatie. |
| Technisch Ontwerp | Technisch Ontwerp: berichten, systeemberichten, notificaties en privéthreads beschrijft dat rich-textinhoud server-side wordt gesanitized en dat na sanitizing geldige inhoud moet overblijven. |
| Technisch Ontwerp | Technisch Ontwerp: readmodels, tellers, badges, caching en materialisatie beschrijft hoe het afgeleide readmodel en MessageUnreadCountChanged omgaan met het zichtbaar worden of actualiseren van de badge bij de ontvanger. |
| Technisch Ontwerp | Technisch Ontwerp: readmodels, tellers, badges, caching en materialisatie beschrijft dat leerlingbadge-onderdrukking tijdens een actieve oefenrun uitsluitend UI-zichtbaarheid raakt en geen readstate of berichtenopslag wijzigt. |
| Software Requirements Specification | Neem de requirements uit deze usecase op als testbare functionele requirements zonder acceptatiecriteria in de usecase te dupliceren. |
| Database-informatie | Bevat de datamodelbasis waarmee 04_communicatie-en-notificaties.md expliciet genoeg beschrijft hoe nieuwe privéthreads, participants, berichten, readstate en ongelezenafleiding worden opgeslagen. |
19. SRS-trace
Deze usecase bevat geen normatieve requirementtekst. De centrale eis en acceptatiecriteria staan in de SRS; onderstaande tabel koppelt de usecase-afleiding alleen aan centrale SRS-*- en AC-*-items.
| Usecase-afleiding | Dekt | Usecasecontext |
|---|---|---|
REQ-UC-GEN-MSG-002-001 | SRS-MSG-001 AC-MSG-001 | Een ingelogde gebruiker een nieuw privébericht kunnen laten opstellen wanneer privéberichten sitebreed beschikbaar zijn |
REQ-UC-GEN-MSG-002-002 | SRS-RDM-001 SRS-RDM-007 SRS-MSG-001 AC-RDM-001 AC-RDM-007 AC-MSG-001 | De actie Nieuw privébericht vanuit het berichtenoverzicht kunnen starten |
REQ-UC-GEN-MSG-002-003 | SRS-AUTH-001 SRS-RDM-001 SRS-RDM-007 SRS-MSG-007 AC-AUTH-001 AC-RDM-001 AC-RDM-007 AC-MSG-007 | Bij openen van de opstelpagina server-side controleren of de gebruiker privéberichten mag gebruiken |
REQ-UC-GEN-MSG-002-004 | SRS-RDM-001 SRS-RDM-007 SRS-REL-001 SRS-MSG-002 SRS-SHR-001 AC-RDM-001 AC-RDM-007 AC-REL-001 AC-MSG-002 AC-SHR-001 | De ontvangerlijst opbouwen uit gebruikers binnen een geldige relatie-, vriendschaps- of deelnemerscontext |
REQ-UC-GEN-MSG-002-005 | SRS-MSG-002 SRS-SHR-001 AC-MSG-002 AC-SHR-001 | Geen willekeurige gebruikers buiten de toegestane ontvangercontext beschikbaar maken als ontvanger |
REQ-UC-GEN-MSG-002-006 | SRS-MSG-002 SRS-SHR-001 AC-MSG-002 AC-SHR-001 | Een niet-verzendbare toestand tonen wanneer er geen toegestane ontvangers beschikbaar zijn |
REQ-UC-GEN-MSG-002-007 | SRS-MSG-002 SRS-SHR-001 AC-MSG-002 AC-SHR-001 | Een ontvanger, onderwerp en berichtinhoud vragen voordat verzenden mogelijk is |
REQ-UC-GEN-MSG-002-008 | SRS-MSG-001 AC-MSG-001 | Annuleren kunnen verwerken zonder thread, bericht of readstate-mutatie op te slaan |
REQ-UC-GEN-MSG-002-009 | SRS-MSG-002 SRS-SHR-006 AC-MSG-002 AC-SHR-006 | Op verzendmoment opnieuw controleren of de gekozen ontvanger nog toegestaan is |
REQ-UC-GEN-MSG-002-010 | SRS-AUTH-001 SRS-REL-001 SRS-MSG-002 AC-AUTH-001 AC-REL-001 AC-MSG-002 | Verzenden blokkeren en POP-GEN-MSG-NO-RELATION tonen wanneer de relatie- of deelnemerscontext niet meer geldig is |
REQ-UC-GEN-MSG-002-011 | SRS-AUTH-001 SRS-MSG-001 AC-AUTH-001 AC-MSG-001 | Onderwerp en berichtinhoud server-side valideren voordat een privébericht wordt opgeslagen |
REQ-UC-GEN-MSG-002-012 | SRS-AUTH-001 SRS-MSG-001 SRS-NFR-SEC-001 AC-AUTH-001 AC-MSG-001 AC-NFR-SEC-001 | Rich-text berichtinhoud server-side sanitizen voordat deze wordt opgeslagen of gerenderd |
REQ-UC-GEN-MSG-002-013 | SRS-AUTH-001 SRS-MSG-002 AC-AUTH-001 AC-MSG-002 | Verzenden blokkeren wanneer na sanitizing geen geldige berichtinhoud overblijft |
REQ-UC-GEN-MSG-002-014 | SRS-MSG-002 AC-MSG-002 | Bij succesvol verzenden een geldige privéthreadcontext aanmaken of gebruiken |
REQ-UC-GEN-MSG-002-015 | SRS-MSG-002 SRS-SHR-001 AC-MSG-002 AC-SHR-001 | Bij succesvol verzenden participantregels voor verzender en ontvanger aanmaken of actualiseren |
REQ-UC-GEN-MSG-002-016 | SRS-MSG-002 AC-MSG-002 | Bij succesvol verzenden precies één nieuw PrivateMessages-record opslaan voor het nieuwe bericht |
REQ-UC-GEN-MSG-002-017 | SRS-MSG-001 AC-MSG-001 | Reguliere nieuwe privéberichten opslaan met de ingelogde gebruiker als verzender |
REQ-UC-GEN-MSG-002-018 | SRS-MSG-002 AC-MSG-002 | Na succesvol verzenden de threadmetadata bijwerken |
REQ-UC-GEN-MSG-002-019 | SRS-MSG-006 AC-MSG-006 | Na succesvol verzenden de leespositie van de verzender bijwerken zodat het eigen bericht niet ongelezen blijft |
REQ-UC-GEN-MSG-002-020 | SRS-MSG-006 SRS-SHR-001 AC-MSG-006 AC-SHR-001 | Na succesvol verzenden de nieuwe activiteit als ongelezen laten meetellen voor de ontvanger |
REQ-UC-GEN-MSG-002-021 | SRS-RDM-001 SRS-RDM-002 SRS-MSG-006 SRS-SHR-006 AC-RDM-001 AC-RDM-002 AC-MSG-006 AC-SHR-006 | Na succesvol verzenden de ongelezenteller van de ontvanger opnieuw kunnen bepalen of actualiseren |
REQ-UC-GEN-MSG-002-022 | SRS-RDM-001 SRS-RDM-002 SRS-MSG-006 SRS-SHR-001 AC-RDM-001 AC-RDM-002 AC-MSG-006 AC-SHR-001 | De badge bij de ontvanger zichtbaar kunnen maken wanneer het ongelezenaantal van nul naar groter dan nul gaat en de UI-context dat toestaat |
REQ-UC-GEN-MSG-002-023 | SRS-RDM-001 SRS-RDM-002 SRS-RDM-007 SRS-MSG-006 SRS-SHR-001 AC-RDM-001 AC-RDM-002 AC-RDM-007 AC-MSG-006 AC-SHR-001 | De bestaande badgewaarde bij de ontvanger kunnen actualiseren wanneer de ontvanger al ongelezen berichten had |
REQ-UC-GEN-MSG-002-024 | SRS-RDM-001 SRS-RDM-002 SRS-RDM-005 SRS-RDM-006 SRS-MSG-006 SRS-LRN-005 AC-RDM-001 AC-RDM-002 AC-RDM-005 AC-RDM-006 AC-MSG-006 AC-LRN-005 | Bij leerlingen tijdens een actieve oefenrun de ongelezenbadge visueel verborgen kunnen houden |
REQ-UC-GEN-MSG-002-025 | SRS-MSG-006 SRS-LRN-009 AC-MSG-006 AC-LRN-009 | Bij leerlingen tijdens een actieve oefenrun de onderliggende ongelezenstatus normaal blijven registreren |
REQ-UC-GEN-MSG-002-026 | SRS-MSG-006 SRS-LRN-006 AC-MSG-006 AC-LRN-006 | Na afronden of verlaten van een actieve oefenrun het actuele ongelezenaantal opnieuw kunnen bepalen en tonen wanneer dit groter is dan nul |
REQ-UC-GEN-MSG-002-027 | SRS-MSG-001 AC-MSG-001 | De mutaties voor threadcontext, participantregels, privébericht, threadmetadata en readstate transactioneel verwerken |
REQ-UC-GEN-MSG-002-028 | SRS-MSG-001 SRS-SHR-001 AC-MSG-001 AC-SHR-001 | Bij technische verzendfout geen gedeeltelijke mutatie achterlaten |
REQ-UC-GEN-MSG-002-029 | SRS-MSG-001 AC-MSG-001 | Bij technische verzendfout POP-GEN-MSG-SEND-FAILED kunnen tonen |
REQ-UC-GEN-MSG-002-030 | SRS-MSG-001 AC-MSG-001 | Bij verzendfouten de ingevoerde berichtinhoud beschikbaar houden zodat de gebruiker opnieuw kan proberen |
REQ-UC-GEN-MSG-002-031 | SRS-MSG-001 AC-MSG-001 | Bij reguliere nieuwe privéberichten geen systeembericht aanmaken |
REQ-UC-GEN-MSG-002-032 | SRS-AUTH-001 SRS-MSG-001 AC-AUTH-001 AC-MSG-001 | Bij autorisatie- of verzendfouten geen technische identifiers, stacktraces of interne databasenaamgeving tonen |
REQ-UC-GEN-MSG-002-033 | SRS-MSG-001 AC-MSG-001 | UTC-bronwaarden lokaal en consistent tonen in de opstel- en vervolgweergave |