The domain is organised around these fundamental concepts:
Users represent authenticated users (or the system user).
Messages refer to the messages sent by users and by the system.
Commands refer to a specific type of message, a command, which will (when authorized) trigger a change to entities in the system (e.g. /rename room My Room
).
Rooms are the message rooms users may join, to which messages are sent.
Memberships represent the membership status history (PendingApproval
, Joined
, Revoked
, etc.) of a user for a given room. This history is used to authorize users using an AuthService.
The uniquely identifiable entity representing a message in the system is a SentMessage. Before being sent, there are a few value objects which represent how messages are processed and dispatched:
/help
) is considered to be a command, represented by an IncomingCommand.The entrypoint to the messaging pipeline is the MessagesService. A simplified view of this service looks like this:
stateDiagram
state MessagesService {
direction LR
state if_state <<choice>>
[*] --> if_state
if_state --> IncomingCommand: isCommand
if_state --> IncomingMessage: !isCommand
IncomingMessage --> Dispatcher
Dispatcher --> SentMessage
IncomingCommand --> CommandService
CommandService --> Dispatcher
}
A message identified as an IncomingCommand
will be parsed and (if it is a valid command) executed.
stateDiagram
state CommandService {
direction LR
[*] --> IncomingCommand
IncomingCommand --> TokenizedCommand : tokenize
TokenizedCommand --> ParsedCommand : parse
ParsedCommand --> Dispatcher : execute
Dispatcher
}
The CommandService applies the following steps to match parsed commands and execute them with the appropriate use case:
CommandService
will match the parsed command and execute the corresponding use case.Dispatcher
as appropriate.