Mail and Conversations (POP)

The pop submodule of com owns the in-app messaging plumbing: conversations attached to a domain entity, mail messages (inbound, outbound, notifications, comments) flowing through those conversations, attachments on each message, and the per-user follower bookkeeping that drives reply-by-mail and read/starred state. It depends on com.org for the company a conversation lives in, on com.par for the partner mail is from/to, on sys.usr for authors and followers, and on sys.xch to actually send and receive emails.

Concepts

Conversation

A thread of mail messages linked to a domain entity (a sales order, a purchase order, a partner, …​). Other modules call findOrCreateConversation to attach a conversation to "their" record without owning the entity-to-conversation glue themselves.

Mail Message

One message inside a conversation. Carries from/to/cc/bcc, subject and body, the type (inbound/outbound/notification/comment), and a derived status. Outbound messages start as drafts and become "sent" when processed; inbound messages are received from the mail provider and become "read" once a follower opens them.

Mail Message Type

Whether a message is inbound (I), outbound (O), a system notification (N), or an internal comment (C). Decides whether the message should be sent over SMTP and how its status moves.

Mail Message Status

The derived state shown in the UI — Received, Read, Draft, Sent. Each conversation message carries one of these.

Conversation Follower

A user that has opted into a conversation. Followers receive notifications and comments by mail when the message is processed.

Mail Follower

A user’s per-message read/starred bookmark on a specific mail message.

Mail Attachment

A file attached to a mail message, with optional extracted (scraped) JSON content for downstream processing.

Mail Message Group

A reference type that bundles a subject and body text-template — used as a starting point when composing notifications.

Entities

POP entities

Conversation (Conversation)

A mail thread attached to a domain entity.

FieldDescription

conversationCode

Business key.

company

The owning finance company.

domainEntityType

Optional class name of the entity the conversation is attached to.

domainEntityKey

Optional id of that entity.

domainEntityCode

Optional business code of that entity (used for searching).

Conversation Follower (ConversationFollower)

A user that follows a conversation.

FieldDescription

conversation

Owning conversation (composite business key with user).

user

The follower.

Mail Message (MailMessage)

One message in a conversation.

FieldDescription

internetMessageId

Business key — the RFC-822 Message-ID (synthesized for system messages).

mailMessageType

Inbound, outbound, notification, or comment — see Mail Message Types below.

author

Optional user that wrote the message.

company

Optional company the message belongs to.

partner

Optional partner the message is from/to.

mailFrom

Sender email address.

mailTo

Optional primary recipient.

mailCC / mailBC

Optional CC/BCC lists.

subject / body

Message subject and body.

messageGroup

Optional group whose subject/body templates were used.

sentAt

Timestamp the message was sent (outbound).

receivedAt

Timestamp the message was received (inbound).

inReplyTo

Optional Message-ID this message replies to.

parentMessage

Optional direct parent in the thread.

rootMessage

Optional thread root.

domainEntityType / domainEntityKey / domainEntityCode

Optional reference back to the domain entity the message is about.

conversation

The conversation the message belongs to.

processed

Status flag: whether the message has been processed (sent/handled).

biMessageStatus

Derived status — see Mail Message Statuses below.

A validation rule enforces that any parentMessage, rootMessage, or conversation referenced by the message belongs to the same partner and company as the message itself.

Mail Message Types (MailMessageType)

CodeNameMeaning

I

Inbound

Received from the mail provider.

O

Outbound

Authored in the ERP, to be sent over SMTP.

N

Notification

System-generated notification, distributed by mail to conversation followers.

C

Comment

Internal comment, distributed by mail to conversation followers.

Mail Message Statuses (MailMessageStatus)

CodeNameMeaning

IR

Received

Inbound message received but not yet read.

IP

Read

Inbound message a follower has read.

OD

Draft

Outbound message not yet sent.

OS

Sent

Outbound message dispatched over SMTP.

The status is derived: a message is Draft while not processed, Processed (and archived) once processed.

