Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: associations #187

Merged
merged 28 commits into from
Aug 16, 2023
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
bb65117
standardize association naming
hvinder Aug 7, 2023
eb589d5
create a union type for association
hvinder Aug 7, 2023
879ee1b
hubspot association ids
hvinder Aug 7, 2023
e29eddf
hubspot contact -> deal association
hvinder Aug 7, 2023
88257bd
hubspot company -> deal association
hvinder Aug 7, 2023
9cf2774
hubspot event -> deal association
hvinder Aug 8, 2023
3f0a6a9
hubspot lead -> deal association
hvinder Aug 8, 2023
432591b
hubspot task -> deal association
hvinder Aug 8, 2023
7c8cc68
sfdc note -> deal association
hvinder Aug 10, 2023
977ed8e
sfdc task -> deal association
hvinder Aug 10, 2023
e224df0
sfdc event -> deal & event -> contact association
hvinder Aug 10, 2023
22c8977
fix import
hvinder Aug 10, 2023
774deb6
fix import
hvinder Aug 10, 2023
f603d98
zoho note -> deal association
hvinder Aug 10, 2023
c89f342
zoho event -> deal association
hvinder Aug 11, 2023
4e1e4b8
zoho task -> deal association
hvinder Aug 11, 2023
0132bde
zoho contact -> deal association
hvinder Aug 13, 2023
1ef0ecc
zoho company -> deal association
hvinder Aug 13, 2023
d975db7
sfdc company -> deal association
hvinder Aug 14, 2023
65957d4
Merge branch 'main' of github.com:revertinc/Revert into feat/associat…
hvinder Aug 14, 2023
9a66afb
enable sdk deploy to s3
hvinder Aug 14, 2023
a6f6ddc
sfdc contact -> deal association
hvinder Aug 14, 2023
f356e00
zoho contact -> deal association payload fixed
hvinder Aug 14, 2023
3345d09
minor changes
hvinder Aug 14, 2023
2961daa
Address comments
hvinder Aug 14, 2023
0fefff4
Handle errors better
hvinder Aug 15, 2023
59f6d07
Handle standard errors
hvinder Aug 16, 2023
a66d6bb
fern types for association
hvinder Aug 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/deploy-js-sdk.yaml
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@ on:
push:
branches:
- main
# paths:
# - packages/js/**
paths:
- packages/js/**

jobs:
build-deploy-js-sdk:
62 changes: 62 additions & 0 deletions fern/api/definition/common/associations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
types:
CompanyAssociation:
properties:
dealId:
type: optional<string>
docs: The id of the deal to associate with company
ContactAssociation:
properties:
dealId:
type: optional<string>
docs: The id of the deal to associate with contact
DealAssociation:
properties:
contactId:
type: optional<string>
docs: The id of the contact to associate with deal
companyId:
type: optional<string>
docs: The id of the company to associate with deal
EventAssociation:
properties:
dealId:
type: optional<string>
docs: The id of the deal to associate with event
contactId:
type: optional<string>
docs: The id of the contact to associate with event
LeadAssociation:
properties:
contactId:
type: optional<string>
docs: The id of the contact to associate with lead
companyId:
type: optional<string>
docs: The id of the company to associate with lead
dealId:
type: optional<string>
docs: The id of the deal to associate with lead
NoteAssociation:
properties:
contactId:
type: optional<string>
docs: The id of the contact to associate with note
companyId:
type: optional<string>
docs: The id of the company to associate with note
leadId:
type: optional<string>
docs: The id of the lead to associate with note
dealId:
type: optional<string>
docs: The id of the deal to associate with note
TaskAssociation:
properties:
dealId:
type: optional<string>
docs: The id of the deal to associate with task
UserAssociation:
properties:
dealId:
type: optional<string>
docs: The id of the deal to associate with user
3 changes: 3 additions & 0 deletions fern/api/definition/common/errors.yml
Original file line number Diff line number Diff line change
@@ -11,5 +11,8 @@ errors:
status-code: 500
type: BaseError
NotFoundError:
status-code: 404
type: BaseError
BadRequestError:
status-code: 400
type: BaseError
16 changes: 13 additions & 3 deletions fern/api/definition/common/unified.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
imports:
associations: ./associations.yml

types:
CommonUnifiedFields:
properties:
@@ -13,7 +16,6 @@ types:
updatedTimestamp:
type: unknown
docs: The last updated timestamp of the object.
associations: unknown
additional:
type: unknown
docs: Any fields that are not unified yet/non-unifiable come inside this `json` object.
@@ -32,6 +34,7 @@ types:
email:
type: string
docs: The email of the lead in a CRM.
associations: optional<associations.LeadAssociation>
Deal:
extends: CommonUnifiedFields
properties:
@@ -40,7 +43,7 @@ types:
docs: The deal amount mentioned in the CRM for this deal.
priority:
type: optional<string>
docs: The priority attached to this deal.
docs: The priority attached to this deal. (not supported by pipedrive)
stage:
type: string
docs: Deal stage in the CRM.
@@ -49,19 +52,21 @@ types:
docs: The name of the deal in a CRM.
expectedCloseDate:
type: unknown
docs: Expected close date for this deal.
docs: Expected close date for this deal. (not supported by pipedrive search api)
isWon:
type: boolean
docs: Is `true` if the deal is closed (won).
probability:
type: integer
docs: Probability of the deal getting closed, a decimal number between 0 to 1 (inclusive).
associations: optional<associations.DealAssociation>
Note:
extends: CommonUnifiedFields
properties:
content:
type: string
docs: The contents of the note in plain text or HTML.
associations: optional<associations.NoteAssociation>
Company:
extends: CommonUnifiedFields
properties:
@@ -86,6 +91,7 @@ types:
address:
type: CompanyAddress
docs: Company address.
associations: optional<associations.CompanyAssociation>
CompanyAddress:
properties:
street: optional<string>
@@ -109,6 +115,7 @@ types:
email:
type: string
docs: The email of the contact in a CRM.
associations: optional<associations.ContactAssociation>
Event:
extends: CommonUnifiedFields
properties:
@@ -133,6 +140,7 @@ types:
location:
type: string
docs: The location of the event/meeting.
associations: optional<associations.EventAssociation>
Task:
extends: CommonUnifiedFields
properties:
@@ -151,6 +159,7 @@ types:
dueDate:
type: unknown
docs: The date when this task is due.
associations: optional<associations.TaskAssociation>
User:
extends: CommonUnifiedFields
properties:
@@ -166,3 +175,4 @@ types:
email:
type: string
docs: The email of a user in a CRM.
associations: optional<associations.UserAssociation>
2 changes: 2 additions & 0 deletions fern/api/definition/crm/contact.yml
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ service:
- errors.UnAuthorizedError
- errors.InternalServerError
- errors.NotFoundError
- errors.BadRequestError
updateContact:
docs: Update a contact
method: PATCH
@@ -98,6 +99,7 @@ service:
- errors.UnAuthorizedError
- errors.InternalServerError
- errors.NotFoundError
- errors.BadRequestError
searchContacts:
docs: Search for contacts
method: POST
Original file line number Diff line number Diff line change
@@ -36,4 +36,4 @@ export const DEFAULT_SCOPE = {
[TP_ID.pipedrive]: [],
};

export type ValueOf<T> = T[keyof T];
export type AllAssociation = 'contactId' | 'companyId' | 'leadId' | 'dealId' | 'noteId';
3 changes: 3 additions & 0 deletions packages/backend/constants/typeHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type ValueOf<T> = T[keyof T];

export type Subtype<T, U extends T> = U;
15 changes: 15 additions & 0 deletions packages/backend/helpers/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {
BadRequestError,
InternalServerError,
NotFoundError,
UnAuthorizedError,
} from '../generated/typescript/api/resources/common';

export const isStandardError = (error: any) => {
return (
error instanceof NotFoundError ||
error instanceof BadRequestError ||
error instanceof UnAuthorizedError ||
error instanceof InternalServerError
);
};
78 changes: 65 additions & 13 deletions packages/backend/helpers/hubspot.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,68 @@
import { NoteAssociation } from '../models/unified';
import { AllAssociation } from '../constants/common';

export const getHubspotAssociationObj = (key: NoteAssociation) => {
switch (key) {
case 'dealId': {
return {
associationCategory: 'HUBSPOT_DEFINED',
associationTypeId: 214,
};
break;
}
default: {
return {};
}
export const getHubspotAssociationObj = (
key: AllAssociation,
associateObj: 'note' | 'deal' | 'contact' | 'lead' | 'company' | 'event' | 'task'
) => {
const associationTypeMapping: {
[x in typeof associateObj]: { [y in AllAssociation]: number | undefined };
} = {
note: {
dealId: 214,
companyId: 190,
contactId: 202,
leadId: 202,
noteId: undefined,
},
deal: {
contactId: 3,
leadId: 3,
companyId: 341,
noteId: 213,
dealId: undefined,
},
contact: {
companyId: 279,
dealId: 4,
noteId: 201,
leadId: undefined,
contactId: undefined,
},
lead: {
companyId: 279,
dealId: 4,
noteId: 201,
contactId: undefined,
leadId: undefined,
},
company: {
contactId: 280,
leadId: 280,
dealId: 342,
noteId: 189,
companyId: undefined,
},
event: {
contactId: 200,
leadId: 601,
dealId: 212,
noteId: undefined,
companyId: 188,
},
task: {
contactId: 204,
leadId: undefined,
dealId: 216,
noteId: undefined,
companyId: 192,
},
};
const associationTypeId = associationTypeMapping[associateObj][key];
if (associationTypeId) {
return {
associationCategory: 'HUBSPOT_DEFINED',
associationTypeId,
};
}
return null;
};
22 changes: 21 additions & 1 deletion packages/backend/models/unified/company.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { TP_ID } from '@prisma/client';
import { PipedriveCompany } from '../../constants/pipedrive';
import { Subtype } from '../../constants/typeHelpers';
import { AllAssociation } from '../../constants/common';
import { getHubspotAssociationObj } from '../../helpers/hubspot';

export type CompanyAssociation = Subtype<AllAssociation, 'dealId'>;

export interface UnifiedCompany {
name: string;
@@ -20,7 +25,9 @@ export interface UnifiedCompany {
remoteId: string;
createdTimestamp: Date;
updatedTimestamp: Date;
associations?: any; // TODO: Support associations
associations?: {
[x in CompanyAssociation]?: string;
};
additional: any;
}

@@ -578,6 +585,19 @@ export function toHubspotCompany(unifiedCompany: UnifiedCompany): Partial<Hubspo
});
}

if (unifiedCompany.associations) {
const associationObj = unifiedCompany.associations;
const associationArr = Object.keys(associationObj).map((key) => {
return {
to: {
id: associationObj[key as CompanyAssociation],
},
types: [getHubspotAssociationObj(key as CompanyAssociation, 'company')],
};
});
hubspotCompany['associations'] = associationArr;
}

return hubspotCompany;
}

25 changes: 23 additions & 2 deletions packages/backend/models/unified/contact.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,11 @@ import { PipedriveContact } from '../../constants/pipedrive';
import { HubspotContact } from '../../constants/hubspot';
import { ZohoContact } from '../../constants/zoho';
import { SalesforceContact } from '../../constants/salesforce';
import { Subtype } from '../../constants/typeHelpers';
import { AllAssociation } from '../../constants/common';
import { getHubspotAssociationObj } from '../../helpers/hubspot';

export type ContactAssociation = Subtype<AllAssociation, 'dealId'>;

export interface UnifiedContact {
firstName: string;
@@ -13,7 +18,9 @@ export interface UnifiedContact {
remoteId: string; // TODO: Make this unique.
createdTimestamp: Date;
updatedTimestamp: Date;
associations?: any; // TODO: Support associations
associations?: {
[x in ContactAssociation]?: string;
};
additional: any;
}

@@ -113,7 +120,9 @@ export function toZohoContact(unifiedContact: UnifiedContact): ZohoContact {
// Map custom fields
if (unifiedContact.additional) {
Object.keys(unifiedContact.additional).forEach((key) => {
zohoContact.data[0][key] = unifiedContact.additional?.[key];
if (key !== 'Contact_Role') {
zohoContact.data[0][key] = unifiedContact.additional?.[key];
}
});
}

@@ -137,6 +146,18 @@ export function toHubspotContact(unifiedContact: UnifiedContact): Partial<Hubspo
hubspotContact['properties'][key] = unifiedContact.additional?.[key];
});
}
if (unifiedContact.associations) {
const associationObj = unifiedContact.associations;
const associationArr = Object.keys(associationObj).map((key) => {
return {
to: {
id: associationObj[key as ContactAssociation],
},
types: [getHubspotAssociationObj(key as ContactAssociation, 'contact')],
};
});
hubspotContact['associations'] = associationArr;
}

return hubspotContact;
}
Loading