Create channels, messages, conversations #2210
Labels
blocked: tech spec needed
scope: backend
Issues that are affecting the backend side only
size: long
type: feature
Context
This is a backend ticket to prepare for the email integration.
Later on, we'll want to integrate other communication channels (e.g. WhatsApp Business, LinkedIn, Twilio SMS, etc.)
Implementation
Create data model
Create migrations and GraphQL API for model described below.
Scope: Backend
Time: 1 day
Prepare endpoints to display threads in UI
Cf discussion on nested relations, we'll need to create a custom endpoint for the show UI (getThreads(companyid / personId))
Scope: backend
Time: 1 day
Display threads in activity feed for companies
Scope: frontend
Time: 1 day
Display list of threads on dedicated tab of contact & company show page
Scope: frontend
Time: 1 day
Display detailed view of a thread
Scope: frontend
Time: 2 days
Discussion
Data model
Message
Note: external used to store channel-specific variables (e.g. historyId, id...)
MessageThread
MessageRecipient
MessageChannel
Access-control
One strong choice being made is that all message metadata is accessible by anyone in the workspace.
That way, we don't have to implement object-level permissions, which would be a pain.
Instead we can focus on a simpler masking system done in the application layer, which we'll call field-level permission or masking. This combines a traditional field level permission (as set per the messaging channel), along with row-level field permission overwrite (I can grant access to a given message/thread).
There are two types of mask:
(note attachments will not be implemented in v1)
Another strong choice that should help simplify things is that permissions are managed at the thread level, regardless of the individual messages recipients. Let's say there's a thread with a client involving 2 team members and then the client replies to the same thread but without CC'ing the second teammate, then that teammate will still have visibility over the full thread.
Some software take a more conservative approach that enables stronger privacy, but that involves complex engineering to know when to split or merge virtual threads that share common messages but don't have the exact same message in it.
We feel that the primary goal of a CRM is to share information across the company and that this is an acceptable trade-off.
Filtering through a nested relation
Sometimes we need to filter through a nested relation.
For example, given a company, we would need to fetch threads' messages' recipients' companies to retrieve the relevant thread they participated in.
If it was supported, the request could look like something like this in an ORM:
MessageThread::whereHas('message.recipient.company', function(query) { query.where('id', $company_id) })
But pg_graphql doesn't support this.
So we have different options:
— Pros: best performance, simple frontend query
— Cons: duplicated data in db, risk on inconsistency
— Pros: simple frontend query
— Cons: do we want to introduce this pattern?
— Pros: simple frontend query
— Cons: do we want to introduce this pattern?
Not mentioning about other options we can quickly discard like doing multiple requests on the frontend!
Tasks
The text was updated successfully, but these errors were encountered: