UC-GEN-MSG-004 — Bericht beantwoorden
1. Kerngegevens
| Veld | Waarde |
|---|---|
| Usecase-ID | UC-GEN-MSG-004 |
| Naam | Bericht beantwoorden |
| Domein | Berichten |
| Primaire actor | Ingelogde gebruiker |
| Secundaire actor(en) | Systeem, andere deelnemer(s) aan de privéberichtthread, relatie- en autorisatieservice, realtime notificatiecomponent |
| Rolcontext | Iedere ingelogde rolcontext waarvoor privéberichten beschikbaar zijn; verzenden wordt server-side beperkt tot beantwoordbare privéthreads waarin de gebruiker actief deelnemer is en waarin de relatie- of deelnemerscontext op verzendmoment nog geldig is |
| Betrokken schermen | SCH-GEN-04 — Open bericht, SCH-GEN-05 — Beantwoord bericht |
| Gerelateerde usecases | UC-GEN-MSG-001 — Berichtenoverzicht bekijken; UC-GEN-MSG-002 — Nieuw privébericht opstellen en verzenden; UC-GEN-MSG-003 — Bericht openen |
| Primaire entiteiten | PrivateMessageThreads, PrivateMessageThreadParticipants, PrivateMessages, participant-readstate |
| Secundaire entiteiten / events | PrivateMessageThreadEvents, Users, UserRelationships, SiteFeatureToggles, PrivateMessageCreated, PrivateMessageThreadSubjectChanged, PrivateThreadReadStateChanged, MessageUnreadCountChanged, PrivateMessageSendFailed |
| Gerelateerde popups | POP-GEN-MSG-NOT-AVAILABLE, POP-GEN-MSG-NO-RELATION, POP-GEN-MSG-SEND-FAILED |
| Popupregister | Ontwerpbronnen — Popup-register |
| MoSCoW | Must have |
2. Omschrijving
De gebruiker beantwoordt een bestaande privéberichtthread vanuit de open-berichtcontext. De inline antwoordweergave toont bovenaan het antwoordformulier en daaronder de bestaande threadtijdlijn, zodat de gebruiker de conversatiecontext kan blijven lezen tijdens het opstellen van het antwoord.
De usecase geldt uitsluitend voor privéberichtthreads. Systeemberichten hebben geen reguliere antwoordactie. Een antwoord wordt pas opgeslagen nadat de gebruiker Verstuur bericht kiest en nadat de backend opnieuw heeft gecontroleerd of de gebruiker de thread mag beantwoorden, of privéberichten sitebreed beschikbaar zijn, of de participantregel geldig is, of de thread niet uit de eigen mailboxcontext is verwijderd en of de vereiste relatie- of deelnemerscontext op dat moment nog bestaat.
Wanneer de gebruiker het onderwerp aanpast, wordt dit niet als apart systeembericht opgeslagen. De threadmetadata wordt bijgewerkt en er ontstaat een PrivateMessageThreadEvents-record van het type SubjectChanged. Het antwoord zelf wordt opgeslagen als nieuw PrivateMessages-record binnen dezelfde PrivateMessageThreads-context.
3. Scope
Deze usecase beschrijft:
- het openen van de inline antwoordweergave vanuit een beantwoordbare privéthread;
- het tonen van het antwoordformulier met onderwerp en berichtinhoud;
- het tonen van de bestaande threadtijdlijn als read-only context;
- het gebruikergebonden bijwerken van de leespositie bij openen van de inline antwoordweergave;
- het annuleren van een antwoord zonder opslag;
- het server-side verzenden van een antwoord binnen een bestaande thread;
- de relatie-, participant-, thread- en featurecontrole op het moment van verzenden;
- het valideren en veilig verwerken van onderwerp en rich-text berichtinhoud;
- het optioneel wijzigen van het threadonderwerp en het vastleggen van een thread-event;
- het aanmaken van een nieuw privébericht;
- het bijwerken van threadmetadata, leespositie van de verzender en ongelezenstatus voor andere deelnemer(s);
- foutpaden voor ontbrekende relatie, niet-beantwoordbare thread, validatiefouten en technische verzendfouten;
- popupverwijzingen naar centrale popupkeys.
Deze usecase beschrijft niet:
- het opstellen van een volledig nieuw privébericht buiten een bestaande thread;
- het zoeken, filteren of pagineren van het berichtenoverzicht;
- het openen van systeemberichten als zelfstandige detailflow;
- het inhoudelijk verwerken van domeinobjecten waar een systeembericht naar verwijst;
- het verwijderen van privéthreads uit de eigen mailbox;
- het beheren van systeemberichtsjablonen, popupdefinities of featuretoggles;
- retentie, cleanup of archivering van privéberichten;
- bijlagen of tussentijdse opslag van niet-verzonden antwoorden, omdat die niet tot de eerste berichtflow behoren.
4. Pre-condities
| ID | Voorwaarde |
|---|---|
| PRE-001 | De gebruiker is ingelogd. |
| PRE-002 | De gebruiker opent de antwoordflow vanuit een privéberichtthread of via een route die naar een bestaande privéthread verwijst. |
| PRE-003 | De privéberichtenfunctionaliteit is sitebreed beschikbaar. |
| PRE-004 | De backend kan de PrivateMessageThreadParticipants-regel voor de ingelogde gebruiker bepalen. |
| PRE-005 | De thread is voor de ingelogde gebruiker niet uit de eigen mailboxcontext verwijderd. |
| PRE-006 | De thread is functioneel beantwoordbaar. |
| PRE-007 | De relatie- of deelnemerscontext die privéberichten tussen de deelnemers toestaat, kan op verzendmoment server-side worden gecontroleerd. |
| PRE-008 | Berichtinhoud en onderwerp kunnen server-side gevalideerd, gesanitized en veilig opgeslagen worden. |
| PRE-009 | De bestaande threadtijdlijn kan worden opgebouwd uit PrivateMessages en PrivateMessageThreadEvents die bij dezelfde thread horen. |
5. Post-condities
| ID | Resultaat |
|---|---|
| POST-001 | Bij annuleren is geen nieuw privébericht aangemaakt en is geen onderwerpwijziging opgeslagen. |
| POST-002 | Bij succesvol verzenden is precies één nieuw PrivateMessages-record aangemaakt binnen de bestaande thread. |
| POST-003 | Als het onderwerp is gewijzigd, is de threadmetadata bijgewerkt en is een PrivateMessageThreadEvents-record met type SubjectChanged vastgelegd. |
| POST-004 | De leespositie van de verzendende deelnemer is bijgewerkt zodat het eigen verzonden antwoord niet ongelezen blijft voor de verzender. |
| POST-005 | Andere relevante deelnemers krijgen de nieuwe activiteit als ongelezen in hun eigen participant-readstate of afgeleid readmodel. |
| POST-006 | De ongelezenteller voor betrokken deelnemers kan opnieuw worden bepaald. |
| POST-007 | Het antwoord en eventuele threadgebeurtenis blijven onderdeel van dezelfde privéberichtthread. |
| POST-008 | Bij geblokkeerd verzenden door ontbrekende relatie, uitgeschakelde feature, niet-beantwoordbare thread of validatiefout wordt geen nieuw privébericht opgeslagen. |
| POST-009 | Bij technische verzendfout blijft de ingevoerde berichtinhoud zichtbaar in het formulier, zodat de gebruiker opnieuw kan proberen. |
| POST-010 | Er worden geen systeemberichten aangemaakt voor gewone privéberichtantwoorden. |
| POST-011 | Er worden geen gegevens van andere threads gelezen, gewijzigd of getoond. |
6. Trigger
De gebruiker kiest in SCH-GEN-04 — Open bericht de actie Beantwoorden bij een privéberichtthread, of opent rechtstreeks de antwoordactie voor een bestaande thread waarvoor server-side toegang en beantwoordbaarheid worden gecontroleerd.
7. Normale processtroom
| Stap | Actor | Scherm / component | Actie | Systeemrespons | Data / regel |
|---|---|---|---|---|---|
| 1 | Gebruiker | SCH-GEN-04 — Open bericht | Kiest Beantwoorden bij een privéthread. | Het systeem start de antwoordflow. | Systeemberichten hebben geen antwoordactie. |
| 2 | Systeem | Backend | Controleert authenticatie en threadtoegang. | Alleen bij geldige participantcontext wordt de inline antwoordweergave geopend. | PrivateMessageThreadParticipants.UserId = huidige gebruiker en DeletedAtUtc is null. |
| 3 | Systeem | Backend | Controleert of de privéberichtenfunctionaliteit beschikbaar is. | Bij beschikbaarheid wordt de threadcontext geladen. | Sitebrede featurecontrole is server-side leidend. |
| 4 | Systeem | Backend | Controleert of de thread beantwoordbaar is. | Alleen beantwoordbare threads krijgen een actief antwoordformulier. | Participantstatus, threadstatus en relatie-/deelnemerscontext bepalen dit gezamenlijk. |
| 5 | Systeem | Backend | Laadt threadmetadata, deelnemers, berichten en thread-events. | De read-only threadtijdlijn wordt opgebouwd. | Alleen objecten uit dezelfde geautoriseerde thread. |
| 6 | Systeem | Backend | Werkt de leespositie van de ingelogde deelnemer bij voor de getoonde context. | Getoonde threaditems blijven niet onterecht ongelezen voor deze gebruiker. | LastReadMessageId en/of LastReadAtUtc op de eigen participantregel. |
| 7 | Systeem | SCH-GEN-05 — Beantwoord bericht | Toont antwoordformulier en threadtijdlijn. | Onderwerp is gevuld met het actuele threadonderwerp; berichtveld is leeg. | Zichtbare namen, tijden en berichten zijn dynamische waarden. |
| 8 | Gebruiker | SCH-GEN-05 — Beantwoord bericht | Vult berichtinhoud in en wijzigt eventueel het onderwerp. | Het formulier bewaart de invoer client-side tot verzenden of annuleren. | Niet-verzonden antwoorden worden binnen deze flow niet tussentijds opgeslagen. |
| 9 | Gebruiker | SCH-GEN-05 — Beantwoord bericht | Kiest Verstuur bericht. | Het systeem start de server-side verzendactie. | Frontendvalidatie is nooit voldoende. |
| 10 | Systeem | Backend | Controleert opnieuw authenticatie, featurestatus, participantstatus, threadstatus en relatie-/deelnemerscontext. | Alleen wanneer alle controles slagen gaat de mutatie door. | Relatiecontrole vindt plaats op verzendmoment. |
| 11 | Systeem | Backend | Valideert onderwerp en berichtinhoud. | Lege of ongeldige inhoud blokkeert verzenden. | Na sanitizing moet inhoud overblijven. |
| 12 | 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. |
| 13 | Systeem | Backend | Vergelijkt het opgegeven onderwerp met het actuele threadonderwerp. | Bij afwijking wordt de onderwerpwijziging voorbereid. | De server gebruikt de actuele databasewaarde, niet alleen de schermstaat. |
| 14 | Systeem | Backend / database | Werkt indien nodig PrivateMessageThreads.Subject bij. | Het nieuwe onderwerp wordt de actuele threadmetadata. | Uitvoering vindt plaats in dezelfde transactie als het antwoord. |
| 15 | Systeem | Backend / database | Legt indien nodig een PrivateMessageThreadEvents-record vast. | De onderwerpwijziging verschijnt als threadgebeurtenis. | Eventtype SubjectChanged; geen SystemMessages en geen PrivateMessages. |
| 16 | Systeem | Backend / database | Maakt het nieuwe PrivateMessages-record aan. | Het antwoord wordt onderdeel van de bestaande thread. | Sender is de ingelogde gebruiker, behalve in expliciet ondersteunde namens-flow buiten deze reguliere antwoordflow. |
| 17 | Systeem | Backend / database | Werkt threadmetadata bij. | LastMessageAtUtc en relevante samenvattingsvelden worden bijgewerkt. | De thread blijft dezelfde thread. |
| 18 | Systeem | Backend / database | Werkt readstate voor de verzender bij. | Het eigen nieuwe bericht telt niet als ongelezen voor de verzender. | Alleen eigen participantregel wordt aangepast. |
| 19 | Systeem | Backend / readmodel | Markeert nieuwe activiteit als ongelezen voor andere relevante deelnemers. | Andere deelnemers zien de thread als ongelezen wanneer zij de nieuwe activiteit nog niet gelezen hebben. | Participantgebonden readstate/readmodel. |
| 20 | Systeem | Eventing / realtime | Publiceert relevante events. | UI-indicatoren en ongelezentellers kunnen worden bijgewerkt. | PrivateMessageCreated, optioneel PrivateMessageThreadSubjectChanged, PrivateThreadReadStateChanged, MessageUnreadCountChanged. |
| 21 | Systeem | SCH-GEN-04 of SCH-GEN-05 | Toont de bijgewerkte threadcontext of navigeert terug naar de open-berichtcontext. | Het verzonden antwoord en eventuele threadgebeurtenis zijn zichtbaar binnen dezelfde thread. | Navigatiekeuze is UI-afhandeling; domeinmutatie is afgerond. |
8. Alternatieve en exceptionele processtromen
| ID | Vanaf stap | Situatie | Systeemgedrag | Popup / melding | Datamutatie |
|---|---|---|---|---|---|
| ALT-001 | 1 | De gebruiker probeert een systeembericht te beantwoorden. | De antwoordactie is niet beschikbaar; bij gemanipuleerde route weigert de backend de actie. | Functionele melding binnen pagina of algemene foutafhandeling. | Geen. |
| ALT-002 | 2 | De gebruiker is geen deelnemer van de thread. | De backend weigert toegang tot de inline antwoordweergave zonder inhoudelijke gegevens prijs te geven. | POP-GEN-MSG-NOT-AVAILABLE of gelijkwaardige inline niet-beschikbaarstaat. | Geen. |
| ALT-003 | 2 | De thread is voor deze gebruiker uit de eigen mailbox verwijderd. | De backend behandelt de normale antwoordactie als niet beschikbaar. | POP-GEN-MSG-NOT-AVAILABLE of gelijkwaardige inline niet-beschikbaarstaat. | Geen. |
| ALT-004 | 3 | Privéberichten zijn sitebreed uitgeschakeld. | De inline antwoordweergave wordt niet bruikbaar gemaakt of de verzendactie wordt geweigerd. | Functionele melding dat privéberichten niet beschikbaar zijn. | Geen. |
| ALT-005 | 4 | De thread is niet meer beantwoordbaar doordat de deelnemer de thread heeft verlaten of de thread administratief gesloten is. | De backend blokkeert beantwoorden. | Functionele melding binnen pagina. | Geen. |
| ALT-006 | 10 | De relatie- of deelnemerscontext is vervallen tussen openen en verzenden. | Verzenden wordt server-side geblokkeerd. | POP-GEN-MSG-NO-RELATION. | Geen. |
| ALT-007 | 11 | Onderwerp ontbreekt. | Verzenden wordt geblokkeerd en het onderwerpveld krijgt een validatiemelding. | Inline validatiemelding. | Geen. |
| ALT-008 | 11 | Berichtinhoud ontbreekt. | Verzenden wordt geblokkeerd en het berichtveld krijgt een validatiemelding. | Inline validatiemelding. | Geen. |
| ALT-009 | 11-12 | Berichtinhoud bevat alleen lege of ongeldig verwijderde opmaak. | Na sanitizing blijft geen inhoud over; verzenden wordt geblokkeerd. | Inline validatiemelding. | Geen. |
| ALT-010 | 12 | Berichtinhoud bevat niet-toegestane actieve inhoud. | Actieve inhoud wordt verwijderd of de invoer wordt geweigerd volgens de veilige invoerregels. | Inline validatiemelding of foutmelding. | Geen bij weigering; bij veilige verwijdering wordt alleen gesanitized inhoud opgeslagen. |
| ALT-011 | 13 | Het onderwerp is door een andere actie gewijzigd sinds de inline antwoordweergave werd geopend. | De backend vergelijkt met de actuele threadwaarde en voorkomt dat een verouderde schermstaat onbedoeld de actuele waarde overschrijft. | Functionele melding of herlaadadvies. | Geen, tenzij de gebruiker opnieuw bevestigt of opnieuw verzendt met actuele context. |
| ALT-012 | 14-16 | Database- of transactiefout tijdens verzenden. | De volledige mutatie wordt teruggedraaid. | POP-GEN-MSG-SEND-FAILED. | Geen gedeeltelijke mutatie. |
| ALT-013 | 20 | Realtime notificatie kan niet worden afgeleverd. | Het bericht blijft opgeslagen; ongelezenstatus blijft via database/readmodel correct. | Geen blocking popup voor verzender, hoogstens technische logging. | Berichtmutatie blijft bestaan. |
| ALT-014 | 21 | De gebruiker verlaat de pagina na succesvol verzenden. | Het antwoord blijft opgeslagen; vervolgnavigatie heeft geen invloed op de mutatie. | Geen. | Geen aanvullende mutatie. |
| ALT-015 | 8 | De gebruiker kiest Annuleren. | De antwoordflow wordt verlaten zonder opslag. | Geen popup vereist. | Geen nieuw bericht, geen onderwerpwijziging, geen thread-event. |
8.1 Beantwoorden binnen één timeline
De antwoordflow gebruikt dezelfde threadtimeline als de open-berichtweergave: oud naar nieuw binnen het geladen venster, met berichtballonnen, participantaccenten, gecentreerde threadevents en waar nodig een marker voor nieuwe activiteit. Het antwoordformulier staat boven de contextweergave; de historie wordt niet naast het formulier geplaatst.
Een antwoord toevoegen is append-only. Gelijktijdige antwoorden van andere deelnemers mogen het verzenden niet blokkeren zolang de actor op verzendmoment nog actieve participant is en de thread beantwoordbaar blijft. Onderwerpwijzigingen worden via het threadmenu verwerkt en als SubjectChanged-event vastgelegd; het antwoordformulier mag geen stale onderwerpwaarde terugschrijven.
9. Business rules
| ID | Regel |
|---|---|
| BR-UC-GEN-MSG-004-001 | Alleen privéberichtthreads zijn beantwoordbaar; systeemberichten hebben geen reguliere antwoordactie. |
| BR-UC-GEN-MSG-004-002 | De gebruiker mag een thread alleen beantwoorden wanneer de backend een geldige participantregel voor de ingelogde gebruiker vindt. |
| BR-UC-GEN-MSG-004-003 | Een thread die voor de gebruiker uit de eigen mailboxcontext is verwijderd, mag niet via de normale antwoordactie worden beantwoord. |
| BR-UC-GEN-MSG-004-004 | Privéberichten moeten sitebreed beschikbaar zijn op het moment dat de inline antwoordweergave wordt gebruikt en op het moment van verzenden. |
| BR-UC-GEN-MSG-004-005 | De backend controleert op verzendmoment opnieuw of de relatie- of deelnemerscontext nog geldig is. |
| BR-UC-GEN-MSG-004-006 | Verzenden mag niet slagen wanneer het onderwerp of de berichtinhoud leeg of ongeldig is. |
| BR-UC-GEN-MSG-004-007 | Rich-textinhoud wordt server-side gesanitized voordat deze wordt opgeslagen of gerenderd. |
| BR-UC-GEN-MSG-004-008 | Een onderwerpwijziging binnen een antwoordflow wordt vastgelegd als PrivateMessageThreadEvents.SubjectChanged en niet als systeembericht. |
| BR-UC-GEN-MSG-004-009 | Een antwoord wordt opgeslagen als nieuw PrivateMessages-record binnen dezelfde PrivateMessageThreads-context. |
| BR-UC-GEN-MSG-004-010 | De leespositie van de verzender wordt na succesvol verzenden bijgewerkt zodat het eigen antwoord niet ongelezen blijft voor de verzender. |
| BR-UC-GEN-MSG-004-011 | Nieuwe berichten en thread-events kunnen voor andere deelnemers bijdragen aan de ongelezenstatus van de thread. |
| BR-UC-GEN-MSG-004-012 | Alle mutaties voor onderwerpwijziging, thread-event, nieuw bericht, threadmetadata en readstate worden transactioneel verwerkt. |
| BR-UC-GEN-MSG-004-013 | Annuleren maakt geen nieuw bericht aan en voert geen onderwerpwijziging door. |
| BR-UC-GEN-MSG-004-014 | Technische identifiers, stacktraces en interne foutdetails worden niet zichtbaar getoond bij verzendfouten of autorisatieblokkades. |
| BR-UC-GEN-MSG-004-015 | Niet-verzonden antwoorden worden binnen deze flow niet tussentijds opgeslagen. |
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-009 | Thread-events binnen privéberichtthreads kunnen bijdragen aan de ongelezenstatus. |
BR-GEN-MSG-012 | Privéthreadweergaven mogen alleen berichten en thread-events uit dezelfde geautoriseerde thread tonen. |
BR-GEN-MSG-013 | Privéberichtantwoorden zijn alleen toegestaan binnen een actieve, beantwoordbare thread waarin de verzender nog een geldige participant- en relatiecontext heeft. |
BR-GEN-MSG-014 | Onderwerpwijzigingen binnen privéthreads worden als thread-event vastgelegd en niet als systeembericht. |
BR-GEN-MSG-015 | Een verzendactie voor een privébericht wordt transactioneel verwerkt. |
10. Datavalidatie
| Veld / object | Validatie |
|---|---|
| Route- of threadreferentie | Mag nooit als autorisatiebewijs worden gebruikt; server-side objectcontrole is verplicht. |
PrivateMessageThreads.Id | Moet bestaan en gekoppeld zijn aan een participantregel voor de ingelogde gebruiker. |
PrivateMessageThreads.Subject | Verplicht bij verzenden; veilig encoden bij weergave; lengtebegrenzing moet in TO/SRS technisch worden vastgelegd. |
| Actuele threadstatus | Moet beantwoordbaar zijn op verzendmoment. |
PrivateMessageThreadParticipants.UserId | Moet overeenkomen met de ingelogde gebruiker. |
PrivateMessageThreadParticipants.DeletedAtUtc | Moet leeg zijn om de thread via de normale antwoordactie te gebruiken. |
| Participant-readstate | Alleen de eigen participantregel mag bij openen of verzenden worden bijgewerkt. |
| Relatie- of deelnemerscontext | Moet op verzendmoment privécommunicatie tussen de deelnemers toestaan. |
| Sitefeature privéberichten | Moet actief zijn op verzendmoment. |
| Berichtinhoud | Verplicht; na sanitizing moet inhoud overblijven. |
| Rich-text opmaak | Alleen veilige, beperkte opmaak is toegestaan; actieve inhoud wordt verwijderd of geweigerd. |
PrivateMessages.ThreadId | Moet gelijk zijn aan de bestaande thread waarin wordt beantwoord. |
PrivateMessages.SenderUserId | Moet de ingelogde gebruiker zijn voor reguliere antwoorden. |
PrivateMessages.Body | Wordt uitsluitend opgeslagen na server-side validatie en sanitizing. |
PrivateMessageThreadEvents.EventType | Bij onderwerpwijziging alleen SubjectChanged; andere eventtypen horen bij eigen flows. |
PrivateMessageThreadEvents.OldValue en NewValue | Moeten de vorige en nieuwe onderwerpwaarde veilig en consistent vastleggen. |
PrivateMessageThreads.LastMessageAtUtc | Wordt bijgewerkt naar het verzendmoment van het nieuwe antwoord. |
| 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-5 | Read | PrivateMessageThreads, PrivateMessageThreadParticipants, PrivateMessages, PrivateMessageThreadEvents, Users | Ophalen van de geautoriseerde threadcontext voor de inline antwoordweergave. |
| 6 | Database | PrivateMessageThreadParticipants | LastReadMessageId en/of LastReadAtUtc wordt bijgewerkt voor de eigen participantregel wanneer de threadcontext wordt getoond. |
| 6 | Event | PrivateThreadReadStateChanged | Leesstatus van de thread is gewijzigd voor de ingelogde gebruiker. |
| 6 | Event | MessageUnreadCountChanged | Ongelezenteller kan opnieuw worden bepaald voor de ingelogde gebruiker. |
| 10 | Read | UserRelationships, participantcontext, featurestatus | Controleren of verzenden op dit moment toegestaan is. |
| 14 | Database | PrivateMessageThreads | Subject wordt bijgewerkt wanneer de gebruiker het onderwerp wijzigt. |
| 15 | Database | PrivateMessageThreadEvents | SubjectChanged wordt vastgelegd met actor, oude waarde, nieuwe waarde en tijdstip. |
| 15 | Event | PrivateMessageThreadSubjectChanged | Threadonderwerp is gewijzigd binnen een bestaande privéthread. |
| 16 | Database | PrivateMessages | Nieuw antwoordbericht wordt aangemaakt binnen de bestaande thread. |
| 16 | Event | PrivateMessageCreated | Nieuw privébericht is succesvol opgeslagen. |
| 17 | Database | PrivateMessageThreads | LastMessageAtUtc en relevante threadsamenvatting worden bijgewerkt. |
| 18 | Database | PrivateMessageThreadParticipants | Leespositie van de verzender wordt bijgewerkt. |
| 18 | Event | PrivateThreadReadStateChanged | Verzender-readstate is bijgewerkt na verzenden. |
| 19 | Database / readmodel | PrivateMessageThreadParticipants of afgeleid readmodel | Andere relevante deelnemers krijgen nieuwe activiteit als ongelezen. |
| 19-20 | Event | MessageUnreadCountChanged | Ongelezentellers van betrokken deelnemers kunnen realtime worden geactualiseerd. |
| ALT-006 | Event / logging | PrivateMessageSendFailed | Verzending is functioneel geblokkeerd door vervallen relatie- of deelnemerscontext. |
| ALT-012 | Event / logging | PrivateMessageSendFailed | Verzending is technisch mislukt; transactie is teruggedraaid. |
12. Geen datamutaties
| Entiteit | Reden |
|---|---|
SystemMessages | Gewone privéberichtantwoorden maken of wijzigen geen systeemberichten. |
SystemMessageTemplates | De antwoordflow gebruikt geen systeemberichtsjabloon. |
PrivateMessageThreads.Id | De bestaande thread blijft dezelfde container; er ontstaat geen nieuwe thread. |
PrivateMessageThreadParticipants van andere deelnemers | Alleen ongelezenafleiding of readmodelstatus voor andere deelnemers wijzigt; hun mailboxverwijdering of expliciete leespositie wordt niet namens hen aangepast. |
PrivateMessages bestaande records | Eerdere berichten worden alleen gelezen en niet gewijzigd. |
PrivateMessageThreadEvents bestaande records | Eerdere thread-events worden alleen gelezen en niet gewijzigd. |
Users | Namen en deelnemersinformatie worden alleen gelezen voor display en autorisatiecontext. |
UserRelationships | Relaties worden alleen gecontroleerd; deze usecase maakt, wijzigt of beëindigt geen relatie. |
Tickets | Een privéberichtantwoord maakt geen melding of ticket aan. |
RelationshipInvitations | Een privéberichtantwoord verwerkt geen relatie-uitnodiging. |
SiteFeatureToggles | Featurestatus wordt alleen gelezen. |
13. State diagram — antwoord- en readstateverloop
14. Decision flow — bericht beantwoorden
15. Data lifecycle diagram — antwoord binnen bestaande thread
16. Sequence diagrammen
16.1 Inline antwoordweergave openen
16.2 Antwoord verzenden zonder onderwerpwijziging
16.3 Antwoord verzenden met onderwerpwijziging
16.4 Verzenden geblokkeerd door vervallen relatiecontext
17. Popupverwijzingen
| PopupKey | Moment | Variant | Doel |
|---|---|---|---|
POP-GEN-MSG-NOT-AVAILABLE | Wanneer de antwoordactie, thread of participantcontext niet bestaat, niet toegankelijk is of voor de gebruiker verwijderd is. | InfoOnly | Duidelijk maken dat het gesprek niet beschikbaar is zonder technische details prijs te geven. |
POP-GEN-MSG-NO-RELATION | Verzenden wordt geblokkeerd omdat de relatie- of deelnemerscontext niet meer geldig is. | InfoOnly | Uitleggen dat het antwoord niet verstuurd kan worden omdat de gebruiker de andere deelnemer niet meer mag berichten. |
POP-GEN-MSG-SEND-FAILED | Verzenden mislukt door een technische of transactionele fout. | InfoOnly | Uitleggen dat het antwoord 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 beantwoorden uitsluitend geldt voor privéthreads, dat het antwoordblok onderaan de bestaande threadtimeline staat, dat systeemberichten geen antwoordactie hebben en dat annuleren niets opslaat. |
| Functioneel Ontwerp | Beschrijft de functionele validaties voor onderwerp, berichtinhoud, featurestatus, participantstatus, beantwoordbaarheid en vervallen relatiecontext. |
| Functioneel Ontwerp | Beschrijft dat onderwerpwijziging via Gespreksopties als threadgebeurtenis zichtbaar wordt en geen systeembericht is. |
| Technisch Ontwerp | Technisch Ontwerp: berichten, systeemberichten, notificaties en privéthreads beschrijft het command ReplyToPrivateMessageThread uit met server-side controle op authenticatie, participantregel, DeletedAtUtc, featuretoggle, threadstatus en relatie-/deelnemerscontext. |
| Technisch Ontwerp | Technisch Ontwerp: berichten, systeemberichten, notificaties en privéthreads beschrijft de transactionele verwerking voor nieuw antwoordbericht, threadmetadata, readstate en eventpublicatie; onderwerpwijziging loopt via Gespreksopties en niet via de replycomposer. |
| Technisch Ontwerp | Technisch Ontwerp: berichten, systeemberichten, notificaties en privéthreads beschrijft dat sanitizing server-side plaatsvindt en dat na sanitizing inhoud moet overblijven voordat opslag is toegestaan. |
| Technisch Ontwerp | Technisch Ontwerp: berichten, systeemberichten, notificaties en privéthreads beschrijft hoe LastReadMessageId en LastReadAtUtc worden gebruikt om zowel privéberichten als thread-events correct in de readstate te betrekken. |
| 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 antwoorden, onderwerpwijzigingen, thread-events, participant-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-004-001 | SRS-MSG-001 SRS-LRN-003 AC-MSG-001 AC-LRN-003 | Een ingelogde gebruiker een bestaande privéberichtthread kunnen laten beantwoorden wanneer de gebruiker een geldige participantcontext heeft |
REQ-UC-GEN-MSG-004-002 | SRS-MSG-001 SRS-LRN-003 AC-MSG-001 AC-LRN-003 | Systeemberichten niet beantwoordbaar maken |
REQ-UC-GEN-MSG-004-003 | SRS-AUTH-001 SRS-RDM-001 SRS-MSG-007 SRS-LRN-003 AC-AUTH-001 AC-RDM-001 AC-MSG-007 AC-LRN-003 | Bij openen van de inline antwoordweergave server-side controleren of de gebruiker deelnemer is van de thread |
REQ-UC-GEN-MSG-004-004 | SRS-AUTH-001 SRS-RDM-001 SRS-RDM-007 SRS-MSG-003 SRS-LRN-003 AC-AUTH-001 AC-RDM-001 AC-RDM-007 AC-MSG-003 AC-LRN-003 | De inline antwoordweergave blokkeren wanneer de thread voor de gebruiker uit de eigen mailboxcontext is verwijderd |
REQ-UC-GEN-MSG-004-005 | SRS-AUTH-001 SRS-MSG-001 SRS-LRN-003 AC-AUTH-001 AC-MSG-001 AC-LRN-003 | Privéberichtantwoorden blokkeren wanneer de privéberichtenfunctionaliteit sitebreed niet beschikbaar is |
REQ-UC-GEN-MSG-004-006 | SRS-RDM-001 SRS-MSG-007 SRS-LRN-003 AC-RDM-001 AC-MSG-007 AC-LRN-003 | Bij openen van de inline antwoordweergave de bestaande threadtijdlijn read-only kunnen tonen |
REQ-UC-GEN-MSG-004-007 | SRS-RDM-001 SRS-MSG-007 SRS-LRN-003 AC-RDM-001 AC-MSG-007 AC-LRN-003 | Bij openen van de inline antwoordweergave de leespositie van de ingelogde deelnemer kunnen bijwerken voor de getoonde threadcontext |
REQ-UC-GEN-MSG-004-008 | SRS-MSG-001 SRS-LRN-003 AC-MSG-001 AC-LRN-003 | Het antwoordformulier tonen met onderwerp en berichtinhoud |
REQ-UC-GEN-MSG-004-009 | SRS-MSG-001 AC-MSG-001 | Het onderwerpveld vullen met het actuele threadonderwerp |
REQ-UC-GEN-MSG-004-010 | SRS-MSG-001 AC-MSG-001 | Annuleren kunnen verwerken zonder nieuw bericht, onderwerpwijziging of thread-event op te slaan |
REQ-UC-GEN-MSG-004-011 | SRS-MSG-001 SRS-LRN-003 AC-MSG-001 AC-LRN-003 | Op verzendmoment opnieuw controleren of de gebruiker de thread mag beantwoorden |
REQ-UC-GEN-MSG-004-012 | SRS-REL-001 SRS-MSG-001 AC-REL-001 AC-MSG-001 | Op verzendmoment controleren of de vereiste relatie- of deelnemerscontext nog geldig is |
REQ-UC-GEN-MSG-004-013 | 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-004-014 | SRS-AUTH-001 SRS-MSG-001 SRS-LRN-003 AC-AUTH-001 AC-MSG-001 AC-LRN-003 | Onderwerp en berichtinhoud server-side valideren voordat een antwoord wordt opgeslagen |
REQ-UC-GEN-MSG-004-015 | 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-004-016 | 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-004-017 | SRS-MSG-001 SRS-LRN-003 AC-MSG-001 AC-LRN-003 | Een onderwerpwijziging via Gespreksopties kunnen verwerken |
REQ-UC-GEN-MSG-004-018 | SRS-MSG-001 SRS-NFR-AUD-001 AC-MSG-001 AC-NFR-AUD-001 | Bij onderwerpwijziging een PrivateMessageThreadEvents-record met type SubjectChanged vastleggen |
REQ-UC-GEN-MSG-004-019 | SRS-MSG-001 AC-MSG-001 | Een onderwerpwijziging binnen een privéthread niet als los systeembericht opslaan |
REQ-UC-GEN-MSG-004-020 | SRS-MSG-001 SRS-LRN-003 AC-MSG-001 AC-LRN-003 | Een succesvol antwoord opslaan als nieuw PrivateMessages-record binnen dezelfde thread |
REQ-UC-GEN-MSG-004-021 | SRS-MSG-002 AC-MSG-002 | Na succesvol verzenden de threadmetadata bijwerken |
REQ-UC-GEN-MSG-004-022 | SRS-MSG-002 AC-MSG-002 | Na succesvol verzenden de leespositie van de verzender bijwerken |
REQ-UC-GEN-MSG-004-023 | SRS-MSG-006 AC-MSG-006 | Na succesvol verzenden nieuwe activiteit als ongelezen kunnen laten meetellen voor andere relevante deelnemers |
REQ-UC-GEN-MSG-004-024 | SRS-RDM-001 SRS-RDM-002 SRS-MSG-006 AC-RDM-001 AC-RDM-002 AC-MSG-006 | Na succesvol verzenden de relevante ongelezentellers opnieuw kunnen bepalen of actualiseren |
REQ-UC-GEN-MSG-004-025 | SRS-MSG-001 AC-MSG-001 | De mutaties voor onderwerpwijziging, thread-event, nieuw bericht, threadmetadata en readstate transactioneel verwerken |
REQ-UC-GEN-MSG-004-026 | SRS-MSG-001 SRS-SHR-001 AC-MSG-001 AC-SHR-001 | Bij technische verzendfout geen gedeeltelijke mutatie achterlaten |
REQ-UC-GEN-MSG-004-027 | SRS-MSG-001 AC-MSG-001 | Bij technische verzendfout POP-GEN-MSG-SEND-FAILED kunnen tonen |
REQ-UC-GEN-MSG-004-028 | SRS-MSG-001 AC-MSG-001 | Bij verzendfouten de ingevoerde berichtinhoud beschikbaar houden zodat de gebruiker opnieuw kan proberen |
REQ-UC-GEN-MSG-004-029 | 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-004-030 | SRS-RDM-001 SRS-MSG-001 SRS-LRN-003 AC-RDM-001 AC-MSG-001 AC-LRN-003 | UTC-bronwaarden lokaal en consistent tonen in de inline antwoordweergave en threadtijdlijn |
8.4 Actuele inline reply-afhandeling
De normale gebruikersflow gebruikt geen zelfstandige replypagina meer. Beantwoorden gebeurt inline onderaan de open privéthread, onder het nieuwste zichtbare timeline-item. De oude /messages/thread/{threadId}/reply-route is alleen nog een fallback voor oude links of race-situaties en redirectt naar de normale threadpagina met #latest.
Het inline antwoordblok bevat alleen het berichtveld, compacte opmaakknoppen en een ?-helpmodal. Onderwerp wijzigen gebeurt niet meer via de replycomposer maar via Gespreksopties in de sticky threadkop.
Bij verzenden controleert de server opnieuw dat de gebruiker actieve participant is, dat er minimaal één andere actieve deelnemer beschikbaar is en dat de body na normalisatie/sanitizing inhoud bevat. Als een andere deelnemer intussen het gesprek heeft verlaten, wordt het antwoord niet opgeslagen en keert de gebruiker terug naar de normale threadpagina met een rode, kindvriendelijke melding.
14.1 Actuele flowcorrectie Batch 6
Historische beschrijvingen of diagrams in dit usecasedocument kunnen nog de oorspronkelijke zelfstandige antwoordpagina noemen. Voor de actuele Batch 6-implementatie is de norm leidend: beantwoorden gebeurt inline op /messages/thread/{threadId} onderaan de threadtimeline. De route /messages/thread/{threadId}/reply is geen normale gebruikersflow meer en redirectt naar de gewone threadpagina. Onderwerp wijzigen hoort bij Gespreksopties, niet bij het antwoordformulier.