Mail Follower (MailFollower)

A user’s read/starred bookmark on a specific mail message.

FieldDescription

mailMessage

The message (composite business key with user).

user

The user.

mailStarred

Whether the user has starred the message.

mailRead

Whether the user has read the message.

Mail Attachment (MailAttachment)

A file attached to a mail message.

FieldDescription

mailMessage

Owning message (composite business key with attachmentName).

attachmentName

File name.

filePath

Path to the file on the document store.

scrapedFileContent

Optional JSON extracted from the file by downstream scraping (operational field).

Mail Message Group (MailMessageGroup)

A bundle of subject and body text templates used as a starting point when composing a notification.

FieldDescription

code

Business key (up to 8 characters).

description

Human-readable name.

subjectTemplate

Text template used for the subject.

bodyTemplate

Text template used for the body.

Functionality

Conversation creation and reuse

MailMessageWriterService.createConversation allocates a new Conversation and links it to a domain object reference (type/key/code). findOrCreateConversation is the idempotent variant — it locates the existing conversation for an entity and returns it, or creates a new one if none exists. Other modules use this to attach a conversation to "their" record without owning the entity-to-conversation glue.

Outbound email posting

postOutboundEmail records a fresh outbound MailMessage against a conversation with the supplied To/CC/BCC, subject, and body. The message is created in Draft state; sending it over SMTP happens when the user (or a downstream job) processes the message.

Follower management

addFollower adds the current user as a follower of a conversation. The matching UI action mailMessageFollow (on MailMessageViewModel) calls into the same service. Followers receive notifications and comments by mail when those messages are processed.

Mail-message processing

The process and processUndo write actions on MailMessageViewModel flip the message between draft and processed status. MailMessageProcessor.sendOutboundEmail is the engine behind processing: it reads the conversation’s followers and decides whether the message should be dispatched over SMTP and whether it should be marked processed. The behaviour depends on the message type:

TypeBehaviour on process

NOTIFICATION

Sent over SMTP to every follower; the message is marked processed.

COMMENT

Sent over SMTP to every follower; the message is marked processed.

INBOUND

Not re-sent; the message stays as it was received.

OUTBOUND

Sent over SMTP to the message’s To/CC/BCC; the message is marked processed.

The actual SMTP send is delegated to `sys.xch’s command API; this submodule only orchestrates the message-level state.

ViewModel ergonomics

MailMessageViewModel sets the author to the logged-in user on createRecord and synthesizes a fresh internetMessageId. It also derives sane defaults for sentAt / receivedAt based on the chosen mailMessageType and refuses to create inbound messages from the UI (those originate from the mail provider). On a processed message, all fields except those of an inbound message are hidden; for inbound processed messages they are read-only.

Public API

COM_POP_QueryApi

Read-side facade.

MethodDescription

findByMailMessageTypeAndProcessed(MailMessageType, Processed)

Mail messages of a given type and processed flag.

findAllAttachmentsByMailMessage(MailMessage)

All attachments of a message.

findAllAttachments()

All mail attachments.

COM_POP_CommandApi

Write-side facade.

MethodDescription

createConversation(HasTrace, Company, DomainObjectType, DomainObjectCode)

Creates a fresh conversation for a domain object reference.

findOrCreateConversation(HasTrace, Company, DomainEntity, Class)

Returns the existing conversation for an entity, or creates one.

postOutboundEmail(HasTrace, User, Conversation, Email, MailSubject, MailBody, EmailList, EmailList)

Records a draft outbound mail message in a conversation.

addFollower(HasTrace, Conversation)

Adds the current user as a follower of the conversation.

ViewModel actions

ActionUser-visible effect

mailMessageFollow (on Mail Message)

Adds the current user as a follower of the message’s conversation.

process (on Mail Message)

Processes a draft message: sends notifications/comments/outbound mail and marks the message processed.

processUndo (on Mail Message)

Reverts a processed message to draft state.