@@ -9,9 +9,20 @@ type Input = {
99 title : string ;
1010 components : ReturnType < typeof uiComponent . text > [ ] ;
1111 labelTypeIds ?: string [ ] ;
12+ organizationId ?: string ;
13+ organizationName ?: string ;
1214} ;
1315
14- export async function sendToPlain ( { userId, email, name, title, components, labelTypeIds } : Input ) {
16+ export async function sendToPlain ( {
17+ userId,
18+ email,
19+ name,
20+ title,
21+ components,
22+ labelTypeIds,
23+ organizationId,
24+ organizationName,
25+ } : Input ) {
1526 if ( ! env . PLAIN_API_KEY ) {
1627 return ;
1728 }
@@ -53,6 +64,34 @@ export async function sendToPlain({ userId, email, name, title, components, labe
5364 return ;
5465 }
5566
67+ // Attribute the thread to the org so support data can be rolled up per org: the tenant is
68+ // keyed by externalId = org_id. Isolated in its own try/catch, and the thread's
69+ // tenantIdentifier is gated on success — so a tenant failure (e.g. an API key without
70+ // tenant scope) downgrades to "no attribution" instead of dropping the thread. The
71+ // customer's own externalId (User.id, used by the customer cards + impersonation link) is
72+ // left untouched.
73+ let tenantLinked = false ;
74+ if ( organizationId ) {
75+ try {
76+ await client . mutation . upsertTenant ( {
77+ input : {
78+ identifier : { externalId : organizationId } ,
79+ externalId : organizationId ,
80+ name : organizationName ?? organizationId ,
81+ } ,
82+ } ) ;
83+ await client . mutation . addCustomerToTenants ( {
84+ input : {
85+ customerIdentifier : { customerId } ,
86+ tenantIdentifiers : [ { externalId : organizationId } ] ,
87+ } ,
88+ } ) ;
89+ tenantLinked = true ;
90+ } catch ( error ) {
91+ console . error ( "Failed to link Plain customer to org tenant" , error ) ;
92+ }
93+ }
94+
5695 await client . mutation . createThread ( {
5796 input : {
5897 customerIdentifier : {
@@ -61,6 +100,7 @@ export async function sendToPlain({ userId, email, name, title, components, labe
61100 title : title ,
62101 components : components ,
63102 labelTypeIds,
103+ tenantIdentifier : tenantLinked ? { externalId : organizationId } : undefined ,
64104 } ,
65105 } ) ;
66106 } catch ( error ) {
0 commit comments