docs: propose a thread participants join - #80
Open
A1exZabr wants to merge 1 commit into
Open
Conversation
|
@A1exZabr is attempting to deploy a commit to the Comp AI - PoC Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Threads should know all their participants
I built a multi-channel CRM a while back (Telegram, MAX, Avito), so I have been reading
this repo with the channel requests in mind. WhatsApp is still open in #50, Outlook was
asked for in #47 and has now shipped, and the mailbox code was just pulled out into a
provider-agnostic
mailbox/module to make room for it.That refactor is what prompted this. The provider abstraction is there now, but one
assumption came through it unchanged, and it is already wrong with just email.
A thread is attached to exactly one contact.
thread-writer.service.tscollects everyparticipant:
and
mailbox-match.service.tshands back a single id:findFirstwith noorderBy, so a thread with three known contacts lands on whicheverrow Postgres returns first. The other two exist only as strings inside
EmailMessage.recipients.That matters more here than it would in most CRMs, because of what
read_crm_historyisfor.
identity-matching.mdcalls it the strongest evidence available anywhere and saysto start every match there rather than at a search engine. It reads
emailThread.findMany({ where: { contactId } }). For the two participants who lost thecoin flip the thread does not exist. The agent reports no history and goes off to pay for
a lookup, while the reply that would have settled it is sitting in the database.
crm.thread-replyis unavailable for exactly the people who did reply.What I would do is add a join table between threads and contacts, and keep
EmailThread.contactIdas the primary contact so nothing existing breaks. The syncwrites a row per participant it can resolve.
read_crm_historyreads through the joininstead of the direct foreign key.
What it costs: a migration and a backfill over existing threads, and any query that
assumes one contact per thread has to decide whether it wants the primary or all of them.
The agent tools are the interesting part of that decision, not the UI.
I hit this in my own CRM early and ended up with a
ConversationContactjoin for thesame reason. A conversation with two people from the client company is not an edge case,
it is Tuesday. Once a channel arrives that has no To field to pick a winner from, there
is nothing left to guess with.
Summary by cubic
Adds an ADR proposing a join table so threads track all participants, while keeping
EmailThread.contactIdas the primary contact. This avoids random single-contact assignment and lets tools likeread_crm_historyandcrm.thread-replyfind threads for every participant.ThreadContactjoin table and backfill existing threads.read_crm_historyto read via the join.Written for commit c1ab1fa. Summary will update on new commits.