From 1d7ea001ae79990a39f53bf18694fbffec77cfb9 Mon Sep 17 00:00:00 2001 From: nael Date: Sun, 28 Apr 2024 02:18:23 +0200 Subject: [PATCH 1/3] :ambulance: Fixed across backend --- .../connections/connections.controller.ts | 2 +- .../services/gorgias/gorgias.service.ts | 13 +- .../services/zendesk/zendesk.service.ts | 12 +- .../src/crm/company/services/attio/mappers.ts | 12 +- .../crm/company/services/hubspot/mappers.ts | 2 +- .../crm/company/services/pipedrive/mappers.ts | 11 +- .../src/crm/company/services/zendesk/index.ts | 14 +- .../crm/company/services/zendesk/mappers.ts | 22 +- .../src/crm/company/services/zoho/mappers.ts | 27 +- .../api/src/crm/company/sync/sync.service.ts | 78 ++- .../src/crm/company/types/model.unified.ts | 32 +- .../src/crm/contact/services/attio/mappers.ts | 17 +- .../crm/contact/services/contact.service.ts | 4 + .../crm/contact/services/hubspot/mappers.ts | 9 +- .../src/crm/contact/services/zendesk/index.ts | 15 +- .../crm/contact/services/zendesk/mappers.ts | 18 +- .../src/crm/contact/services/zoho/mappers.ts | 21 +- .../api/src/crm/contact/sync/sync.service.ts | 78 ++- .../src/crm/contact/types/model.unified.ts | 6 +- .../src/crm/deal/services/zendesk/mappers.ts | 9 +- .../api/src/crm/deal/sync/sync.service.ts | 78 ++- .../api/src/crm/deal/types/model.unified.ts | 18 +- .../engagement/services/hubspot/mappers.ts | 2 +- .../engagement/services/zendesk/mappers.ts | 10 +- .../src/crm/engagement/sync/sync.service.ts | 80 ++-- .../src/crm/engagement/types/model.unified.ts | 29 +- .../api/src/crm/note/sync/sync.service.ts | 78 ++- .../api/src/crm/note/types/model.unified.ts | 16 +- .../src/crm/stage/services/zendesk/index.ts | 2 +- .../api/src/crm/stage/sync/sync.service.ts | 96 ++-- .../api/src/crm/stage/types/model.unified.ts | 4 +- .../src/crm/task/services/zendesk/index.ts | 1 - .../api/src/crm/task/sync/sync.service.ts | 78 ++- .../api/src/crm/task/types/model.unified.ts | 28 +- .../api/src/crm/user/sync/sync.service.ts | 78 ++- .../api/src/crm/user/types/model.unified.ts | 9 +- .../src/ticketing/account/account.module.ts | 4 + .../account/services/github/index.ts | 64 --- .../account/services/github/mappers.ts | 54 --- .../account/services/github/types.ts | 16 - .../ticketing/account/sync/sync.service.ts | 76 ++- .../attachment/services/github/mappers.ts | 44 -- .../attachment/services/github/types.ts | 3 - .../ticketing/collection/sync/sync.service.ts | 74 ++- .../src/ticketing/comment/comment.module.ts | 4 - .../comment/services/comment.service.ts | 4 +- .../comment/services/github/index.ts | 121 ----- .../comment/services/github/mappers.ts | 47 -- .../comment/services/github/types.ts | 5 - .../comment/services/hubspot/index.ts | 121 ----- .../comment/services/hubspot/mappers.ts | 48 -- .../comment/services/hubspot/types.ts | 5 - .../comment/services/jira/mappers.ts | 4 +- .../comment/services/zendesk/mappers.ts | 21 +- .../ticketing/comment/sync/sync.service.ts | 92 ++-- .../ticketing/comment/types/model.unified.ts | 2 +- .../src/ticketing/contact/contact.module.ts | 2 - .../contact/services/github/index.ts | 65 --- .../contact/services/github/mappers.ts | 28 -- .../contact/services/github/types.ts | 6 - .../ticketing/contact/sync/sync.service.ts | 94 ++-- .../ticketing/tag/services/github/index.ts | 65 --- .../ticketing/tag/services/github/mappers.ts | 28 -- .../ticketing/tag/services/github/types.ts | 6 - .../src/ticketing/tag/sync/sync.service.ts | 92 ++-- packages/api/src/ticketing/tag/tag.module.ts | 2 - .../ticketing/team/services/github/index.ts | 67 --- .../ticketing/team/services/github/mappers.ts | 28 -- .../ticketing/team/services/github/types.ts | 6 - .../src/ticketing/team/sync/sync.service.ts | 76 ++- .../api/src/ticketing/team/team.module.ts | 2 - .../ticket/services/front/mappers.ts | 19 +- .../ticket/services/gorgias/mappers.ts | 22 +- .../ticket/services/hubspot/mappers.ts | 4 +- .../ticketing/ticket/services/jira/mappers.ts | 4 +- .../ticket/services/ticket.service.ts | 4 + .../ticket/services/zendesk/index.ts | 4 + .../ticket/services/zendesk/mappers.ts | 58 +-- .../src/ticketing/ticket/sync/sync.service.ts | 74 ++- .../ticketing/ticket/types/model.unified.ts | 4 +- .../ticketing/user/services/github/index.ts | 65 --- .../ticketing/user/services/github/mappers.ts | 28 -- .../ticketing/user/services/github/types.ts | 6 - .../src/ticketing/user/sync/sync.service.ts | 74 ++- .../api/src/ticketing/user/user.module.ts | 2 - packages/api/swagger/swagger-spec.json | 446 +++++++++++++++--- 86 files changed, 1336 insertions(+), 1863 deletions(-) delete mode 100644 packages/api/src/ticketing/account/services/github/index.ts delete mode 100644 packages/api/src/ticketing/account/services/github/mappers.ts delete mode 100644 packages/api/src/ticketing/account/services/github/types.ts delete mode 100644 packages/api/src/ticketing/attachment/services/github/mappers.ts delete mode 100644 packages/api/src/ticketing/attachment/services/github/types.ts delete mode 100644 packages/api/src/ticketing/comment/services/github/index.ts delete mode 100644 packages/api/src/ticketing/comment/services/github/mappers.ts delete mode 100644 packages/api/src/ticketing/comment/services/github/types.ts delete mode 100644 packages/api/src/ticketing/comment/services/hubspot/index.ts delete mode 100644 packages/api/src/ticketing/comment/services/hubspot/mappers.ts delete mode 100644 packages/api/src/ticketing/comment/services/hubspot/types.ts delete mode 100644 packages/api/src/ticketing/contact/services/github/index.ts delete mode 100644 packages/api/src/ticketing/contact/services/github/mappers.ts delete mode 100644 packages/api/src/ticketing/contact/services/github/types.ts delete mode 100644 packages/api/src/ticketing/tag/services/github/index.ts delete mode 100644 packages/api/src/ticketing/tag/services/github/mappers.ts delete mode 100644 packages/api/src/ticketing/tag/services/github/types.ts delete mode 100644 packages/api/src/ticketing/team/services/github/index.ts delete mode 100644 packages/api/src/ticketing/team/services/github/mappers.ts delete mode 100644 packages/api/src/ticketing/team/services/github/types.ts delete mode 100644 packages/api/src/ticketing/user/services/github/index.ts delete mode 100644 packages/api/src/ticketing/user/services/github/mappers.ts delete mode 100644 packages/api/src/ticketing/user/services/github/types.ts diff --git a/packages/api/src/@core/connections/connections.controller.ts b/packages/api/src/@core/connections/connections.controller.ts index 3dbf6fecc..2bbdb4053 100644 --- a/packages/api/src/@core/connections/connections.controller.ts +++ b/packages/api/src/@core/connections/connections.controller.ts @@ -110,7 +110,7 @@ export class ConnectionsController { } } - @Get('gorgias/oauth/install') + @Get('/gorgias/oauth/install') handleGorgiasAuthUrl( @Res() res: Response, @Query('account') account: string, diff --git a/packages/api/src/@core/connections/ticketing/services/gorgias/gorgias.service.ts b/packages/api/src/@core/connections/ticketing/services/gorgias/gorgias.service.ts index f9f1eeadc..1d4b55597 100644 --- a/packages/api/src/@core/connections/ticketing/services/gorgias/gorgias.service.ts +++ b/packages/api/src/@core/connections/ticketing/services/gorgias/gorgias.service.ts @@ -12,7 +12,11 @@ import { ITicketingConnectionService, } from '../../types'; import { ServiceRegistry } from '../registry.service'; -import { OAuth2AuthData, providerToType } from '@panora/shared'; +import { + OAuth2AuthData, + providersConfig, + providerToType, +} from '@panora/shared'; import { AuthStrategy } from '@panora/shared'; import { ConnectionsStrategiesService } from '@@core/connections-strategies/connections-strategies.service'; @@ -84,6 +88,9 @@ export class GorgiasConnectionService implements ITicketingConnectionService { let db_res; const connection_token = uuidv4(); + const BASE_API_URL = + CREDENTIALS.SUBDOMAIN + + providersConfig['ticketing']['gorgias'].urls.apiUrl; if (isNotUnique) { db_res = await this.prisma.connections.update({ @@ -93,7 +100,7 @@ export class GorgiasConnectionService implements ITicketingConnectionService { data: { access_token: this.cryptoService.encrypt(data.access_token), refresh_token: this.cryptoService.encrypt(data.refresh_token), - account_url: CREDENTIALS.SUBDOMAIN!, + account_url: BASE_API_URL, expiration_timestamp: new Date( new Date().getTime() + Number(data.expires_in) * 1000, ), @@ -109,7 +116,7 @@ export class GorgiasConnectionService implements ITicketingConnectionService { provider_slug: 'gorgias', vertical: 'ticketing', token_type: 'oauth', - account_url: CREDENTIALS.SUBDOMAIN!, + account_url: BASE_API_URL, access_token: this.cryptoService.encrypt(data.access_token), refresh_token: this.cryptoService.encrypt(data.refresh_token), expiration_timestamp: new Date( diff --git a/packages/api/src/@core/connections/ticketing/services/zendesk/zendesk.service.ts b/packages/api/src/@core/connections/ticketing/services/zendesk/zendesk.service.ts index 8a095dfee..3944b4314 100644 --- a/packages/api/src/@core/connections/ticketing/services/zendesk/zendesk.service.ts +++ b/packages/api/src/@core/connections/ticketing/services/zendesk/zendesk.service.ts @@ -12,7 +12,7 @@ import { ITicketingConnectionService, } from '../../types'; import { ServiceRegistry } from '../registry.service'; -import { AuthStrategy } from '@panora/shared'; +import { AuthStrategy, providersConfig } from '@panora/shared'; import { OAuth2AuthData, providerToType } from '@panora/shared'; import { ConnectionsStrategiesService } from '@@core/connections-strategies/connections-strategies.service'; @@ -65,9 +65,8 @@ export class ZendeskConnectionService implements ITicketingConnectionService { scope: 'read', }); - //const subdomain = 'panora7548'; const res = await axios.post( - `${CREDENTIALS.SUBDOMAIN!}/oauth/tokens`, + `${CREDENTIALS.SUBDOMAIN}/oauth/tokens`, formData.toString(), { headers: { @@ -82,6 +81,9 @@ export class ZendeskConnectionService implements ITicketingConnectionService { let db_res; const connection_token = uuidv4(); + const BASE_API_URL = + CREDENTIALS.SUBDOMAIN + + providersConfig['ticketing']['zendesk'].urls.apiUrl; if (isNotUnique) { db_res = await this.prisma.connections.update({ @@ -90,7 +92,7 @@ export class ZendeskConnectionService implements ITicketingConnectionService { }, data: { access_token: this.cryptoService.encrypt(data.access_token), - account_url: CREDENTIALS.SUBDOMAIN!, + account_url: BASE_API_URL, refresh_token: '', expiration_timestamp: new Date(), //TODO status: 'valid', @@ -105,7 +107,7 @@ export class ZendeskConnectionService implements ITicketingConnectionService { provider_slug: 'zendesk', vertical: 'ticketing', token_type: 'oauth', - account_url: CREDENTIALS.SUBDOMAIN!, + account_url: BASE_API_URL, access_token: this.cryptoService.encrypt(data.access_token), refresh_token: '', expiration_timestamp: new Date(), //TODO diff --git a/packages/api/src/crm/company/services/attio/mappers.ts b/packages/api/src/crm/company/services/attio/mappers.ts index d2575b95b..3db40908c 100644 --- a/packages/api/src/crm/company/services/attio/mappers.ts +++ b/packages/api/src/crm/company/services/attio/mappers.ts @@ -26,13 +26,15 @@ export class AttioCompanyMapper implements ICompanyMapper { value: source.name, }, ], - categories: [ - { - option: source.industry, - }, - ], }, }; + if (source.industry) { + result.values.categories = [ + { + option: source.industry, + }, + ]; + } // const result: AttioCompanyInput = { // city: '', // name: source.name, diff --git a/packages/api/src/crm/company/services/hubspot/mappers.ts b/packages/api/src/crm/company/services/hubspot/mappers.ts index 97f57649b..512eea8eb 100644 --- a/packages/api/src/crm/company/services/hubspot/mappers.ts +++ b/packages/api/src/crm/company/services/hubspot/mappers.ts @@ -25,7 +25,7 @@ export class HubspotCompanyMapper implements ICompanyMapper { phone: '', state: '', domain: '', - industry: source.industry, + industry: source.industry || '', }; // Assuming 'phone_numbers' array contains at least one phone number diff --git a/packages/api/src/crm/company/services/pipedrive/mappers.ts b/packages/api/src/crm/company/services/pipedrive/mappers.ts index 7f7b2f696..a2510e943 100644 --- a/packages/api/src/crm/company/services/pipedrive/mappers.ts +++ b/packages/api/src/crm/company/services/pipedrive/mappers.ts @@ -22,12 +22,15 @@ export class PipedriveCompanyMapper implements ICompanyMapper { ): Promise { const result: PipedriveCompanyInput = { name: source.name, - address: source.addresses[0].street_1, - address_locality: source.addresses[0].city, - address_country: source.addresses[0].country, - address_postal_code: source.addresses[0].postal_code, }; + if (source.addresses && source.addresses[0]) { + result.address = source.addresses[0].street_1; + result.address_locality = source.addresses[0].city; + result.address_country = source.addresses[0].country; + result.address_postal_code = source.addresses[0].postal_code; + } + if (source.user_id) { const owner = await this.utils.getUser(source.user_id); if (owner) { diff --git a/packages/api/src/crm/company/services/zendesk/index.ts b/packages/api/src/crm/company/services/zendesk/index.ts index fa597c351..4b3ed6091 100644 --- a/packages/api/src/crm/company/services/zendesk/index.ts +++ b/packages/api/src/crm/company/services/zendesk/index.ts @@ -86,15 +86,17 @@ export class ZendeskService implements ICompanyService { )}`, }, }); - const finalData = resp.data.items - .filter((item) => item.data.is_organization === true) - .map((item) => { - return item.data; - }); + const finalData: any[] = resp.data.items.map((item) => { + return item.data; + }); + const filteredData = finalData.filter( + (item) => item.data.is_organization === true, + ); + this.logger.log(`Synced zendesk companies !`); return { - data: finalData, + data: filteredData, message: 'Zendesk companies retrieved', statusCode: 200, }; diff --git a/packages/api/src/crm/company/services/zendesk/mappers.ts b/packages/api/src/crm/company/services/zendesk/mappers.ts index 8fe9771e1..731599f88 100644 --- a/packages/api/src/crm/company/services/zendesk/mappers.ts +++ b/packages/api/src/crm/company/services/zendesk/mappers.ts @@ -26,18 +26,26 @@ export class ZendeskCompanyMapper implements ICompanyMapper { const result: ZendeskCompanyInput = { name: source.name, - email: primaryEmail, - phone: primaryPhone, - address: { + is_organization: true, + industry: source.industry, + }; + + if (source.addresses && source.addresses[0]) { + result.address = { line1: source.addresses[0].street_1, city: source.addresses[0].city, state: source.addresses[0].state, postal_code: source.addresses[0].postal_code, country: source.addresses[0].country, - }, - is_organization: true, - industry: source.industry, - }; + }; + } + + if (primaryEmail) { + result.email = primaryEmail; + } + if (primaryPhone) { + result.phone = primaryPhone; + } if (source.user_id) { const owner_id = await this.utils.getRemoteIdFromUserUuid(source.user_id); if (owner_id) { diff --git a/packages/api/src/crm/company/services/zoho/mappers.ts b/packages/api/src/crm/company/services/zoho/mappers.ts index 3aaae294d..1304a3aad 100644 --- a/packages/api/src/crm/company/services/zoho/mappers.ts +++ b/packages/api/src/crm/company/services/zoho/mappers.ts @@ -15,18 +15,25 @@ export class ZohoCompanyMapper implements ICompanyMapper { ): ZohoCompanyInput { const result: ZohoCompanyInput = { Account_Name: source.name, - Phone: source.phone_numbers?.find( + }; + + if (source.addresses && source.addresses[0]) { + result.Mailing_Street = source.addresses?.[0]?.street_1; + result.Mailing_City = source.addresses?.[0]?.city; + result.Mailing_State = source.addresses?.[0]?.state; + result.Mailing_Zip = source.addresses?.[0]?.postal_code; + result.Mailing_Country = source.addresses?.[0]?.country; + } + if (source.phone_numbers) { + result.Phone = source.phone_numbers?.find( (phone) => phone.phone_type === 'primary', - )?.phone_number, - Email: source.email_addresses?.find( + )?.phone_number; + } + if (source.email_addresses) { + result.Email = source.email_addresses?.find( (email) => email.email_address_type === 'primary', - )?.email_address, - Mailing_Street: source.addresses?.[0]?.street_1, - Mailing_City: source.addresses?.[0]?.city, - Mailing_State: source.addresses?.[0]?.state, - Mailing_Zip: source.addresses?.[0]?.postal_code, - Mailing_Country: source.addresses?.[0]?.country, - }; + )?.email_address; + } // Custom field mappings if (customFieldMappings && source.field_mappings) { diff --git a/packages/api/src/crm/company/sync/sync.service.ts b/packages/api/src/crm/company/sync/sync.service.ts index 2134d352f..e4a8e6592 100644 --- a/packages/api/src/crm/company/sync/sync.service.ts +++ b/packages/api/src/crm/company/sync/sync.service.ts @@ -47,50 +47,44 @@ export class SyncService implements OnModuleInit { async syncCompanies() { try { this.logger.log(`Syncing companies....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = CRM_PROVIDERS.filter( - (provider) => provider !== 'zoho' && provider !== 'freshsales', - ); - for (const provider of providers) { - try { - await this.syncCompaniesForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = CRM_PROVIDERS.filter( + (provider) => provider !== 'zoho', + ); + for (const provider of providers) { + try { + await this.syncCompaniesForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/crm/company/types/model.unified.ts b/packages/api/src/crm/company/types/model.unified.ts index 7e4864296..e513d2531 100644 --- a/packages/api/src/crm/company/types/model.unified.ts +++ b/packages/api/src/crm/company/types/model.unified.ts @@ -1,13 +1,39 @@ import { Address, Email, Phone } from '@crm/@utils/@types'; -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class UnifiedCompanyInput { + @ApiProperty({ description: 'The name of the company' }) name: string; - industry: string; - number_of_employees: number; + + @ApiPropertyOptional({ description: 'The industry of the company' }) + industry?: string; + + @ApiPropertyOptional({ + description: 'The number of employees of the company', + }) + number_of_employees?: number; + + @ApiPropertyOptional({ + description: 'The uuid of the user who owns the company', + }) user_id?: string; + + @ApiPropertyOptional({ + description: 'The email addresses of the company', + type: [Email], + }) email_addresses?: Email[]; + + @ApiPropertyOptional({ + description: 'The addresses of the company', + type: [Address], + }) addresses?: Address[]; + + @ApiPropertyOptional({ + description: 'The phone numbers of the company', + type: [Phone], + }) phone_numbers?: Phone[]; @ApiPropertyOptional({ diff --git a/packages/api/src/crm/contact/services/attio/mappers.ts b/packages/api/src/crm/contact/services/attio/mappers.ts index bbb9397bd..62a871bb6 100644 --- a/packages/api/src/crm/contact/services/attio/mappers.ts +++ b/packages/api/src/crm/contact/services/attio/mappers.ts @@ -25,13 +25,6 @@ export class AttioContactMapper implements IContactMapper { const primaryEmail = source.email_addresses?.[0]?.email_address; const primaryPhone = source.phone_numbers?.[0]?.phone_number; - // const emailObject = primaryEmail - // ? [{ value: primaryEmail, primary: true, label: '' }] - // : []; - // const phoneObject = primaryPhone - // ? [{ value: primaryPhone, primary: true, label: '' }] - // : []; - const result: AttioContactInput = { values: { name: [ @@ -41,11 +34,17 @@ export class AttioContactMapper implements IContactMapper { full_name: `${source.first_name} ${source.last_name}`, }, ], - email_addresses: [{ email_address: primaryEmail }], - phone_numbers: [{ original_phone_number: primaryPhone }], }, }; + if (primaryEmail) { + result.values.email_addresses = [{ email_address: primaryEmail }]; + } + + if (primaryPhone) { + result.values.phone_numbers = [{ original_phone_number: primaryPhone }]; + } + // if (source.user_id) { // const owner = await this.utils.getUser(source.user_id); // if (owner) { diff --git a/packages/api/src/crm/contact/services/contact.service.ts b/packages/api/src/crm/contact/services/contact.service.ts index 986e233ed..44aea31a7 100644 --- a/packages/api/src/crm/contact/services/contact.service.ts +++ b/packages/api/src/crm/contact/services/contact.service.ts @@ -90,6 +90,10 @@ export class ContactService { : [], }); + this.logger.log( + 'desunified obect is ' + JSON.stringify(desunifiedObject), + ); + const service: IContactService = this.serviceRegistry.getService(integrationId); const resp: ApiResponse = await service.addContact( diff --git a/packages/api/src/crm/contact/services/hubspot/mappers.ts b/packages/api/src/crm/contact/services/hubspot/mappers.ts index ecad3aa8d..3b700466c 100644 --- a/packages/api/src/crm/contact/services/hubspot/mappers.ts +++ b/packages/api/src/crm/contact/services/hubspot/mappers.ts @@ -27,10 +27,15 @@ export class HubspotContactMapper implements IContactMapper { const result: HubspotContactInput = { firstname: source.first_name, lastname: source.last_name, - email: primaryEmail, - phone: primaryPhone, }; + if (primaryEmail) { + result.email = primaryEmail; + } + if (primaryPhone) { + result.phone = primaryPhone; + } + if (source.user_id) { const owner_id = await this.utils.getRemoteIdFromUserUuid(source.user_id); if (owner_id) { diff --git a/packages/api/src/crm/contact/services/zendesk/index.ts b/packages/api/src/crm/contact/services/zendesk/index.ts index 4d96e4396..e815ec19b 100644 --- a/packages/api/src/crm/contact/services/zendesk/index.ts +++ b/packages/api/src/crm/contact/services/zendesk/index.ts @@ -86,15 +86,18 @@ export class ZendeskService implements IContactService { )}`, }, }); - const finalData = resp.data.items - .filter((item) => item.is_organization === false) - .map((item) => { - return item.data; - }); + + const finalData: any[] = resp.data.items.map((item) => { + return item.data; + }); + const filteredData = finalData.filter( + (item) => item.is_organization === false, + ); + this.logger.log(`Synced zendesk contacts !`); return { - data: finalData, + data: filteredData, message: 'Zendesk contacts retrieved', statusCode: 200, }; diff --git a/packages/api/src/crm/contact/services/zendesk/mappers.ts b/packages/api/src/crm/contact/services/zendesk/mappers.ts index 880c20ae6..42df87483 100644 --- a/packages/api/src/crm/contact/services/zendesk/mappers.ts +++ b/packages/api/src/crm/contact/services/zendesk/mappers.ts @@ -29,16 +29,24 @@ export class ZendeskContactMapper implements IContactMapper { name: `${source.first_name} ${source.last_name}`, first_name: source.first_name, last_name: source.last_name, - email: primaryEmail, - phone: primaryPhone, - address: { + }; + + if (primaryEmail) { + result.email = primaryEmail; + } + if (primaryPhone) { + result.phone = primaryPhone; + } + if (source.addresses && source.addresses[0]) { + result.address = { line1: source.addresses[0].street_1, city: source.addresses[0].city, state: source.addresses[0].state, postal_code: source.addresses[0].postal_code, country: source.addresses[0].country, - }, - }; + }; + } + if (source.user_id) { const owner_id = await this.utils.getRemoteIdFromUserUuid(source.user_id); if (owner_id) { diff --git a/packages/api/src/crm/contact/services/zoho/mappers.ts b/packages/api/src/crm/contact/services/zoho/mappers.ts index 58238f717..84c290cfc 100644 --- a/packages/api/src/crm/contact/services/zoho/mappers.ts +++ b/packages/api/src/crm/contact/services/zoho/mappers.ts @@ -21,15 +21,20 @@ export class ZohoContactMapper implements IContactMapper { const result: ZohoContactInput = { First_Name: source.first_name, Last_Name: source.last_name, - Email: primaryEmail, - Phone: primaryPhone, - Mailing_Street: source.addresses[0].street_1, - Mailing_City: source.addresses[0].city, - Mailing_State: source.addresses[0].state, - Mailing_Zip: source.addresses[0].postal_code, - Mailing_Country: source.addresses[0].country, }; - + if (primaryEmail) { + result.Email = primaryEmail; + } + if (primaryPhone) { + result.Phone = primaryPhone; + } + if (source.addresses && source.addresses[0]) { + result.Mailing_Street = source.addresses[0].street_1; + result.Mailing_City = source.addresses[0].city; + result.Mailing_State = source.addresses[0].state; + result.Mailing_Zip = source.addresses[0].postal_code; + result.Mailing_Country = source.addresses[0].country; + } if (customFieldMappings && source.field_mappings) { for (const fieldMapping of source.field_mappings) { for (const key in fieldMapping) { diff --git a/packages/api/src/crm/contact/sync/sync.service.ts b/packages/api/src/crm/contact/sync/sync.service.ts index f8188b7d2..ceca97bd9 100644 --- a/packages/api/src/crm/contact/sync/sync.service.ts +++ b/packages/api/src/crm/contact/sync/sync.service.ts @@ -47,50 +47,44 @@ export class SyncContactsService implements OnModuleInit { async syncContacts() { try { this.logger.log(`Syncing contacts....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = CRM_PROVIDERS.filter( - (provider) => provider !== 'zoho' && provider !== 'freshsales', - ); - for (const provider of providers) { - try { - await this.syncContactsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = CRM_PROVIDERS.filter( + (provider) => provider !== 'zoho', + ); + for (const provider of providers) { + try { + await this.syncContactsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/crm/contact/types/model.unified.ts b/packages/api/src/crm/contact/types/model.unified.ts index 4a7cf3afc..37a306fbc 100644 --- a/packages/api/src/crm/contact/types/model.unified.ts +++ b/packages/api/src/crm/contact/types/model.unified.ts @@ -8,19 +8,19 @@ export class UnifiedContactInput { @ApiProperty({ description: 'The last name of the contact' }) last_name: string; - @ApiProperty({ + @ApiPropertyOptional({ type: [Email], description: 'The email addresses of the contact', }) email_addresses: Email[]; - @ApiProperty({ + @ApiPropertyOptional({ type: [Phone], description: 'The phone numbers of the contact', }) phone_numbers: Phone[]; - @ApiProperty({ + @ApiPropertyOptional({ type: [Address], description: 'The addresses of the contact', }) diff --git a/packages/api/src/crm/deal/services/zendesk/mappers.ts b/packages/api/src/crm/deal/services/zendesk/mappers.ts index 69584b6b7..8fab58851 100644 --- a/packages/api/src/crm/deal/services/zendesk/mappers.ts +++ b/packages/api/src/crm/deal/services/zendesk/mappers.ts @@ -23,11 +23,14 @@ export class ZendeskDealMapper implements IDealMapper { const result: ZendeskDealInput = { name: source.name, value: source.amount, - contact_id: Number( - await this.utils.getRemoteIdFromCompanyUuid(source.company_id), - ), }; + if (source.company_id) { + result.contact_id = Number( + await this.utils.getRemoteIdFromCompanyUuid(source.company_id), + ); + } + if (source.user_id) { const owner_id = await this.utils.getRemoteIdFromUserUuid(source.user_id); if (owner_id) { diff --git a/packages/api/src/crm/deal/sync/sync.service.ts b/packages/api/src/crm/deal/sync/sync.service.ts index 1c3a3b068..3d3be3e1c 100644 --- a/packages/api/src/crm/deal/sync/sync.service.ts +++ b/packages/api/src/crm/deal/sync/sync.service.ts @@ -42,50 +42,44 @@ export class SyncService implements OnModuleInit { async syncDeals() { try { this.logger.log(`Syncing deals....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = CRM_PROVIDERS.filter( - (provider) => provider !== 'zoho' && provider !== 'freshsales', - ); - for (const provider of providers) { - try { - await this.syncDealsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = CRM_PROVIDERS.filter( + (provider) => provider !== 'zoho', + ); + for (const provider of providers) { + try { + await this.syncDealsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/crm/deal/types/model.unified.ts b/packages/api/src/crm/deal/types/model.unified.ts index 0af200e81..c081c2ea6 100644 --- a/packages/api/src/crm/deal/types/model.unified.ts +++ b/packages/api/src/crm/deal/types/model.unified.ts @@ -1,12 +1,28 @@ -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class UnifiedDealInput { + @ApiProperty({ description: 'The name of the deal' }) name: string; + + @ApiProperty({ description: 'The description of the deal' }) description: string; + + @ApiProperty({ description: 'The amount of the deal' }) amount: number; + + @ApiPropertyOptional({ + description: 'The uuid of the user who is on the deal', + }) user_id?: string; + + @ApiPropertyOptional({ description: 'The uuid of the stage of the deal' }) stage_id?: string; + + @ApiPropertyOptional({ + description: 'The uuid of the company tied to the deal', + }) company_id?: string; + @ApiPropertyOptional({ type: [{}], description: diff --git a/packages/api/src/crm/engagement/services/hubspot/mappers.ts b/packages/api/src/crm/engagement/services/hubspot/mappers.ts index 287611bd6..6af942164 100644 --- a/packages/api/src/crm/engagement/services/hubspot/mappers.ts +++ b/packages/api/src/crm/engagement/services/hubspot/mappers.ts @@ -57,7 +57,7 @@ export class HubspotEngagementMapper implements IEngagementMapper { // Assuming direction is used to determine call status hs_call_status: '', hs_call_duration: '', // Needs appropriate mapping - hs_call_direction: source.direction, // Needs appropriate mapping + hs_call_direction: source.direction || '', // Needs appropriate mapping hubspot_owner_id: '', hs_call_to_number: '', // Needs appropriate mapping hs_call_from_number: '', // Needs appropriate mapping diff --git a/packages/api/src/crm/engagement/services/zendesk/mappers.ts b/packages/api/src/crm/engagement/services/zendesk/mappers.ts index 84f4adeb3..84189be9b 100644 --- a/packages/api/src/crm/engagement/services/zendesk/mappers.ts +++ b/packages/api/src/crm/engagement/services/zendesk/mappers.ts @@ -43,12 +43,16 @@ export class ZendeskEngagementMapper implements IEngagementMapper { }[], ): Promise { const result: ZendeskEngagementInput = { - summary: source.content, + summary: source.content || '', incoming: source.direction === 'incoming', // Example mapping - made_at: source.start_at?.toISOString(), - updated_at: source.end_time?.toISOString(), }; + if (source.start_at && source.end_time) { + // TODO; compute a date difference instead of raw difference + result.duration = + source.end_time.getSeconds() - source.start_at.getSeconds(); + } + if (source.user_id) { const owner_id = await this.utils.getRemoteIdFromUserUuid(source.user_id); if (owner_id) { diff --git a/packages/api/src/crm/engagement/sync/sync.service.ts b/packages/api/src/crm/engagement/sync/sync.service.ts index 72f6a96a3..2e69d00fd 100644 --- a/packages/api/src/crm/engagement/sync/sync.service.ts +++ b/packages/api/src/crm/engagement/sync/sync.service.ts @@ -44,53 +44,47 @@ export class SyncService implements OnModuleInit { async syncEngagements() { try { this.logger.log(`Syncing engagements....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = CRM_PROVIDERS.filter( - (provider) => provider !== 'zoho' && provider !== 'freshsales', - ); - for (const provider of providers) { - try { - for (const type of ENGAGEMENTS_TYPE) { - await this.syncEngagementsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - type, + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = CRM_PROVIDERS.filter( + (provider) => provider !== 'zoho', ); + for (const provider of providers) { + try { + for (const type of ENGAGEMENTS_TYPE) { + await this.syncEngagementsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + type, + ); + } + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); } - } catch (error) { - handleServiceError(error, this.logger); - } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/crm/engagement/types/model.unified.ts b/packages/api/src/crm/engagement/types/model.unified.ts index 27273df05..62a6163d2 100644 --- a/packages/api/src/crm/engagement/types/model.unified.ts +++ b/packages/api/src/crm/engagement/types/model.unified.ts @@ -1,15 +1,42 @@ -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class UnifiedEngagementInput { + @ApiPropertyOptional({ description: 'The content of the engagement' }) content?: string; + + @ApiPropertyOptional({ description: 'The direction of the engagement' }) direction?: string; + + @ApiPropertyOptional({ description: 'The subject of the engagement' }) subject?: string; + + @ApiPropertyOptional({ description: 'The start time of the engagement' }) start_at?: Date; + + @ApiPropertyOptional({ description: 'The end time of the engagement' }) end_time?: Date; + + @ApiProperty({ + description: + 'The type of the engagement. Authorized values are EMAIL, CALL or MEETING', + }) type: string; + + @ApiPropertyOptional({ + description: 'The uuid of the user tied to the engagement', + }) user_id?: string; + + @ApiPropertyOptional({ + description: 'The uuid of the company tied to the engagement', + }) company_id?: string; // uuid of Company object + + @ApiPropertyOptional({ + description: 'The uuids of contacts tied to the engagement object', + }) contacts?: string[]; // array of uuids of Engagement Contacts objects + @ApiPropertyOptional({ type: [{}], description: diff --git a/packages/api/src/crm/note/sync/sync.service.ts b/packages/api/src/crm/note/sync/sync.service.ts index f6283c345..2bcdb5b2f 100644 --- a/packages/api/src/crm/note/sync/sync.service.ts +++ b/packages/api/src/crm/note/sync/sync.service.ts @@ -42,50 +42,44 @@ export class SyncService implements OnModuleInit { async syncNotes() { try { this.logger.log(`Syncing notes....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = CRM_PROVIDERS.filter( - (provider) => provider !== 'zoho' && provider !== 'freshsales', - ); - for (const provider of providers) { - try { - await this.syncNotesForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = CRM_PROVIDERS.filter( + (provider) => provider !== 'zoho', + ); + for (const provider of providers) { + try { + await this.syncNotesForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/crm/note/types/model.unified.ts b/packages/api/src/crm/note/types/model.unified.ts index 854801a9c..420b9844e 100644 --- a/packages/api/src/crm/note/types/model.unified.ts +++ b/packages/api/src/crm/note/types/model.unified.ts @@ -1,11 +1,25 @@ -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class UnifiedNoteInput { + @ApiProperty({ description: 'The content of the note' }) content: string; + + @ApiPropertyOptional({ description: 'The uuid of the user tied the note' }) user_id?: string; + + @ApiPropertyOptional({ + description: 'The uuid of the company tied to the note', + }) company_id?: string; + + @ApiPropertyOptional({ + description: 'The uuid fo the contact tied to the note', + }) contact_id?: string; + + @ApiPropertyOptional({ description: 'The uuid of the deal tied to the note' }) deal_id?: string; + @ApiPropertyOptional({ type: [{}], description: diff --git a/packages/api/src/crm/stage/services/zendesk/index.ts b/packages/api/src/crm/stage/services/zendesk/index.ts index 70db655dc..015f5930a 100644 --- a/packages/api/src/crm/stage/services/zendesk/index.ts +++ b/packages/api/src/crm/stage/services/zendesk/index.ts @@ -59,7 +59,7 @@ export class ZendeskService implements IStageService { }, }); - const finalData = resp.data.items.find( + const finalData = (resp.data.items as any[]).find( (item) => item.data.id === stage_remote_id, ); diff --git a/packages/api/src/crm/stage/sync/sync.service.ts b/packages/api/src/crm/stage/sync/sync.service.ts index 40fee0958..6b76601ef 100644 --- a/packages/api/src/crm/stage/sync/sync.service.ts +++ b/packages/api/src/crm/stage/sync/sync.service.ts @@ -42,64 +42,58 @@ export class SyncService implements OnModuleInit { async syncStages() { try { this.logger.log(`Syncing stages....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = CRM_PROVIDERS.filter( - (provider) => provider !== 'zoho' && provider !== 'freshsales', - ); - for (const provider of providers) { - try { + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { try { - //call the sync comments for every ticket of the linkedUser (a comment is tied to a ticket) - const deals = await this.prisma.crm_deals.findMany({ - where: { - remote_platform: provider, - id_linked_user: linkedUser.id_linked_user, - }, - }); - for (const deal of deals) { - await this.syncStagesForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - deal.id_crm_deal, - ); + const providers = CRM_PROVIDERS.filter( + (provider) => provider !== 'zoho', + ); + for (const provider of providers) { + try { + try { + //call the sync comments for every ticket of the linkedUser (a comment is tied to a ticket) + const deals = await this.prisma.crm_deals.findMany({ + where: { + remote_platform: provider, + id_linked_user: linkedUser.id_linked_user, + }, + }); + for (const deal of deals) { + await this.syncStagesForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + deal.id_crm_deal, + ); + } + } catch (error) { + handleServiceError(error, this.logger); + } + } catch (error) { + handleServiceError(error, this.logger); + } } } catch (error) { handleServiceError(error, this.logger); } - } catch (error) { - handleServiceError(error, this.logger); - } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/crm/stage/types/model.unified.ts b/packages/api/src/crm/stage/types/model.unified.ts index d8d304db2..2974fc575 100644 --- a/packages/api/src/crm/stage/types/model.unified.ts +++ b/packages/api/src/crm/stage/types/model.unified.ts @@ -1,7 +1,9 @@ -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class UnifiedStageInput { + @ApiProperty({ description: 'The name of the stage' }) stage_name: string; + @ApiPropertyOptional({ type: [{}], description: diff --git a/packages/api/src/crm/task/services/zendesk/index.ts b/packages/api/src/crm/task/services/zendesk/index.ts index 9cdecad10..c317b32f5 100644 --- a/packages/api/src/crm/task/services/zendesk/index.ts +++ b/packages/api/src/crm/task/services/zendesk/index.ts @@ -9,7 +9,6 @@ import { ActionType, handleServiceError } from '@@core/utils/errors'; import { EncryptionService } from '@@core/encryption/encryption.service'; import { ApiResponse } from '@@core/utils/types'; import { ServiceRegistry } from '../registry.service'; -import { OriginalTaskOutput } from '@@core/utils/types/original/original.crm'; @Injectable() export class ZendeskService implements ITaskService { constructor( diff --git a/packages/api/src/crm/task/sync/sync.service.ts b/packages/api/src/crm/task/sync/sync.service.ts index 3f18c20c3..b19c4c79e 100644 --- a/packages/api/src/crm/task/sync/sync.service.ts +++ b/packages/api/src/crm/task/sync/sync.service.ts @@ -42,50 +42,44 @@ export class SyncService implements OnModuleInit { async syncTasks() { try { this.logger.log(`Syncing tasks....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = CRM_PROVIDERS.filter( - (provider) => provider !== 'zoho' && provider !== 'freshsales', - ); - for (const provider of providers) { - try { - await this.syncTasksForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = CRM_PROVIDERS.filter( + (provider) => provider !== 'zoho', + ); + for (const provider of providers) { + try { + await this.syncTasksForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/crm/task/types/model.unified.ts b/packages/api/src/crm/task/types/model.unified.ts index 7687820f0..2e7511a4a 100644 --- a/packages/api/src/crm/task/types/model.unified.ts +++ b/packages/api/src/crm/task/types/model.unified.ts @@ -1,13 +1,33 @@ -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class UnifiedTaskInput { - subject?: string; - content?: string; - status?: string; + @ApiProperty({ description: 'The subject of the task' }) + subject: string; + + @ApiProperty({ description: 'The content of the task' }) + content: string; + + @ApiProperty({ + description: + 'The status of the task. Authorized values are "Completed" and "Not Completed" ', + }) + status: string; + + @ApiPropertyOptional({ description: 'The due date of the task' }) due_date?: Date; + + @ApiPropertyOptional({ description: 'The finished date of the task' }) finished_date?: Date; + + @ApiPropertyOptional({ description: 'The uuid of the user tied to the task' }) user_id?: string; + + @ApiPropertyOptional({ + description: 'The uuid fo the company tied to the task', + }) company_id?: string; + + @ApiPropertyOptional({ description: 'The uuid of the deal tied to the task' }) deal_id?: string; @ApiPropertyOptional({ diff --git a/packages/api/src/crm/user/sync/sync.service.ts b/packages/api/src/crm/user/sync/sync.service.ts index 9d473ad73..0bf7b8f4a 100644 --- a/packages/api/src/crm/user/sync/sync.service.ts +++ b/packages/api/src/crm/user/sync/sync.service.ts @@ -41,50 +41,44 @@ export class SyncService implements OnModuleInit { async syncUsers() { try { this.logger.log(`Syncing users....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = CRM_PROVIDERS.filter( - (provider) => provider !== 'zoho' && provider !== 'freshsales', - ); - for (const provider of providers) { - try { - await this.syncUsersForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = CRM_PROVIDERS.filter( + (provider) => provider !== 'zoho', + ); + for (const provider of providers) { + try { + await this.syncUsersForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/crm/user/types/model.unified.ts b/packages/api/src/crm/user/types/model.unified.ts index d1a220bef..7fb8a206a 100644 --- a/packages/api/src/crm/user/types/model.unified.ts +++ b/packages/api/src/crm/user/types/model.unified.ts @@ -1,8 +1,11 @@ -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class UnifiedUserInput { - name?: string; - email?: string; + @ApiProperty({ description: 'The name of the user' }) + name: string; + + @ApiProperty({ description: 'The email of the user' }) + email: string; @ApiPropertyOptional({ type: [{}], diff --git a/packages/api/src/ticketing/account/account.module.ts b/packages/api/src/ticketing/account/account.module.ts index 6df3fb0cd..b8c7862f7 100644 --- a/packages/api/src/ticketing/account/account.module.ts +++ b/packages/api/src/ticketing/account/account.module.ts @@ -9,6 +9,8 @@ import { FieldMappingService } from '@@core/field-mapping/field-mapping.service' import { PrismaService } from '@@core/prisma/prisma.service'; import { WebhookService } from '@@core/webhook/webhook.service'; import { BullModule } from '@nestjs/bull'; +import { ZendeskService } from './services/zendesk'; +import { FrontService } from './services/front'; @Module({ imports: [ @@ -27,6 +29,8 @@ import { BullModule } from '@nestjs/bull'; FieldMappingService, ServiceRegistry, /* PROVIDERS SERVICES */ + ZendeskService, + FrontService, ], exports: [SyncService], }) diff --git a/packages/api/src/ticketing/account/services/github/index.ts b/packages/api/src/ticketing/account/services/github/index.ts deleted file mode 100644 index ab398e186..000000000 --- a/packages/api/src/ticketing/account/services/github/index.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { LoggerService } from '@@core/logger/logger.service'; -import { PrismaService } from '@@core/prisma/prisma.service'; -import { EncryptionService } from '@@core/encryption/encryption.service'; -import { TicketingObject } from '@ticketing/@utils/@types'; -import { ApiResponse } from '@@core/utils/types'; -import axios from 'axios'; -import { ActionType, handleServiceError } from '@@core/utils/errors'; -import { ServiceRegistry } from '../registry.service'; -import { IAccountService } from '@ticketing/account/types'; -import { GithubAccountOutput } from './types'; - -@Injectable() -export class GithubService implements IAccountService { - constructor( - private prisma: PrismaService, - private logger: LoggerService, - private cryptoService: EncryptionService, - private registry: ServiceRegistry, - ) { - this.logger.setContext( - TicketingObject.account.toUpperCase() + ':' + GithubService.name, - ); - this.registry.registerService('github', this); - } - - async syncAccounts( - linkedUserId: string, - custom_properties?: string[], - ): Promise> { - try { - const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'github', - vertical: 'ticketing', - }, - }); - const resp = await axios.get(`${connection.account_url}/user/orgs`, { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }); - this.logger.log(`Synced github accounts (organizations) !`); - - return { - data: resp.data, - message: 'Github accounts retrieved', - statusCode: 200, - }; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Github', - TicketingObject.account, - ActionType.GET, - ); - } - } -} diff --git a/packages/api/src/ticketing/account/services/github/mappers.ts b/packages/api/src/ticketing/account/services/github/mappers.ts deleted file mode 100644 index b7ec4e143..000000000 --- a/packages/api/src/ticketing/account/services/github/mappers.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { IAccountMapper } from '@ticketing/account/types'; -import { GithubAccountInput, GithubAccountOutput } from './types'; -import { - UnifiedAccountInput, - UnifiedAccountOutput, -} from '@ticketing/account/types/model.unified'; - -export class GithubAccountMapper implements IAccountMapper { - desunify( - source: UnifiedAccountInput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): GithubAccountInput { - return; - } - - unify( - source: GithubAccountOutput | GithubAccountOutput[], - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedAccountOutput | UnifiedAccountOutput[] { - if (!Array.isArray(source)) { - return this.mapSingleAccountToUnified(source, customFieldMappings); - } - return source.map((ticket) => - this.mapSingleAccountToUnified(ticket, customFieldMappings), - ); - } - - private mapSingleAccountToUnified( - account: GithubAccountOutput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedAccountOutput { - const unifiedAccount: UnifiedAccountOutput = { - name: account.login, - domains: [ - account.events_url, - account.hooks_url, - account.issues_url, - account.members_url, - account.public_members_url, - account.repos_url, - ], - }; - return unifiedAccount; - } -} diff --git a/packages/api/src/ticketing/account/services/github/types.ts b/packages/api/src/ticketing/account/services/github/types.ts deleted file mode 100644 index 7531eb14e..000000000 --- a/packages/api/src/ticketing/account/services/github/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -export type GithubAccountInput = { - login: string; - id: number; - node_id: string; - url: string; - repos_url: string; - events_url: string; - hooks_url: string; - issues_url: string; - members_url: string; - public_members_url: string; - avatar_url: string; - description: string | null; -}; - -export type GithubAccountOutput = GithubAccountInput; diff --git a/packages/api/src/ticketing/account/sync/sync.service.ts b/packages/api/src/ticketing/account/sync/sync.service.ts index 8f0854517..10034c5a8 100644 --- a/packages/api/src/ticketing/account/sync/sync.service.ts +++ b/packages/api/src/ticketing/account/sync/sync.service.ts @@ -42,55 +42,49 @@ export class SyncService implements OnModuleInit { async syncAccounts() { try { this.logger.log(`Syncing accounts....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedAccounts = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedAccounts.map(async (linkedAccount) => { - try { - const providers = TICKETING_PROVIDERS; - for (const provider of providers) { - try { - await this.syncAccountsForLinkedAccount( - provider, - linkedAccount.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = TICKETING_PROVIDERS; + for (const provider of providers) { + try { + await this.syncAccountsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } } //todo: HANDLE DATA REMOVED FROM PROVIDER - async syncAccountsForLinkedAccount( + async syncAccountsForLinkedUser( integrationId: string, linkedUserId: string, id_project: string, diff --git a/packages/api/src/ticketing/attachment/services/github/mappers.ts b/packages/api/src/ticketing/attachment/services/github/mappers.ts deleted file mode 100644 index 0fd35df71..000000000 --- a/packages/api/src/ticketing/attachment/services/github/mappers.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { IAttachmentMapper } from '@ticketing/attachment/types'; -import { - UnifiedAttachmentInput, - UnifiedAttachmentOutput, -} from '@ticketing/attachment/types/model.unified'; -import { GithubAttachmentOutput } from './types'; - -export class GithubAttachmentMapper implements IAttachmentMapper { - async desunify( - source: UnifiedAttachmentInput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): Promise { - return; - } - - unify( - source: GithubAttachmentOutput | GithubAttachmentOutput[], - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedAttachmentOutput | UnifiedAttachmentOutput[] { - if (!Array.isArray(source)) { - return this.mapSingleAttachmentToUnified(source, customFieldMappings); - } - return source.map((attachment) => - this.mapSingleAttachmentToUnified(attachment, customFieldMappings), - ); - } - - //TODO; - private mapSingleAttachmentToUnified( - attachment: GithubAttachmentOutput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedAttachmentOutput { - return; - } -} diff --git a/packages/api/src/ticketing/attachment/services/github/types.ts b/packages/api/src/ticketing/attachment/services/github/types.ts deleted file mode 100644 index 39b76d9cf..000000000 --- a/packages/api/src/ticketing/attachment/services/github/types.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type GithubAttachmentOutput = { - id: string; -}; diff --git a/packages/api/src/ticketing/collection/sync/sync.service.ts b/packages/api/src/ticketing/collection/sync/sync.service.ts index d95ff65d3..b8c4af4f8 100644 --- a/packages/api/src/ticketing/collection/sync/sync.service.ts +++ b/packages/api/src/ticketing/collection/sync/sync.service.ts @@ -42,48 +42,42 @@ export class SyncService implements OnModuleInit { async syncCollections() { try { this.logger.log(`Syncing collections....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = TICKETING_PROVIDERS; - for (const provider of providers) { - try { - await this.syncCollectionsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = TICKETING_PROVIDERS; + for (const provider of providers) { + try { + await this.syncCollectionsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/ticketing/comment/comment.module.ts b/packages/api/src/ticketing/comment/comment.module.ts index 11bef6ead..0747d1023 100644 --- a/packages/api/src/ticketing/comment/comment.module.ts +++ b/packages/api/src/ticketing/comment/comment.module.ts @@ -10,9 +10,7 @@ import { CommentController } from './comment.controller'; import { CommentService } from './services/comment.service'; import { FieldMappingService } from '@@core/field-mapping/field-mapping.service'; import { ServiceRegistry } from './services/registry.service'; -import { GithubService } from './services/github'; import { FrontService } from './services/front'; -import { HubspotService } from './services/hubspot'; import { JiraService } from './services/jira'; import { GorgiasService } from './services/gorgias'; @@ -34,9 +32,7 @@ import { GorgiasService } from './services/gorgias'; ServiceRegistry, /* PROVIDERS SERVICES */ ZendeskService, - HubspotService, FrontService, - GithubService, JiraService, GorgiasService, ], diff --git a/packages/api/src/ticketing/comment/services/comment.service.ts b/packages/api/src/ticketing/comment/services/comment.service.ts index 7b57ff0e5..a0588e759 100644 --- a/packages/api/src/ticketing/comment/services/comment.service.ts +++ b/packages/api/src/ticketing/comment/services/comment.service.ts @@ -340,7 +340,7 @@ export class CommentService { body: comment.body, html_body: comment.html_body, is_private: comment.is_private, - creator_type: comment.creator_type, + creator_type: comment.creator_type as 'user' | 'contact', ticket_id: comment.id_tcg_ticket, contact_id: comment.id_tcg_contact, // uuid of Contact object user_id: comment.id_tcg_user, // uuid of User object @@ -418,7 +418,7 @@ export class CommentService { body: comment.body, html_body: comment.html_body, is_private: comment.is_private, - creator_type: comment.creator_type, + creator_type: comment.creator_type as 'user' | 'contact', ticket_id: comment.id_tcg_ticket, contact_id: comment.id_tcg_contact, // uuid of Contact object user_id: comment.id_tcg_user, // uuid of User object diff --git a/packages/api/src/ticketing/comment/services/github/index.ts b/packages/api/src/ticketing/comment/services/github/index.ts deleted file mode 100644 index 27aec9186..000000000 --- a/packages/api/src/ticketing/comment/services/github/index.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { LoggerService } from '@@core/logger/logger.service'; -import { PrismaService } from '@@core/prisma/prisma.service'; -import { EncryptionService } from '@@core/encryption/encryption.service'; -import { ApiResponse } from '@@core/utils/types'; -import { DesunifyReturnType } from '@@core/utils/types/desunify.input'; -import axios from 'axios'; -import { ActionType, handleServiceError } from '@@core/utils/errors'; -import { ICommentService } from '@ticketing/comment/types'; -import { TicketingObject } from '@ticketing/@utils/@types'; -import { OriginalCommentOutput } from '@@core/utils/types/original/original.ticketing'; -import { ServiceRegistry } from '../registry.service'; -import { GithubCommentInput, GithubCommentOutput } from './types'; - -@Injectable() -export class GithubService implements ICommentService { - constructor( - private prisma: PrismaService, - private logger: LoggerService, - private cryptoService: EncryptionService, - private registry: ServiceRegistry, - ) { - this.logger.setContext( - TicketingObject.comment.toUpperCase() + ':' + GithubService.name, - ); - this.registry.registerService('github', this); - } - async addComment( - commentData: GithubCommentInput, - linkedUserId: string, - remoteIdTicket: string, - ): Promise> { - try { - const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'github', - vertical: 'ticketing', - }, - }); - const dataBody = { - comment: commentData, - }; - const resp = await axios.post( - `${connection.account_url}conversations/${remoteIdTicket}/comments`, - JSON.stringify(dataBody), - { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }, - ); - return { - data: resp.data, - message: 'Github comment created', - statusCode: 201, - }; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Github', - TicketingObject.comment, - ActionType.POST, - ); - } - } - async syncComments( - linkedUserId: string, - id_ticket: string, - ): Promise> { - try { - const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'github', - vertical: 'ticketing', - }, - }); - //retrieve ticket remote id so we can retrieve the comments in the original software - const ticket = await this.prisma.tcg_tickets.findUnique({ - where: { - id_tcg_ticket: id_ticket, - }, - select: { - remote_id: true, - }, - }); - - const resp = await axios.get( - `${connection.account_url}/conversations/${ticket.remote_id}/comments`, - { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }, - ); - this.logger.log(`Synced github comments !`); - - return { - data: resp.data._results, - message: 'Front github retrieved', - statusCode: 200, - }; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Github', - TicketingObject.comment, - ActionType.GET, - ); - } - } -} diff --git a/packages/api/src/ticketing/comment/services/github/mappers.ts b/packages/api/src/ticketing/comment/services/github/mappers.ts deleted file mode 100644 index 048fe09d1..000000000 --- a/packages/api/src/ticketing/comment/services/github/mappers.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ICommentMapper } from '@ticketing/comment/types'; -import { - UnifiedCommentInput, - UnifiedCommentOutput, -} from '@ticketing/comment/types/model.unified'; -import { GithubCommentInput, GithubCommentOutput } from './types'; - -export class GithubCommentMapper implements ICommentMapper { - desunify( - source: UnifiedCommentInput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): GithubCommentInput { - //TODO - return; - } - - async unify( - source: GithubCommentOutput | GithubCommentOutput[], - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): Promise { - if (!Array.isArray(source)) { - return this.mapSingleCommentToUnified(source, customFieldMappings); - } - return source.map((comment) => - this.mapSingleCommentToUnified(comment, customFieldMappings), - ); - } - - private mapSingleCommentToUnified( - comment: GithubCommentOutput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedCommentOutput { - /*TODO const field_mappings = customFieldMappings.map((mapping) => ({ - [mapping.slug]: comment.custom_fields[mapping.remote_id], - }));*/ - return; - } -} diff --git a/packages/api/src/ticketing/comment/services/github/types.ts b/packages/api/src/ticketing/comment/services/github/types.ts deleted file mode 100644 index bcc9d9ec5..000000000 --- a/packages/api/src/ticketing/comment/services/github/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type GithubCommentInput = { - id: string; -}; - -export type GithubCommentOutput = GithubCommentInput; diff --git a/packages/api/src/ticketing/comment/services/hubspot/index.ts b/packages/api/src/ticketing/comment/services/hubspot/index.ts deleted file mode 100644 index f844a1383..000000000 --- a/packages/api/src/ticketing/comment/services/hubspot/index.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { LoggerService } from '@@core/logger/logger.service'; -import { PrismaService } from '@@core/prisma/prisma.service'; -import { EncryptionService } from '@@core/encryption/encryption.service'; -import { ApiResponse } from '@@core/utils/types'; -import { DesunifyReturnType } from '@@core/utils/types/desunify.input'; -import axios from 'axios'; -import { ActionType, handleServiceError } from '@@core/utils/errors'; -import { ICommentService } from '@ticketing/comment/types'; -import { TicketingObject } from '@ticketing/@utils/@types'; -import { OriginalCommentOutput } from '@@core/utils/types/original/original.ticketing'; -import { ServiceRegistry } from '../registry.service'; -import { HubspotCommentInput, HubspotCommentOutput } from './types'; - -@Injectable() -export class HubspotService implements ICommentService { - constructor( - private prisma: PrismaService, - private logger: LoggerService, - private cryptoService: EncryptionService, - private registry: ServiceRegistry, - ) { - this.logger.setContext( - TicketingObject.comment.toUpperCase() + ':' + HubspotService.name, - ); - this.registry.registerService('hubspot_t', this); - } - async addComment( - commentData: HubspotCommentInput, - linkedUserId: string, - remoteIdTicket: string, - ): Promise> { - try { - /*const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'hubspot_t', - }, - }); - const dataBody = { - comment: commentData, - }; - const resp = await axios.post( - `https://api2.frontapp.com/conversations/${remoteIdTicket}/comments`, - JSON.stringify(dataBody), - { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }, - ); - return { - data: resp.data, - message: 'Hubspot comment created', - statusCode: 201, - };*/ - return; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Hubspot', - TicketingObject.comment, - ActionType.POST, - ); - } - } - async syncComments( - linkedUserId: string, - id_ticket: string, - ): Promise> { - try { - /*const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'hubspot_t', - }, - }); - //retrieve ticket remote id so we can retrieve the comments in the original software - const ticket = await this.prisma.tcg_tickets.findUnique({ - where: { - id_tcg_ticket: id_ticket, - }, - select: { - remote_id: true, - }, - }); - - const resp = await axios.get( - `https://api2.frontapp.com/conversations/${ticket.remote_id}/comments`, - { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }, - ); - this.logger.log(`Synced hubspot comments !`); - - return { - data: resp.data._results, - message: 'Hubspot comments retrieved', - statusCode: 200, - };*/ - return; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Hubspot', - TicketingObject.comment, - ActionType.GET, - ); - } - } -} diff --git a/packages/api/src/ticketing/comment/services/hubspot/mappers.ts b/packages/api/src/ticketing/comment/services/hubspot/mappers.ts deleted file mode 100644 index e6b306658..000000000 --- a/packages/api/src/ticketing/comment/services/hubspot/mappers.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ICommentMapper } from '@ticketing/comment/types'; -import { - UnifiedCommentInput, - UnifiedCommentOutput, -} from '@ticketing/comment/types/model.unified'; -import { HubspotCommentInput, HubspotCommentOutput } from './types'; - -//TODO: HUBSPOT DOES NOT HAVE A COMMENT ENDPOINT -export class HubspotCommentMapper implements ICommentMapper { - desunify( - source: UnifiedCommentInput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): HubspotCommentInput { - //TODO - return; - } - - async unify( - source: HubspotCommentOutput | HubspotCommentOutput[], - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): Promise { - if (!Array.isArray(source)) { - return this.mapSingleCommentToUnified(source, customFieldMappings); - } - return source.map((comment) => - this.mapSingleCommentToUnified(comment, customFieldMappings), - ); - } - - private mapSingleCommentToUnified( - comment: HubspotCommentOutput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedCommentOutput { - /*TODO const field_mappings = customFieldMappings.map((mapping) => ({ - [mapping.slug]: comment.custom_fields[mapping.remote_id], - }));*/ - return; - } -} diff --git a/packages/api/src/ticketing/comment/services/hubspot/types.ts b/packages/api/src/ticketing/comment/services/hubspot/types.ts deleted file mode 100644 index d3ec77b6f..000000000 --- a/packages/api/src/ticketing/comment/services/hubspot/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type HubspotCommentInput = { - id: string; -}; - -export type HubspotCommentOutput = HubspotCommentInput; diff --git a/packages/api/src/ticketing/comment/services/jira/mappers.ts b/packages/api/src/ticketing/comment/services/jira/mappers.ts index ffe3f3a23..7e16c588a 100644 --- a/packages/api/src/ticketing/comment/services/jira/mappers.ts +++ b/packages/api/src/ticketing/comment/services/jira/mappers.ts @@ -26,8 +26,10 @@ export class JiraCommentMapper implements ICommentMapper { ): Promise { const result: JiraCommentInput = { body: source.body, - attachments: source.attachments, }; + if (source.attachments) { + result.attachments = source.attachments; + } return result; } diff --git a/packages/api/src/ticketing/comment/services/zendesk/mappers.ts b/packages/api/src/ticketing/comment/services/zendesk/mappers.ts index cd680b476..25e8553ea 100644 --- a/packages/api/src/ticketing/comment/services/zendesk/mappers.ts +++ b/packages/api/src/ticketing/comment/services/zendesk/mappers.ts @@ -26,15 +26,24 @@ export class ZendeskCommentMapper implements ICommentMapper { ): Promise { const result: ZendeskCommentInput = { body: source.body, - html_body: source.html_body, - public: !source.is_private, - author_id: source.contact_id - ? Number(await this.utils.getContactRemoteIdFromUuid(source.contact_id)) - : Number(await this.utils.getUserRemoteIdFromUuid(source.user_id)), + public: source.is_private ? !source.is_private : true, type: 'Comment', - uploads: source.attachments, //we let the array of uuids on purpose (it will be modified in the given service on the fly!) }; + if (source.contact_id) { + result.author_id = source.contact_id + ? Number(await this.utils.getContactRemoteIdFromUuid(source.contact_id)) + : Number(await this.utils.getUserRemoteIdFromUuid(source.user_id)); + } + + if (source.attachments) { + result.uploads = source.attachments; //we let the array of uuids on purpose (it will be modified in the given service on the fly!) + } + + if (source.html_body) { + result.html_body = source.html_body; + } + return result; } diff --git a/packages/api/src/ticketing/comment/sync/sync.service.ts b/packages/api/src/ticketing/comment/sync/sync.service.ts index e8d943957..a630b4aa7 100644 --- a/packages/api/src/ticketing/comment/sync/sync.service.ts +++ b/packages/api/src/ticketing/comment/sync/sync.service.ts @@ -42,58 +42,52 @@ export class SyncService implements OnModuleInit { async syncComments() { try { this.logger.log(`Syncing comments....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = TICKETING_PROVIDERS; - for (const provider of providers) { - try { - //call the sync comments for every ticket of the linkedUser (a comment is tied to a ticket) - const tickets = await this.prisma.tcg_tickets.findMany({ - where: { - remote_platform: provider, - id_linked_user: linkedUser.id_linked_user, - }, - }); - for (const ticket of tickets) { - await this.syncCommentsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ticket.id_tcg_ticket, - ); + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = TICKETING_PROVIDERS; + for (const provider of providers) { + try { + //call the sync comments for every ticket of the linkedUser (a comment is tied to a ticket) + const tickets = await this.prisma.tcg_tickets.findMany({ + where: { + remote_platform: provider, + id_linked_user: linkedUser.id_linked_user, + }, + }); + for (const ticket of tickets) { + await this.syncCommentsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ticket.id_tcg_ticket, + ); + } + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); } - } catch (error) { - handleServiceError(error, this.logger); - } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/ticketing/comment/types/model.unified.ts b/packages/api/src/ticketing/comment/types/model.unified.ts index 2785791c7..56030c0ca 100644 --- a/packages/api/src/ticketing/comment/types/model.unified.ts +++ b/packages/api/src/ticketing/comment/types/model.unified.ts @@ -17,7 +17,7 @@ export class UnifiedCommentInput { @ApiPropertyOptional({ description: 'The creator type of the comment (either user or contact)', }) - creator_type: 'user' | 'contact' | null | string; + creator_type?: 'user' | 'contact'; @ApiPropertyOptional({ description: 'The uuid of the ticket the comment is tied to', diff --git a/packages/api/src/ticketing/contact/contact.module.ts b/packages/api/src/ticketing/contact/contact.module.ts index 4db82645c..ad2e375cd 100644 --- a/packages/api/src/ticketing/contact/contact.module.ts +++ b/packages/api/src/ticketing/contact/contact.module.ts @@ -11,7 +11,6 @@ import { ServiceRegistry } from './services/registry.service'; import { ContactService } from './services/contact.service'; import { ContactController } from './contact.controller'; import { FrontService } from './services/front'; -import { GithubService } from './services/github'; import { GorgiasService } from './services/gorgias'; @Module({ @@ -33,7 +32,6 @@ import { GorgiasService } from './services/gorgias'; /* PROVIDERS SERVICES */ ZendeskService, FrontService, - GithubService, GorgiasService, ], exports: [SyncService], diff --git a/packages/api/src/ticketing/contact/services/github/index.ts b/packages/api/src/ticketing/contact/services/github/index.ts deleted file mode 100644 index 6c27e0e2a..000000000 --- a/packages/api/src/ticketing/contact/services/github/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { LoggerService } from '@@core/logger/logger.service'; -import { PrismaService } from '@@core/prisma/prisma.service'; -import { EncryptionService } from '@@core/encryption/encryption.service'; -import { TicketingObject } from '@ticketing/@utils/@types'; -import { ApiResponse } from '@@core/utils/types'; -import axios from 'axios'; -import { ActionType, handleServiceError } from '@@core/utils/errors'; -import { ServiceRegistry } from '../registry.service'; -import { IContactService } from '@ticketing/contact/types'; -import { GithubContactOutput } from './types'; - -//TODO -@Injectable() -export class GithubService implements IContactService { - constructor( - private prisma: PrismaService, - private logger: LoggerService, - private cryptoService: EncryptionService, - private registry: ServiceRegistry, - ) { - this.logger.setContext( - TicketingObject.contact.toUpperCase() + ':' + GithubService.name, - ); - this.registry.registerService('github', this); - } - - async syncContacts( - linkedUserId: string, - custom_properties?: string[], - ): Promise> { - try { - const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'github', - vertical: 'ticketing', - }, - }); - const resp = await axios.get(`${connection.account_url}/contacts`, { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }); - this.logger.log(`Synced github contacts !`); - - return { - data: resp.data, - message: 'Github contacts retrieved', - statusCode: 200, - }; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Github', - TicketingObject.contact, - ActionType.GET, - ); - } - } -} diff --git a/packages/api/src/ticketing/contact/services/github/mappers.ts b/packages/api/src/ticketing/contact/services/github/mappers.ts deleted file mode 100644 index cd5d22f33..000000000 --- a/packages/api/src/ticketing/contact/services/github/mappers.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { IContactMapper } from '@ticketing/contact/types'; -import { GithubContactInput, GithubContactOutput } from './types'; -import { - UnifiedContactInput, - UnifiedContactOutput, -} from '@ticketing/contact/types/model.unified'; - -export class GithubContactMapper implements IContactMapper { - desunify( - source: UnifiedContactInput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): GithubContactInput { - return; - } - - unify( - source: GithubContactOutput | GithubContactOutput[], - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedContactOutput | UnifiedContactOutput[] { - return; - } -} diff --git a/packages/api/src/ticketing/contact/services/github/types.ts b/packages/api/src/ticketing/contact/services/github/types.ts deleted file mode 100644 index 422136439..000000000 --- a/packages/api/src/ticketing/contact/services/github/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type GithubContactInput = { - name: string; -}; - -//TODO -export type GithubContactOutput = GithubContactInput; diff --git a/packages/api/src/ticketing/contact/sync/sync.service.ts b/packages/api/src/ticketing/contact/sync/sync.service.ts index 29ab7ef12..1509e780b 100644 --- a/packages/api/src/ticketing/contact/sync/sync.service.ts +++ b/packages/api/src/ticketing/contact/sync/sync.service.ts @@ -42,60 +42,54 @@ export class SyncService implements OnModuleInit { async syncContacts() { try { this.logger.log(`Syncing contacts....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = TICKETING_PROVIDERS; - for (const provider of providers) { - try { - const accounts = await this.prisma.tcg_accounts.findMany(); - if (accounts) { - for (const acc of accounts) { - await this.syncContactsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - acc.remote_id, - ); + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = TICKETING_PROVIDERS; + for (const provider of providers) { + try { + const accounts = await this.prisma.tcg_accounts.findMany(); + if (accounts) { + for (const acc of accounts) { + await this.syncContactsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + acc.remote_id, + ); + } + } else { + await this.syncContactsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } + } catch (error) { + handleServiceError(error, this.logger); + } } - } else { - await this.syncContactsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); + } catch (error) { + handleServiceError(error, this.logger); } - } catch (error) { - handleServiceError(error, this.logger); - } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/ticketing/tag/services/github/index.ts b/packages/api/src/ticketing/tag/services/github/index.ts deleted file mode 100644 index 7df11274d..000000000 --- a/packages/api/src/ticketing/tag/services/github/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { LoggerService } from '@@core/logger/logger.service'; -import { PrismaService } from '@@core/prisma/prisma.service'; -import { EncryptionService } from '@@core/encryption/encryption.service'; -import { TicketingObject } from '@ticketing/@utils/@types'; -import { ApiResponse } from '@@core/utils/types'; -import axios from 'axios'; -import { ActionType, handleServiceError } from '@@core/utils/errors'; -import { ServiceRegistry } from '../registry.service'; -import { ITagService } from '@ticketing/tag/types'; -import { GithubTagOutput } from './types'; - -//TODO -@Injectable() -export class GithubService implements ITagService { - constructor( - private prisma: PrismaService, - private logger: LoggerService, - private cryptoService: EncryptionService, - private registry: ServiceRegistry, - ) { - this.logger.setContext( - TicketingObject.tag.toUpperCase() + ':' + GithubService.name, - ); - this.registry.registerService('github', this); - } - - async syncTags( - linkedUserId: string, - id_ticket: string, - ): Promise> { - try { - const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'github', - vertical: 'ticketing', - }, - }); - const resp = await axios.get(`${connection.account_url}/tags`, { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }); - this.logger.log(`Synced github tags !`); - - return { - data: resp.data, - message: 'Github tags retrieved', - statusCode: 200, - }; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Github', - TicketingObject.tag, - ActionType.GET, - ); - } - } -} diff --git a/packages/api/src/ticketing/tag/services/github/mappers.ts b/packages/api/src/ticketing/tag/services/github/mappers.ts deleted file mode 100644 index bea26ee1a..000000000 --- a/packages/api/src/ticketing/tag/services/github/mappers.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ITagMapper } from '@ticketing/tag/types'; -import { GithubTagInput, GithubTagOutput } from './types'; -import { - UnifiedTagInput, - UnifiedTagOutput, -} from '@ticketing/tag/types/model.unified'; - -export class GithubTagMapper implements ITagMapper { - desunify( - source: UnifiedTagInput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): GithubTagInput { - return; - } - - unify( - source: GithubTagOutput | GithubTagOutput[], - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedTagOutput | UnifiedTagOutput[] { - return; - } -} diff --git a/packages/api/src/ticketing/tag/services/github/types.ts b/packages/api/src/ticketing/tag/services/github/types.ts deleted file mode 100644 index 9598acae2..000000000 --- a/packages/api/src/ticketing/tag/services/github/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type GithubTagInput = { - name: string; -}; - -//TODO -export type GithubTagOutput = GithubTagInput; diff --git a/packages/api/src/ticketing/tag/sync/sync.service.ts b/packages/api/src/ticketing/tag/sync/sync.service.ts index 32eb6da8a..399110248 100644 --- a/packages/api/src/ticketing/tag/sync/sync.service.ts +++ b/packages/api/src/ticketing/tag/sync/sync.service.ts @@ -42,58 +42,52 @@ export class SyncService implements OnModuleInit { async syncTags() { try { this.logger.log(`Syncing tags....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = TICKETING_PROVIDERS; - for (const provider of providers) { - try { - //call the sync comments for every ticket of the linkedUser (a comment is tied to a ticket) - const tickets = await this.prisma.tcg_tickets.findMany({ - where: { - remote_platform: provider, - id_linked_user: linkedUser.id_linked_user, - }, - }); - for (const ticket of tickets) { - await this.syncTagsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ticket.id_tcg_ticket, - ); + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = TICKETING_PROVIDERS; + for (const provider of providers) { + try { + //call the sync comments for every ticket of the linkedUser (a comment is tied to a ticket) + const tickets = await this.prisma.tcg_tickets.findMany({ + where: { + remote_platform: provider, + id_linked_user: linkedUser.id_linked_user, + }, + }); + for (const ticket of tickets) { + await this.syncTagsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ticket.id_tcg_ticket, + ); + } + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); } - } catch (error) { - handleServiceError(error, this.logger); - } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/ticketing/tag/tag.module.ts b/packages/api/src/ticketing/tag/tag.module.ts index 8c95d440d..9e2cb2904 100644 --- a/packages/api/src/ticketing/tag/tag.module.ts +++ b/packages/api/src/ticketing/tag/tag.module.ts @@ -10,7 +10,6 @@ import { PrismaService } from '@@core/prisma/prisma.service'; import { WebhookService } from '@@core/webhook/webhook.service'; import { BullModule } from '@nestjs/bull'; import { FrontService } from './services/front'; -import { GithubService } from './services/github'; import { ZendeskService } from './services/zendesk'; import { JiraService } from './services/jira'; import { GorgiasService } from './services/gorgias'; @@ -34,7 +33,6 @@ import { GorgiasService } from './services/gorgias'; /* PROVIDERS SERVICES */ ZendeskService, FrontService, - GithubService, JiraService, GorgiasService, ], diff --git a/packages/api/src/ticketing/team/services/github/index.ts b/packages/api/src/ticketing/team/services/github/index.ts deleted file mode 100644 index e9ba67034..000000000 --- a/packages/api/src/ticketing/team/services/github/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { LoggerService } from '@@core/logger/logger.service'; -import { PrismaService } from '@@core/prisma/prisma.service'; -import { EncryptionService } from '@@core/encryption/encryption.service'; -import { TicketingObject } from '@ticketing/@utils/@types'; -import { ApiResponse } from '@@core/utils/types'; -import axios from 'axios'; -import { ActionType, handleServiceError } from '@@core/utils/errors'; -import { ServiceRegistry } from '../registry.service'; -import { ITeamService } from '@ticketing/team/types'; -import { GithubTeamOutput } from './types'; - -//TODO -@Injectable() -export class GithubService implements ITeamService { - constructor( - private prisma: PrismaService, - private logger: LoggerService, - private cryptoService: EncryptionService, - private registry: ServiceRegistry, - ) { - this.logger.setContext( - TicketingObject.team.toUpperCase() + ':' + GithubService.name, - ); - this.registry.registerService('github', this); - } - - async syncTeams( - linkedUserId: string, - custom_properties?: string[], - ): Promise> { - try { - const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'github', - vertical: 'ticketing', - }, - }); - const org = ''; - - const resp = await axios.get(`${connection.account_url}/${org}/teams`, { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }); - this.logger.log(`Synced github teams !`); - - return { - data: resp.data, - message: 'Github teams retrieved', - statusCode: 200, - }; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Github', - TicketingObject.team, - ActionType.GET, - ); - } - } -} diff --git a/packages/api/src/ticketing/team/services/github/mappers.ts b/packages/api/src/ticketing/team/services/github/mappers.ts deleted file mode 100644 index 69bd3ea70..000000000 --- a/packages/api/src/ticketing/team/services/github/mappers.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ITeamMapper } from '@ticketing/team/types'; -import { GithubTeamInput, GithubTeamOutput } from './types'; -import { - UnifiedTeamInput, - UnifiedTeamOutput, -} from '@ticketing/team/types/model.unified'; - -export class GithubTeamMapper implements ITeamMapper { - desunify( - source: UnifiedTeamInput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): GithubTeamInput { - return; - } - - unify( - source: GithubTeamOutput | GithubTeamOutput[], - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedTeamOutput | UnifiedTeamOutput[] { - return; - } -} diff --git a/packages/api/src/ticketing/team/services/github/types.ts b/packages/api/src/ticketing/team/services/github/types.ts deleted file mode 100644 index f92dda4f8..000000000 --- a/packages/api/src/ticketing/team/services/github/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type GithubTeamInput = { - name: string; -}; - -//TODO -export type GithubTeamOutput = GithubTeamInput; diff --git a/packages/api/src/ticketing/team/sync/sync.service.ts b/packages/api/src/ticketing/team/sync/sync.service.ts index 68c9f5d9f..2dc065f1a 100644 --- a/packages/api/src/ticketing/team/sync/sync.service.ts +++ b/packages/api/src/ticketing/team/sync/sync.service.ts @@ -42,55 +42,49 @@ export class SyncService implements OnModuleInit { async syncTeams() { try { this.logger.log(`Syncing teams....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedTeams = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedTeams.map(async (linkedTeam) => { - try { - const providers = TICKETING_PROVIDERS; - for (const provider of providers) { - try { - await this.syncTeamsForLinkedTeam( - provider, - linkedTeam.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = TICKETING_PROVIDERS; + for (const provider of providers) { + try { + await this.syncTeamsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } } //todo: HANDLE DATA REMOVED FROM PROVIDER - async syncTeamsForLinkedTeam( + async syncTeamsForLinkedUser( integrationId: string, linkedUserId: string, id_project: string, diff --git a/packages/api/src/ticketing/team/team.module.ts b/packages/api/src/ticketing/team/team.module.ts index c24f4403d..aba6d0e58 100644 --- a/packages/api/src/ticketing/team/team.module.ts +++ b/packages/api/src/ticketing/team/team.module.ts @@ -10,7 +10,6 @@ import { PrismaService } from '@@core/prisma/prisma.service'; import { WebhookService } from '@@core/webhook/webhook.service'; import { BullModule } from '@nestjs/bull'; import { FrontService } from './services/front'; -import { GithubService } from './services/github'; import { ZendeskService } from './services/zendesk'; import { JiraService } from './services/jira'; import { GorgiasService } from './services/gorgias'; @@ -34,7 +33,6 @@ import { GorgiasService } from './services/gorgias'; /* PROVIDERS SERVICES */ ZendeskService, FrontService, - GithubService, JiraService, GorgiasService, ], diff --git a/packages/api/src/ticketing/ticket/services/front/mappers.ts b/packages/api/src/ticketing/ticket/services/front/mappers.ts index 50094c721..5e1272fda 100644 --- a/packages/api/src/ticketing/ticket/services/front/mappers.ts +++ b/packages/api/src/ticketing/ticket/services/front/mappers.ts @@ -20,19 +20,18 @@ export class FrontTicketMapper implements ITicketMapper { remote_id: string; }[], ): Promise { - let result: FrontTicketInput = { + const result: FrontTicketInput = { type: 'discussion', // Assuming 'discussion' as a default type for Front conversations subject: source.name, - teammate_ids: source.assigned_to, comment: { - body: source.comment.body, + body: source.comment.body || '', author_id: source.comment.creator_type === 'user' ? await this.utils.getAsigneeRemoteIdFromUserUuid( source.comment.user_id, ) - : undefined, - attachments: source.comment.attachments, + : '', + attachments: source.comment.attachments || [], }, }; @@ -44,17 +43,11 @@ export class FrontTicketMapper implements ITicketMapper { res.push(data); } } - result = { - ...result, - teammate_ids: res, - }; + result.teammate_ids = res; } if (source.tags) { - result = { - ...result, - tags: source.tags, - }; + result.tags = source.tags; } if (customFieldMappings && source.field_mappings) { diff --git a/packages/api/src/ticketing/ticket/services/gorgias/mappers.ts b/packages/api/src/ticketing/ticket/services/gorgias/mappers.ts index cea0ba8aa..d902b7ad7 100644 --- a/packages/api/src/ticketing/ticket/services/gorgias/mappers.ts +++ b/packages/api/src/ticketing/ticket/services/gorgias/mappers.ts @@ -23,18 +23,20 @@ export class GorgiasTicketMapper implements ITicketMapper { const result: GorgiasTicketInput = { channel: source.type ?? 'email', // Assuming 'email' as default channel subject: source.name, - status: source.status, - created_datetime: source.due_date?.toISOString(), + created_datetime: + source.due_date?.toISOString() || new Date().toISOString(), messages: [ { via: source.type ?? 'email', from_agent: false, channel: source.type ?? 'email', - body_html: source.comment.html_body, - body_text: source.comment.body, - attachments: source.comment.attachments.map((att) => ({ - extra: att, - })), + body_html: source.comment.html_body || '', + body_text: source.comment.body || '', + attachments: source.comment.attachments + ? source.comment.attachments.map((att) => ({ + extra: att, + })) + : [], sender: source.comment.creator_type === 'user' ? { @@ -44,11 +46,15 @@ export class GorgiasTicketMapper implements ITicketMapper { ), ), } - : undefined, + : null, }, ], }; + if (source.status) { + result.status = source.status; + } + if (source.assigned_to && source.assigned_to.length > 0) { const data = await this.utils.getAsigneeRemoteIdFromUserUuid( source.assigned_to[0], diff --git a/packages/api/src/ticketing/ticket/services/hubspot/mappers.ts b/packages/api/src/ticketing/ticket/services/hubspot/mappers.ts index 6fb5e3ea9..607e6b239 100644 --- a/packages/api/src/ticketing/ticket/services/hubspot/mappers.ts +++ b/packages/api/src/ticketing/ticket/services/hubspot/mappers.ts @@ -15,9 +15,9 @@ export class HubspotTicketMapper implements ITicketMapper { ): HubspotTicketInput { const result = { subject: source.name, - hs_pipeline: source.type, + hs_pipeline: source.type || '', hubspot_owner_id: '', // TODO Replace 'default' with actual owner ID - hs_pipeline_stage: source.status, + hs_pipeline_stage: source.status || '', hs_ticket_priority: source.priority || 'MEDIUM', }; diff --git a/packages/api/src/ticketing/ticket/services/jira/mappers.ts b/packages/api/src/ticketing/ticket/services/jira/mappers.ts index 6ec7bf279..7bd13eb78 100644 --- a/packages/api/src/ticketing/ticket/services/jira/mappers.ts +++ b/packages/api/src/ticketing/ticket/services/jira/mappers.ts @@ -26,11 +26,11 @@ export class JiraTicketMapper implements ITicketMapper { const result: JiraTicketInput = { fields: { project: { - key: source.project_id, + key: source.project_id || '', }, description: source.description, issuetype: { - name: source.type, + name: source.type || '', }, }, }; diff --git a/packages/api/src/ticketing/ticket/services/ticket.service.ts b/packages/api/src/ticketing/ticket/services/ticket.service.ts index 6f95e634b..5a09c16c5 100644 --- a/packages/api/src/ticketing/ticket/services/ticket.service.ts +++ b/packages/api/src/ticketing/ticket/services/ticket.service.ts @@ -121,6 +121,10 @@ export class TicketService { : [], }); + this.logger.log( + 'ticket desunified is ' + JSON.stringify(desunifiedObject), + ); + const service: ITicketService = this.serviceRegistry.getService(integrationId); const resp: ApiResponse = await service.addTicket( diff --git a/packages/api/src/ticketing/ticket/services/zendesk/index.ts b/packages/api/src/ticketing/ticket/services/zendesk/index.ts index e075e5a6b..ccb52c2b6 100644 --- a/packages/api/src/ticketing/ticket/services/zendesk/index.ts +++ b/packages/api/src/ticketing/ticket/services/zendesk/index.ts @@ -81,6 +81,10 @@ export class ZendeskService implements ITicketService { }; } + this.logger.log( + 'data to insert for zendesk ticket is ' + JSON.stringify(dataBody), + ); + const resp = await axios.post( `${connection.account_url}/tickets.json`, JSON.stringify(dataBody), diff --git a/packages/api/src/ticketing/ticket/services/zendesk/mappers.ts b/packages/api/src/ticketing/ticket/services/zendesk/mappers.ts index 35aa6c16c..0c02738f0 100644 --- a/packages/api/src/ticketing/ticket/services/zendesk/mappers.ts +++ b/packages/api/src/ticketing/ticket/services/zendesk/mappers.ts @@ -20,61 +20,43 @@ export class ZendeskTicketMapper implements ITicketMapper { remote_id: string; }[], ): Promise { - let result: ZendeskTicketInput = { + const result: ZendeskTicketInput = { description: source.description, - priority: 'high', - status: 'new', subject: source.name, comment: { - body: source.comment.body, - html_body: source.comment.html_body || null, + body: source.comment.body || '', public: !source.comment.is_private || true, - uploads: source.comment.attachments, //fetch token attachments for this uuid, would be done on the fly in dest service + uploads: source.comment.attachments || [], //fetch token attachments for this uuid, would be done on the fly in dest service }, }; + if (source.comment.html_body) { + result.comment.html_body = source.comment.html_body; + } if (source.assigned_to && source.assigned_to.length > 0) { - result = { - ...result, - assignee_email: await this.utils.getAssigneeMetadataFromUuid( - source.assigned_to?.[0], - ), // get the mail of the uuid - }; + result.assignee_email = await this.utils.getAssigneeMetadataFromUuid( + source.assigned_to?.[0], + ); // get the mail of the uuid } if (source.due_date) { - result = { - ...result, - due_at: source.due_date?.toISOString(), - }; + result.due_at = source.due_date?.toISOString(); } if (source.priority) { - result = { - ...result, - priority: source.priority as 'urgent' | 'high' | 'normal' | 'low', - }; + result.priority = source.priority as 'urgent' | 'high' | 'normal' | 'low'; } if (source.status) { - result = { - ...result, - status: source.status as - | 'new' - | 'open' - | 'pending' - | 'hold' - | 'solved' - | 'closed', - }; + result.status = source.status as + | 'new' + | 'open' + | 'pending' + | 'hold' + | 'solved' + | 'closed'; } if (source.tags) { - result = { - ...result, - tags: source.tags, - }; + result.tags = source.tags; } if (source.type) { - result = { - ...result, - type: source.type as 'problem' | 'incident' | 'question' | 'task', - }; + result.type = source.type as 'problem' | 'incident' | 'question' | 'task'; } if (customFieldMappings && source.field_mappings) { diff --git a/packages/api/src/ticketing/ticket/sync/sync.service.ts b/packages/api/src/ticketing/ticket/sync/sync.service.ts index b3020c9f5..0cb65525f 100644 --- a/packages/api/src/ticketing/ticket/sync/sync.service.ts +++ b/packages/api/src/ticketing/ticket/sync/sync.service.ts @@ -42,48 +42,42 @@ export class SyncService implements OnModuleInit { async syncTickets() { try { this.logger.log(`Syncing tickets....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = TICKETING_PROVIDERS; - for (const provider of providers) { - try { - await this.syncTicketsForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = TICKETING_PROVIDERS; + for (const provider of providers) { + try { + await this.syncTicketsForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/ticketing/ticket/types/model.unified.ts b/packages/api/src/ticketing/ticket/types/model.unified.ts index f0e8999a5..2f44dd05c 100644 --- a/packages/api/src/ticketing/ticket/types/model.unified.ts +++ b/packages/api/src/ticketing/ticket/types/model.unified.ts @@ -64,8 +64,8 @@ export class UnifiedTicketInput { assigned_to?: string[]; //uuid of Users objects ? @ApiPropertyOptional({ - type: [String], - description: 'The comments of the ticket', + type: UnifiedCommentInput, + description: 'The comment of the ticket', }) comment?: UnifiedCommentInput; diff --git a/packages/api/src/ticketing/user/services/github/index.ts b/packages/api/src/ticketing/user/services/github/index.ts deleted file mode 100644 index a92b04abc..000000000 --- a/packages/api/src/ticketing/user/services/github/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { LoggerService } from '@@core/logger/logger.service'; -import { PrismaService } from '@@core/prisma/prisma.service'; -import { EncryptionService } from '@@core/encryption/encryption.service'; -import { TicketingObject } from '@ticketing/@utils/@types'; -import { ApiResponse } from '@@core/utils/types'; -import axios from 'axios'; -import { ActionType, handleServiceError } from '@@core/utils/errors'; -import { ServiceRegistry } from '../registry.service'; -import { IUserService } from '@ticketing/user/types'; -import { GithubUserOutput } from './types'; - -//TODO -@Injectable() -export class GithubService implements IUserService { - constructor( - private prisma: PrismaService, - private logger: LoggerService, - private cryptoService: EncryptionService, - private registry: ServiceRegistry, - ) { - this.logger.setContext( - TicketingObject.user.toUpperCase() + ':' + GithubService.name, - ); - this.registry.registerService('github', this); - } - - async syncUsers( - linkedUserId: string, - custom_properties?: string[], - ): Promise> { - try { - const connection = await this.prisma.connections.findFirst({ - where: { - id_linked_user: linkedUserId, - provider_slug: 'github', - vertical: 'ticketing', - }, - }); - const resp = await axios.get(`${connection.account_url}/user`, { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.cryptoService.decrypt( - connection.access_token, - )}`, - }, - }); - this.logger.log(`Synced github users !`); - - return { - data: resp.data, - message: 'Github users retrieved', - statusCode: 200, - }; - } catch (error) { - handleServiceError( - error, - this.logger, - 'Github', - TicketingObject.user, - ActionType.GET, - ); - } - } -} diff --git a/packages/api/src/ticketing/user/services/github/mappers.ts b/packages/api/src/ticketing/user/services/github/mappers.ts deleted file mode 100644 index 653d692ea..000000000 --- a/packages/api/src/ticketing/user/services/github/mappers.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { IUserMapper } from '@ticketing/user/types'; -import { GithubUserInput, GithubUserOutput } from './types'; -import { - UnifiedUserInput, - UnifiedUserOutput, -} from '@ticketing/user/types/model.unified'; - -export class GithubUserMapper implements IUserMapper { - desunify( - source: UnifiedUserInput, - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): GithubUserInput { - return; - } - - unify( - source: GithubUserOutput | GithubUserOutput[], - customFieldMappings?: { - slug: string; - remote_id: string; - }[], - ): UnifiedUserOutput | UnifiedUserOutput[] { - return; - } -} diff --git a/packages/api/src/ticketing/user/services/github/types.ts b/packages/api/src/ticketing/user/services/github/types.ts deleted file mode 100644 index 1f644a57b..000000000 --- a/packages/api/src/ticketing/user/services/github/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type GithubUserInput = { - name: string; -}; - -//TODO -export type GithubUserOutput = GithubUserInput; diff --git a/packages/api/src/ticketing/user/sync/sync.service.ts b/packages/api/src/ticketing/user/sync/sync.service.ts index 8e5b15983..a06f7efe9 100644 --- a/packages/api/src/ticketing/user/sync/sync.service.ts +++ b/packages/api/src/ticketing/user/sync/sync.service.ts @@ -42,48 +42,42 @@ export class SyncService implements OnModuleInit { async syncUsers() { try { this.logger.log(`Syncing users....`); - /*const defaultOrg = await this.prisma.organizations.findFirst({ - where: { - name: 'Acme Inc', - }, - });*/ - - const defaultUser = await this.prisma.users.findFirst({ - where: { - email: 'audrey@aubry.io', - }, - }); - - const defaultProject = await this.prisma.projects.findFirst({ - where: { - id_user: defaultUser.id_user, - name: 'Project 1', - }, - }); - const id_project = defaultProject.id_project; - const linkedUsers = await this.prisma.linked_users.findMany({ - where: { - id_project: id_project, - }, - }); - linkedUsers.map(async (linkedUser) => { - try { - const providers = TICKETING_PROVIDERS; - for (const provider of providers) { - try { - await this.syncUsersForLinkedUser( - provider, - linkedUser.id_linked_user, - id_project, - ); - } catch (error) { - handleServiceError(error, this.logger); - } + const users = await this.prisma.users.findMany(); + if (users && users.length > 0) { + for (const user of users) { + const projects = await this.prisma.projects.findMany({ + where: { + id_user: user.id_user, + }, + }); + for (const project of projects) { + const id_project = project.id_project; + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: id_project, + }, + }); + linkedUsers.map(async (linkedUser) => { + try { + const providers = TICKETING_PROVIDERS; + for (const provider of providers) { + try { + await this.syncUsersForLinkedUser( + provider, + linkedUser.id_linked_user, + id_project, + ); + } catch (error) { + handleServiceError(error, this.logger); + } + } + } catch (error) { + handleServiceError(error, this.logger); + } + }); } - } catch (error) { - handleServiceError(error, this.logger); } - }); + } } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/ticketing/user/user.module.ts b/packages/api/src/ticketing/user/user.module.ts index 46630a475..6b5f8c481 100644 --- a/packages/api/src/ticketing/user/user.module.ts +++ b/packages/api/src/ticketing/user/user.module.ts @@ -11,7 +11,6 @@ import { WebhookService } from '@@core/webhook/webhook.service'; import { BullModule } from '@nestjs/bull'; import { ZendeskService } from './services/zendesk'; import { FrontService } from './services/front'; -import { GithubService } from './services/github'; import { JiraService } from './services/jira'; import { GorgiasService } from './services/gorgias'; @@ -34,7 +33,6 @@ import { GorgiasService } from './services/gorgias'; /* PROVIDERS SERVICES */ ZendeskService, FrontService, - GithubService, JiraService, GorgiasService, ], diff --git a/packages/api/swagger/swagger-spec.json b/packages/api/swagger/swagger-spec.json index ed67b2d77..5d7d3ebbd 100644 --- a/packages/api/swagger/swagger-spec.json +++ b/packages/api/swagger/swagger-spec.json @@ -5042,15 +5042,36 @@ "required": [ "first_name", "last_name", - "email_addresses", - "phone_numbers", - "addresses", "field_mappings" ] }, "UnifiedDealOutput": { "type": "object", "properties": { + "name": { + "type": "string", + "description": "The name of the deal" + }, + "description": { + "type": "string", + "description": "The description of the deal" + }, + "amount": { + "type": "number", + "description": "The amount of the deal" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user who is on the deal" + }, + "stage_id": { + "type": "string", + "description": "The uuid of the stage of the deal" + }, + "company_id": { + "type": "string", + "description": "The uuid of the company tied to the deal" + }, "field_mappings": { "type": "object", "properties": {} @@ -5069,6 +5090,9 @@ } }, "required": [ + "name", + "description", + "amount", "field_mappings", "remote_data" ] @@ -5076,18 +5100,65 @@ "UnifiedDealInput": { "type": "object", "properties": { + "name": { + "type": "string", + "description": "The name of the deal" + }, + "description": { + "type": "string", + "description": "The description of the deal" + }, + "amount": { + "type": "number", + "description": "The amount of the deal" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user who is on the deal" + }, + "stage_id": { + "type": "string", + "description": "The uuid of the stage of the deal" + }, + "company_id": { + "type": "string", + "description": "The uuid of the company tied to the deal" + }, "field_mappings": { "type": "object", "properties": {} } }, "required": [ + "name", + "description", + "amount", "field_mappings" ] }, "UnifiedNoteOutput": { "type": "object", "properties": { + "content": { + "type": "string", + "description": "The content of the note" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user tied the note" + }, + "company_id": { + "type": "string", + "description": "The uuid of the company tied to the note" + }, + "contact_id": { + "type": "string", + "description": "The uuid fo the contact tied to the note" + }, + "deal_id": { + "type": "string", + "description": "The uuid of the deal tied to the note" + }, "field_mappings": { "type": "object", "properties": {} @@ -5106,6 +5177,7 @@ } }, "required": [ + "content", "field_mappings", "remote_data" ] @@ -5113,18 +5185,76 @@ "UnifiedNoteInput": { "type": "object", "properties": { + "content": { + "type": "string", + "description": "The content of the note" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user tied the note" + }, + "company_id": { + "type": "string", + "description": "The uuid of the company tied to the note" + }, + "contact_id": { + "type": "string", + "description": "The uuid fo the contact tied to the note" + }, + "deal_id": { + "type": "string", + "description": "The uuid of the deal tied to the note" + }, "field_mappings": { "type": "object", "properties": {} } }, "required": [ + "content", "field_mappings" ] }, "UnifiedCompanyOutput": { "type": "object", "properties": { + "name": { + "type": "string", + "description": "The name of the company" + }, + "industry": { + "type": "string", + "description": "The industry of the company" + }, + "number_of_employees": { + "type": "number", + "description": "The number of employees of the company" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user who owns the company" + }, + "email_addresses": { + "description": "The email addresses of the company", + "type": "array", + "items": { + "$ref": "#/components/schemas/Email" + } + }, + "addresses": { + "description": "The addresses of the company", + "type": "array", + "items": { + "$ref": "#/components/schemas/Address" + } + }, + "phone_numbers": { + "description": "The phone numbers of the company", + "type": "array", + "items": { + "$ref": "#/components/schemas/Phone" + } + }, "field_mappings": { "type": "object", "properties": {} @@ -5143,6 +5273,7 @@ } }, "required": [ + "name", "field_mappings", "remote_data" ] @@ -5150,18 +5281,97 @@ "UnifiedCompanyInput": { "type": "object", "properties": { + "name": { + "type": "string", + "description": "The name of the company" + }, + "industry": { + "type": "string", + "description": "The industry of the company" + }, + "number_of_employees": { + "type": "number", + "description": "The number of employees of the company" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user who owns the company" + }, + "email_addresses": { + "description": "The email addresses of the company", + "type": "array", + "items": { + "$ref": "#/components/schemas/Email" + } + }, + "addresses": { + "description": "The addresses of the company", + "type": "array", + "items": { + "$ref": "#/components/schemas/Address" + } + }, + "phone_numbers": { + "description": "The phone numbers of the company", + "type": "array", + "items": { + "$ref": "#/components/schemas/Phone" + } + }, "field_mappings": { "type": "object", "properties": {} } }, "required": [ + "name", "field_mappings" ] }, "UnifiedEngagementOutput": { "type": "object", "properties": { + "content": { + "type": "string", + "description": "The content of the engagement" + }, + "direction": { + "type": "string", + "description": "The direction of the engagement" + }, + "subject": { + "type": "string", + "description": "The subject of the engagement" + }, + "start_at": { + "format": "date-time", + "type": "string", + "description": "The start time of the engagement" + }, + "end_time": { + "format": "date-time", + "type": "string", + "description": "The end time of the engagement" + }, + "type": { + "type": "string", + "description": "The type of the engagement. Authorized values are EMAIL, CALL or MEETING" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user tied to the engagement" + }, + "company_id": { + "type": "string", + "description": "The uuid of the company tied to the engagement" + }, + "contacts": { + "description": "The uuids of contacts tied to the engagement object", + "type": "array", + "items": { + "type": "string" + } + }, "field_mappings": { "type": "object", "properties": {} @@ -5180,6 +5390,7 @@ } }, "required": [ + "type", "field_mappings", "remote_data" ] @@ -5187,18 +5398,64 @@ "UnifiedEngagementInput": { "type": "object", "properties": { + "content": { + "type": "string", + "description": "The content of the engagement" + }, + "direction": { + "type": "string", + "description": "The direction of the engagement" + }, + "subject": { + "type": "string", + "description": "The subject of the engagement" + }, + "start_at": { + "format": "date-time", + "type": "string", + "description": "The start time of the engagement" + }, + "end_time": { + "format": "date-time", + "type": "string", + "description": "The end time of the engagement" + }, + "type": { + "type": "string", + "description": "The type of the engagement. Authorized values are EMAIL, CALL or MEETING" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user tied to the engagement" + }, + "company_id": { + "type": "string", + "description": "The uuid of the company tied to the engagement" + }, + "contacts": { + "description": "The uuids of contacts tied to the engagement object", + "type": "array", + "items": { + "type": "string" + } + }, "field_mappings": { "type": "object", "properties": {} } }, "required": [ + "type", "field_mappings" ] }, "UnifiedStageOutput": { "type": "object", "properties": { + "stage_name": { + "type": "string", + "description": "The name of the stage" + }, "field_mappings": { "type": "object", "properties": {} @@ -5217,6 +5474,7 @@ } }, "required": [ + "stage_name", "field_mappings", "remote_data" ] @@ -5224,6 +5482,40 @@ "UnifiedTaskOutput": { "type": "object", "properties": { + "subject": { + "type": "string", + "description": "The subject of the task" + }, + "content": { + "type": "string", + "description": "The content of the task" + }, + "status": { + "type": "string", + "description": "The status of the task. Authorized values are \"Completed\" and \"Not Completed\" " + }, + "due_date": { + "format": "date-time", + "type": "string", + "description": "The due date of the task" + }, + "finished_date": { + "format": "date-time", + "type": "string", + "description": "The finished date of the task" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user tied to the task" + }, + "company_id": { + "type": "string", + "description": "The uuid fo the company tied to the task" + }, + "deal_id": { + "type": "string", + "description": "The uuid of the deal tied to the task" + }, "field_mappings": { "type": "object", "properties": {} @@ -5242,6 +5534,9 @@ } }, "required": [ + "subject", + "content", + "status", "field_mappings", "remote_data" ] @@ -5249,12 +5544,49 @@ "UnifiedTaskInput": { "type": "object", "properties": { + "subject": { + "type": "string", + "description": "The subject of the task" + }, + "content": { + "type": "string", + "description": "The content of the task" + }, + "status": { + "type": "string", + "description": "The status of the task. Authorized values are \"Completed\" and \"Not Completed\" " + }, + "due_date": { + "format": "date-time", + "type": "string", + "description": "The due date of the task" + }, + "finished_date": { + "format": "date-time", + "type": "string", + "description": "The finished date of the task" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user tied to the task" + }, + "company_id": { + "type": "string", + "description": "The uuid fo the company tied to the task" + }, + "deal_id": { + "type": "string", + "description": "The uuid of the deal tied to the task" + }, "field_mappings": { "type": "object", "properties": {} } }, "required": [ + "subject", + "content", + "status", "field_mappings" ] }, @@ -5307,6 +5639,49 @@ "remote_data" ] }, + "UnifiedCommentInput": { + "type": "object", + "properties": { + "body": { + "type": "string", + "description": "The body of the comment" + }, + "html_body": { + "type": "string", + "description": "The html body of the comment" + }, + "is_private": { + "type": "boolean", + "description": "The public status of the comment" + }, + "creator_type": { + "type": "string", + "description": "The creator type of the comment (either user or contact)" + }, + "ticket_id": { + "type": "string", + "description": "The uuid of the ticket the comment is tied to" + }, + "contact_id": { + "type": "string", + "description": "The uuid of the contact which the comment belongs to (if no user_id specified)" + }, + "user_id": { + "type": "string", + "description": "The uuid of the user which the comment belongs to (if no contact_id specified)" + }, + "attachments": { + "description": "The attachements uuids tied to the comment", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "body" + ] + }, "UnifiedTicketOutput": { "type": "object", "properties": { @@ -5366,11 +5741,12 @@ } }, "comment": { - "description": "The comments of the ticket", - "type": "array", - "items": { - "type": "string" - } + "description": "The comment of the ticket", + "allOf": [ + { + "$ref": "#/components/schemas/UnifiedCommentInput" + } + ] }, "account_id": { "type": "string", @@ -5463,11 +5839,12 @@ } }, "comment": { - "description": "The comments of the ticket", - "type": "array", - "items": { - "type": "string" - } + "description": "The comment of the ticket", + "allOf": [ + { + "$ref": "#/components/schemas/UnifiedCommentInput" + } + ] }, "account_id": { "type": "string", @@ -5584,49 +5961,6 @@ "remote_data" ] }, - "UnifiedCommentInput": { - "type": "object", - "properties": { - "body": { - "type": "string", - "description": "The body of the comment" - }, - "html_body": { - "type": "string", - "description": "The html body of the comment" - }, - "is_private": { - "type": "boolean", - "description": "The public status of the comment" - }, - "creator_type": { - "type": "string", - "description": "The creator type of the comment (either user or contact)" - }, - "ticket_id": { - "type": "string", - "description": "The uuid of the ticket the comment is tied to" - }, - "contact_id": { - "type": "string", - "description": "The uuid of the contact which the comment belongs to (if no user_id specified)" - }, - "user_id": { - "type": "string", - "description": "The uuid of the user which the comment belongs to (if no contact_id specified)" - }, - "attachments": { - "description": "The attachements uuids tied to the comment", - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "body" - ] - }, "UnifiedAttachmentInput": { "type": "object", "properties": { From c6ec7a9b21986dcc9045bee2316204c74b26427d Mon Sep 17 00:00:00 2001 From: nael Date: Mon, 29 Apr 2024 10:14:26 +0200 Subject: [PATCH 2/3] :ambulance: Hotfix backend --- .../connections-strategies.service.ts | 6 +++--- packages/api/src/@core/connections/@utils/index.ts | 2 +- .../@core/connections/crm/services/accelo/accelo.service.ts | 4 +--- .../connections/crm/services/crm.connection.service.ts | 2 +- .../connections/crm/services/hubspot/hubspot.service.ts | 4 ++-- packages/api/src/crm/company/services/company.service.ts | 2 +- packages/api/src/crm/contact/contact.controller.ts | 2 +- packages/api/src/ticketing/account/sync/sync.service.ts | 2 +- packages/api/src/ticketing/comment/sync/sync.service.ts | 2 +- packages/api/src/ticketing/contact/sync/sync.service.ts | 2 +- .../api/src/ticketing/ticket/services/ticket.service.ts | 2 +- packages/api/src/ticketing/ticket/sync/sync.service.ts | 2 +- packages/api/src/ticketing/user/sync/sync.service.ts | 2 +- 13 files changed, 16 insertions(+), 18 deletions(-) diff --git a/packages/api/src/@core/connections-strategies/connections-strategies.service.ts b/packages/api/src/@core/connections-strategies/connections-strategies.service.ts index cacb184c1..baae66bd6 100644 --- a/packages/api/src/@core/connections-strategies/connections-strategies.service.ts +++ b/packages/api/src/@core/connections-strategies/connections-strategies.service.ts @@ -232,11 +232,11 @@ export class ConnectionsStrategiesService { .scopes, }; } - const isSubdomain = needsSubdomain( + /*const isSubdomain = needsSubdomain( provider.toLowerCase(), vertical.toLowerCase(), - ); - console.log('needs subdomain ??? ' + isSubdomain); + );*/ + // console.log('needs subdomain ??? ' + isSubdomain); if (needsSubdomain(provider.toLowerCase(), vertical.toLowerCase())) { data = { ...data, diff --git a/packages/api/src/@core/connections/@utils/index.ts b/packages/api/src/@core/connections/@utils/index.ts index 8053f81f7..08adb842e 100644 --- a/packages/api/src/@core/connections/@utils/index.ts +++ b/packages/api/src/@core/connections/@utils/index.ts @@ -18,7 +18,7 @@ export class ConnectionUtils { token: string, ): Promise { try { - console.log('token is ' + token); + // console.log('token is ' + token); if (!token) throw new Error('token provided for connection token is invalid'); const res = await this.prisma.connections.findFirst({ diff --git a/packages/api/src/@core/connections/crm/services/accelo/accelo.service.ts b/packages/api/src/@core/connections/crm/services/accelo/accelo.service.ts index d4c6a33ae..26e42aff4 100644 --- a/packages/api/src/@core/connections/crm/services/accelo/accelo.service.ts +++ b/packages/api/src/@core/connections/crm/services/accelo/accelo.service.ts @@ -49,9 +49,7 @@ export class AcceloConnectionService implements ICrmConnectionService { async handleCallback(opts: CallbackParams) { try { const { linkedUserId, projectId, code } = opts; - this.logger.log( - 'linkeduserid is ' + linkedUserId + ' inside callback accelo', - ); + // this.logger.log('linkeduserid is ' + linkedUserId + ' inside callback accelo',); const isNotUnique = await this.prisma.connections.findFirst({ where: { id_linked_user: linkedUserId, diff --git a/packages/api/src/@core/connections/crm/services/crm.connection.service.ts b/packages/api/src/@core/connections/crm/services/crm.connection.service.ts index d260d193f..f39da7a04 100644 --- a/packages/api/src/@core/connections/crm/services/crm.connection.service.ts +++ b/packages/api/src/@core/connections/crm/services/crm.connection.service.ts @@ -59,7 +59,7 @@ export class CrmConnectionsService { location: zohoLocation || null, }; const data: Connection = await service.handleCallback(callbackOpts); - this.logger.log('data is ' + data); + // this.logger.log('data is ' + data); const event = await this.prisma.events.create({ data: { id_event: uuidv4(), diff --git a/packages/api/src/@core/connections/crm/services/hubspot/hubspot.service.ts b/packages/api/src/@core/connections/crm/services/hubspot/hubspot.service.ts index 576a8c519..26ff4b850 100644 --- a/packages/api/src/@core/connections/crm/services/hubspot/hubspot.service.ts +++ b/packages/api/src/@core/connections/crm/services/hubspot/hubspot.service.ts @@ -46,9 +46,9 @@ export class HubspotConnectionService implements ICrmConnectionService { async handleCallback(opts: CallbackParams) { try { const { linkedUserId, projectId, code } = opts; - this.logger.log( + /* this.logger.log( 'linkeduserid is ' + linkedUserId + ' inside callback hubspot', - ); + );*/ const isNotUnique = await this.prisma.connections.findFirst({ where: { id_linked_user: linkedUserId, diff --git a/packages/api/src/crm/company/services/company.service.ts b/packages/api/src/crm/company/services/company.service.ts index 8d426ecdb..6b80c8d51 100644 --- a/packages/api/src/crm/company/services/company.service.ts +++ b/packages/api/src/crm/company/services/company.service.ts @@ -245,7 +245,7 @@ export class CompanyService { unique_crm_company_id = res.id_crm_company; } else { // Create a new company - this.logger.log('company not exists'); + // this.logger.log('company not exists'); const uuid = uuidv4(); let data: any = { id_crm_company: uuid, diff --git a/packages/api/src/crm/contact/contact.controller.ts b/packages/api/src/crm/contact/contact.controller.ts index 19d40796b..b3eaed11a 100644 --- a/packages/api/src/crm/contact/contact.controller.ts +++ b/packages/api/src/crm/contact/contact.controller.ts @@ -131,7 +131,7 @@ export class ContactController { @Query('remote_data') remote_data?: boolean, ) { try { - this.logger.log('x-connection-token is ' + connection_token); + // this.logger.log('x-connection-token is ' + connection_token); const { linkedUserId, remoteSource } = await this.connectionUtils.getConnectionMetadataFromConnectionToken( connection_token, diff --git a/packages/api/src/ticketing/account/sync/sync.service.ts b/packages/api/src/ticketing/account/sync/sync.service.ts index 10034c5a8..4739345b0 100644 --- a/packages/api/src/ticketing/account/sync/sync.service.ts +++ b/packages/api/src/ticketing/account/sync/sync.service.ts @@ -125,7 +125,7 @@ export class SyncService implements OnModuleInit { await service.syncAccounts(linkedUserId, remoteProperties); const sourceObject: OriginalAccountOutput[] = resp.data; - this.logger.log('resp is ' + sourceObject); + // this.logger.log('resp is ' + sourceObject); //unify the data according to the target obj wanted const unifiedObject = (await unify({ diff --git a/packages/api/src/ticketing/comment/sync/sync.service.ts b/packages/api/src/ticketing/comment/sync/sync.service.ts index a630b4aa7..0b80c8d67 100644 --- a/packages/api/src/ticketing/comment/sync/sync.service.ts +++ b/packages/api/src/ticketing/comment/sync/sync.service.ts @@ -316,7 +316,7 @@ export class SyncService implements OnModuleInit { unique_ticketing_attachmt_id = res.id_tcg_attachment; } else { // Create a new attachment - this.logger.log('attchmt not exists'); + // this.logger.log('attchmt not exists'); const data = { id_tcg_attachment: uuidv4(), remote_id: attchmt.id, diff --git a/packages/api/src/ticketing/contact/sync/sync.service.ts b/packages/api/src/ticketing/contact/sync/sync.service.ts index 1509e780b..66f6712e2 100644 --- a/packages/api/src/ticketing/contact/sync/sync.service.ts +++ b/packages/api/src/ticketing/contact/sync/sync.service.ts @@ -247,7 +247,7 @@ export class SyncService implements OnModuleInit { contacts_results = [...contacts_results, res]; } else { // Create a new contact - this.logger.log('not existing contact ' + contact.name); + // this.logger.log('not existing contact ' + contact.name); const data: any = { id_tcg_contact: uuidv4(), name: contact.name, diff --git a/packages/api/src/ticketing/ticket/services/ticket.service.ts b/packages/api/src/ticketing/ticket/services/ticket.service.ts index 5a09c16c5..2d0994e28 100644 --- a/packages/api/src/ticketing/ticket/services/ticket.service.ts +++ b/packages/api/src/ticketing/ticket/services/ticket.service.ts @@ -199,7 +199,7 @@ export class TicketService { unique_ticketing_ticket_id = res.id_tcg_ticket; } else { // Create a new ticket - this.logger.log('not existing ticket ' + target_ticket.name); + // this.logger.log('not existing ticket ' + target_ticket.name); let data: any = { id_tcg_ticket: uuidv4(), diff --git a/packages/api/src/ticketing/ticket/sync/sync.service.ts b/packages/api/src/ticketing/ticket/sync/sync.service.ts index 0cb65525f..304c2a4f2 100644 --- a/packages/api/src/ticketing/ticket/sync/sync.service.ts +++ b/packages/api/src/ticketing/ticket/sync/sync.service.ts @@ -242,7 +242,7 @@ export class SyncService implements OnModuleInit { tickets_results = [...tickets_results, res]; } else { // Create a new ticket - this.logger.log('not existing ticket ' + ticket.name); + // this.logger.log('not existing ticket ' + ticket.name); let data: any = { id_tcg_ticket: uuidv4(), diff --git a/packages/api/src/ticketing/user/sync/sync.service.ts b/packages/api/src/ticketing/user/sync/sync.service.ts index a06f7efe9..5af5377a5 100644 --- a/packages/api/src/ticketing/user/sync/sync.service.ts +++ b/packages/api/src/ticketing/user/sync/sync.service.ts @@ -222,7 +222,7 @@ export class SyncService implements OnModuleInit { users_results = [...users_results, res]; } else { // Create a new user - this.logger.log('not existing user ' + user.name); + // this.logger.log('not existing user ' + user.name); const data = { id_tcg_user: uuidv4(), name: user.name, From 1491af097095ac4871b3cec083fc5637f1a85d64 Mon Sep 17 00:00:00 2001 From: nael Date: Mon, 29 Apr 2024 10:54:32 +0200 Subject: [PATCH 3/3] :recycle: Refactor fixes --- README.md | 19 ++++--- .../types/original/original.ticketing.ts | 53 +------------------ packages/api/src/ticketing/README.md | 10 ++-- .../ticketing/account/types/mappingsTypes.ts | 6 --- .../attachment/types/mappingsTypes.ts | 6 --- .../ticketing/comment/types/mappingsTypes.ts | 6 --- .../ticketing/contact/types/mappingsTypes.ts | 6 --- .../src/ticketing/tag/types/mappingsTypes.ts | 6 --- .../src/ticketing/team/types/mappingsTypes.ts | 6 --- .../src/ticketing/user/types/mappingsTypes.ts | 6 --- 10 files changed, 16 insertions(+), 108 deletions(-) diff --git a/README.md b/README.md index 5680fae61..d0a2356c6 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ Your customers expect all of their tools to work well together. Panora avoids your team spending hundreds of hours building and maintaining integrations instead of your core product. - # ✨ Core Features | | @@ -38,11 +37,12 @@ Your customers expect all of their tools to work well together. Panora avoids yo | **Passthrough Requests:** Interact with other software platforms in their native format. | | **Webhooks:** Listen to one webhook to receive normalized data from various software platforms | - # ✨ Integrations Catalog + Panora supports integration with the following objects across multiple platforms: -### CRM +### CRM + | | Contacts | Deals | Notes | Engagements | Tasks | Users | Companies | |-----------------------------------------------|:--------:|:-----:|:-----:|:-----------:|:-----:|:-----:|:---------:| | Hubspot | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | | @@ -51,18 +51,16 @@ Panora supports integration with the following objects across multiple platforms | Zendesk Sell | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | | | Attio | ✔️ | | | | | | ✔️ | +### Ticketing -### Ticketing | | Tickets | Comments | Users | Contacts | Accounts | Tags | Teams | Collections | |-------------|:----------:|:-------:|:-------:|:------------:|:-------:|:-------:|:------:|:-------------:| -| Zendesk | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| Front | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| Zendesk | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | +| Front | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | | Jira | ✔ | ✔ | ✔ | | | ✔ | ✔ | ✔ | -| Gorgias | ✔ | ✔ | ✔ | ✔ | | ✔ | ✔ | ✔ | - -Your favourite software is missing? [Ask the community to build a connector!](https://github.com/panoratech/Panora/issues/new) - +| Gorgias | ✔ | ✔ | ✔ | ✔ | | ✔ | ✔ | | +Your favourite software is missing? [Ask the community to build a connector!](https://github.com/panoratech/Panora/issues/new) # 🕹️ Try the Open-Source version @@ -85,6 +83,7 @@ Your favourite software is missing? [Ask the community to build a connector!](ht ``` docker compose up ``` + Visit our [Quickstart Guide](https://docs.panora.dev/quick-start) to start adding integrations to your product # 🤔 Questions? Ask the core team diff --git a/packages/api/src/@core/utils/types/original/original.ticketing.ts b/packages/api/src/@core/utils/types/original/original.ticketing.ts index bb360ef86..678028eed 100644 --- a/packages/api/src/@core/utils/types/original/original.ticketing.ts +++ b/packages/api/src/@core/utils/types/original/original.ticketing.ts @@ -2,49 +2,24 @@ import { FrontAccountInput, FrontAccountOutput, } from '@ticketing/account/services/front/types'; -import { - GithubAccountInput, - GithubAccountOutput, -} from '@ticketing/account/services/github/types'; import { FrontAttachmentOutput } from '@ticketing/attachment/services/front/types'; -import { GithubAttachmentOutput } from '@ticketing/attachment/services/github/types'; import { ZendeskAttachmentOutput } from '@ticketing/attachment/services/zendesk/types'; import { FrontCommentInput, FrontCommentOutput, } from '@ticketing/comment/services/front/types'; -import { - GithubCommentInput, - GithubCommentOutput, -} from '@ticketing/comment/services/github/types'; -import { - HubspotCommentInput, - HubspotCommentOutput, -} from '@ticketing/comment/services/hubspot/types'; import { FrontContactInput, FrontContactOutput, } from '@ticketing/contact/services/front/types'; -import { - GithubContactInput, - GithubContactOutput, -} from '@ticketing/contact/services/github/types'; import { FrontTagInput, FrontTagOutput, } from '@ticketing/tag/services/front/types'; -import { - GithubTagInput, - GithubTagOutput, -} from '@ticketing/tag/services/github/types'; import { FrontTeamInput, FrontTeamOutput, } from '@ticketing/team/services/front/types'; -import { - GithubTeamInput, - GithubTeamOutput, -} from '@ticketing/team/services/github/types'; import { FrontTicketInput, FrontTicketOutput, @@ -61,11 +36,6 @@ import { FrontUserInput, FrontUserOutput, } from '@ticketing/user/services/front/types'; -import { - GithubUserInput, - GithubUserOutput, -} from '@ticketing/user/services/github/types'; - import { GorgiasTicketInput, GorgiasTicketOutput, @@ -158,42 +128,33 @@ export type OriginalTicketInput = export type OriginalCommentInput = | ZendeskCommentInput | FrontCommentInput - | GithubCommentInput - | HubspotCommentInput | GorgiasCommentInput | JiraCommentInput; //| JiraCommentServiceMgmtInput; /* user */ export type OriginalUserInput = | ZendeskUserInput - | GithubUserInput | FrontUserInput | GorgiasUserInput | JiraUserInput; //| JiraServiceMgmtUserInput; /* account */ -export type OriginalAccountInput = - | ZendeskAccountInput - | GithubAccountInput - | FrontAccountInput; +export type OriginalAccountInput = ZendeskAccountInput | FrontAccountInput; /* contact */ export type OriginalContactInput = | ZendeskContactInput - | GithubContactInput | FrontContactInput | GorgiasContactInput; /* tag */ export type OriginalTagInput = | ZendeskTagInput - | GithubTagInput | FrontTagInput | GorgiasTagInput | JiraTagInput; /* team */ export type OriginalTeamInput = | ZendeskTeamInput - | GithubTeamInput | FrontTeamInput | GorgiasTeamInput | JiraTeamInput; @@ -228,33 +189,25 @@ export type OriginalTicketOutput = export type OriginalCommentOutput = | ZendeskCommentOutput | FrontCommentOutput - | GithubCommentOutput - | HubspotCommentOutput | GorgiasCommentOutput | JiraCommentOutput; /* user */ export type OriginalUserOutput = | ZendeskUserOutput - | GithubUserOutput | FrontUserOutput | GorgiasUserOutput | JiraUserOutput; /* account */ -export type OriginalAccountOutput = - | ZendeskAccountOutput - | GithubAccountOutput - | FrontAccountOutput; +export type OriginalAccountOutput = ZendeskAccountOutput | FrontAccountOutput; /* contact */ export type OriginalContactOutput = | ZendeskContactOutput - | GithubContactOutput | FrontContactOutput | GorgiasContactOutput; /* tag */ export type OriginalTagOutput = | ZendeskTagOutput - | GithubTagOutput | FrontTagOutput | GorgiasTagOutput | JiraTagOutput; @@ -262,7 +215,6 @@ export type OriginalTagOutput = /* team */ export type OriginalTeamOutput = | ZendeskTeamOutput - | GithubTeamOutput | FrontTeamOutput | GorgiasTeamOutput | JiraTeamOutput; @@ -271,7 +223,6 @@ export type OriginalTeamOutput = export type OriginalAttachmentOutput = | ZendeskAttachmentOutput | FrontAttachmentOutput - | GithubAttachmentOutput | GorgiasAttachmentOutput | JiraAttachmentOutput; diff --git a/packages/api/src/ticketing/README.md b/packages/api/src/ticketing/README.md index 89cd585a8..e6801bef4 100644 --- a/packages/api/src/ticketing/README.md +++ b/packages/api/src/ticketing/README.md @@ -1,12 +1,12 @@ -### Ticketing +### Ticketing Panora supports integration with the following objects across multiple platforms: | | Tickets | Comments | Users | Contacts | Accounts | Tags | Teams | Collections | |-------------|:----------:|:-------:|:-------:|:------------:|:-------:|:-------:|:------:|:-------------:| -| Zendesk | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| Front | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| Zendesk | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | +| Front | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | | Jira | ✔ | ✔ | ✔ | | | ✔ | ✔ | ✔ | -| Gorgias | ✔ | ✔ | ✔ | ✔ | | ✔ | ✔ | ✔ | +| Gorgias | ✔ | ✔ | ✔ | ✔ | | ✔ | ✔ | | -Your favourite software is missing? [Ask the community to build a connector!](https://github.com/panoratech/Panora/issues/new) \ No newline at end of file +Your favourite software is missing? [Ask the community to build a connector!](https://github.com/panoratech/Panora/issues/new) diff --git a/packages/api/src/ticketing/account/types/mappingsTypes.ts b/packages/api/src/ticketing/account/types/mappingsTypes.ts index f1eb05ee8..1f7179213 100644 --- a/packages/api/src/ticketing/account/types/mappingsTypes.ts +++ b/packages/api/src/ticketing/account/types/mappingsTypes.ts @@ -1,10 +1,8 @@ import { FrontAccountMapper } from '../services/front/mappers'; -import { GithubAccountMapper } from '../services/github/mappers'; import { ZendeskAccountMapper } from '../services/zendesk/mappers'; const zendeskAccountMapper = new ZendeskAccountMapper(); const frontAccountMapper = new FrontAccountMapper(); -const githubAccountMapper = new GithubAccountMapper(); export const accountUnificationMapping = { zendesk: { @@ -15,8 +13,4 @@ export const accountUnificationMapping = { unify: frontAccountMapper.unify.bind(frontAccountMapper), desunify: frontAccountMapper.desunify, }, - github: { - unify: githubAccountMapper.unify.bind(githubAccountMapper), - desunify: githubAccountMapper.desunify, - }, }; diff --git a/packages/api/src/ticketing/attachment/types/mappingsTypes.ts b/packages/api/src/ticketing/attachment/types/mappingsTypes.ts index c38f6c6d4..57286259e 100644 --- a/packages/api/src/ticketing/attachment/types/mappingsTypes.ts +++ b/packages/api/src/ticketing/attachment/types/mappingsTypes.ts @@ -1,10 +1,8 @@ import { FrontAttachmentMapper } from '../services/front/mappers'; -import { GithubAttachmentMapper } from '../services/github/mappers'; import { GorgiasAttachmentMapper } from '../services/gorgias/mappers'; import { ZendeskAttachmentMapper } from '../services/zendesk/mappers'; const zendeskAttachmentMapper = new ZendeskAttachmentMapper(); -const githubAttachmentMapper = new GithubAttachmentMapper(); const frontAttachmentMapper = new FrontAttachmentMapper(); const gorgiasAttachmentMapper = new GorgiasAttachmentMapper(); @@ -17,10 +15,6 @@ export const attachmentUnificationMapping = { unify: frontAttachmentMapper.unify.bind(frontAttachmentMapper), desunify: frontAttachmentMapper.desunify, }, - github: { - unify: githubAttachmentMapper.unify.bind(githubAttachmentMapper), - desunify: githubAttachmentMapper.desunify, - }, gorgias: { unify: gorgiasAttachmentMapper.unify.bind(gorgiasAttachmentMapper), desunify: gorgiasAttachmentMapper.desunify, diff --git a/packages/api/src/ticketing/comment/types/mappingsTypes.ts b/packages/api/src/ticketing/comment/types/mappingsTypes.ts index a54430f46..9b996cee6 100644 --- a/packages/api/src/ticketing/comment/types/mappingsTypes.ts +++ b/packages/api/src/ticketing/comment/types/mappingsTypes.ts @@ -1,10 +1,8 @@ import { FrontCommentMapper } from '../services/front/mappers'; -import { GithubCommentMapper } from '../services/github/mappers'; import { GorgiasCommentMapper } from '../services/gorgias/mappers'; import { ZendeskCommentMapper } from '../services/zendesk/mappers'; const zendeskCommentMapper = new ZendeskCommentMapper(); -const githubCommentMapper = new GithubCommentMapper(); const frontCommentMapper = new FrontCommentMapper(); const gorgiasCommentMapper = new GorgiasCommentMapper(); @@ -17,10 +15,6 @@ export const commentUnificationMapping = { unify: frontCommentMapper.unify.bind(frontCommentMapper), desunify: frontCommentMapper.desunify, }, - github: { - unify: githubCommentMapper.unify.bind(githubCommentMapper), - desunify: githubCommentMapper.desunify, - }, gorgias: { unify: gorgiasCommentMapper.unify.bind(gorgiasCommentMapper), desunify: gorgiasCommentMapper.desunify, diff --git a/packages/api/src/ticketing/contact/types/mappingsTypes.ts b/packages/api/src/ticketing/contact/types/mappingsTypes.ts index a3804234b..3cadd18f6 100644 --- a/packages/api/src/ticketing/contact/types/mappingsTypes.ts +++ b/packages/api/src/ticketing/contact/types/mappingsTypes.ts @@ -1,11 +1,9 @@ import { FrontContactMapper } from '../services/front/mappers'; -import { GithubContactMapper } from '../services/github/mappers'; import { GorgiasContactMapper } from '../services/gorgias/mappers'; import { ZendeskContactMapper } from '../services/zendesk/mappers'; const zendeskContactMapper = new ZendeskContactMapper(); const frontContactMapper = new FrontContactMapper(); -const githubContactMapper = new GithubContactMapper(); const gorgiasContactMapper = new GorgiasContactMapper(); export const contactUnificationMapping = { @@ -17,10 +15,6 @@ export const contactUnificationMapping = { unify: frontContactMapper.unify.bind(frontContactMapper), desunify: frontContactMapper.desunify, }, - github: { - unify: githubContactMapper.unify.bind(githubContactMapper), - desunify: githubContactMapper.desunify, - }, gorgias: { unify: gorgiasContactMapper.unify.bind(gorgiasContactMapper), desunify: gorgiasContactMapper.desunify, diff --git a/packages/api/src/ticketing/tag/types/mappingsTypes.ts b/packages/api/src/ticketing/tag/types/mappingsTypes.ts index bee1dd1af..0e89c936a 100644 --- a/packages/api/src/ticketing/tag/types/mappingsTypes.ts +++ b/packages/api/src/ticketing/tag/types/mappingsTypes.ts @@ -1,11 +1,9 @@ import { FrontTagMapper } from '../services/front/mappers'; -import { GithubTagMapper } from '../services/github/mappers'; import { GorgiasTagMapper } from '../services/gorgias/mappers'; import { ZendeskTagMapper } from '../services/zendesk/mappers'; const zendeskTagMapper = new ZendeskTagMapper(); const frontTagMapper = new FrontTagMapper(); -const githubTagMapper = new GithubTagMapper(); const gorgiasTagMapper = new GorgiasTagMapper(); export const tagUnificationMapping = { @@ -17,10 +15,6 @@ export const tagUnificationMapping = { unify: frontTagMapper.unify.bind(frontTagMapper), desunify: frontTagMapper.desunify, }, - github: { - unify: githubTagMapper.unify.bind(githubTagMapper), - desunify: githubTagMapper.desunify, - }, gorgias: { unify: gorgiasTagMapper.unify.bind(gorgiasTagMapper), desunify: gorgiasTagMapper.desunify, diff --git a/packages/api/src/ticketing/team/types/mappingsTypes.ts b/packages/api/src/ticketing/team/types/mappingsTypes.ts index 7d1e7f5af..4013ab0b4 100644 --- a/packages/api/src/ticketing/team/types/mappingsTypes.ts +++ b/packages/api/src/ticketing/team/types/mappingsTypes.ts @@ -1,12 +1,10 @@ import { JiraTeamMapper } from '../services/jira/mappers'; import { FrontTeamMapper } from '../services/front/mappers'; -import { GithubTeamMapper } from '../services/github/mappers'; import { GorgiasTeamMapper } from '../services/gorgias/mappers'; import { ZendeskTeamMapper } from '../services/zendesk/mappers'; const zendeskTeamMapper = new ZendeskTeamMapper(); const frontTeamMapper = new FrontTeamMapper(); -const githubTeamMapper = new GithubTeamMapper(); const gorgiasTeamMapper = new GorgiasTeamMapper(); const jiraTeamMapper = new JiraTeamMapper(); @@ -19,10 +17,6 @@ export const teamUnificationMapping = { unify: frontTeamMapper.unify.bind(frontTeamMapper), desunify: frontTeamMapper.desunify, }, - github: { - unify: githubTeamMapper.unify.bind(githubTeamMapper), - desunify: githubTeamMapper.desunify, - }, gorgias: { unify: gorgiasTeamMapper.unify.bind(gorgiasTeamMapper), desunify: gorgiasTeamMapper.desunify, diff --git a/packages/api/src/ticketing/user/types/mappingsTypes.ts b/packages/api/src/ticketing/user/types/mappingsTypes.ts index 4d17bedf7..4ad24ef23 100644 --- a/packages/api/src/ticketing/user/types/mappingsTypes.ts +++ b/packages/api/src/ticketing/user/types/mappingsTypes.ts @@ -1,10 +1,8 @@ import { FrontUserMapper } from '../services/front/mappers'; -import { GithubUserMapper } from '../services/github/mappers'; import { ZendeskUserMapper } from '../services/zendesk/mappers'; const zendeskUserMapper = new ZendeskUserMapper(); const frontUserMapper = new FrontUserMapper(); -const githubUserMapper = new GithubUserMapper(); export const userUnificationMapping = { zendesk: { @@ -15,8 +13,4 @@ export const userUnificationMapping = { unify: frontUserMapper.unify.bind(frontUserMapper), desunify: frontUserMapper.desunify, }, - github: { - unify: githubUserMapper.unify.bind(githubUserMapper), - desunify: githubUserMapper.desunify, - }, };