From 0ab3e0321580646e45b7eaea891a7675d2a62816 Mon Sep 17 00:00:00 2001 From: Praneeth Shetty Date: Wed, 7 Aug 2024 17:27:40 +0530 Subject: [PATCH] adding linear teams --- .../types/original/original.ticketing.ts | 6 +- .../ticketing/team/services/linear/index.ts | 67 +++++++++++++++++++ .../ticketing/team/services/linear/mappers.ts | 59 ++++++++++++++++ .../ticketing/team/services/linear/types.ts | 8 +++ .../api/src/ticketing/team/team.module.ts | 4 ++ 5 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 packages/api/src/ticketing/team/services/linear/index.ts create mode 100644 packages/api/src/ticketing/team/services/linear/mappers.ts create mode 100644 packages/api/src/ticketing/team/services/linear/types.ts 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 3783aac50..a8f782bb2 100644 --- a/packages/api/src/@core/utils/types/original/original.ticketing.ts +++ b/packages/api/src/@core/utils/types/original/original.ticketing.ts @@ -1,3 +1,5 @@ +import { LinearTeamInput, LinearTeamOutput } from '@ticketing/team/services/linear/types'; + import { GitlabUserInput, GitlabUserOutput } from '@ticketing/user/services/gitlab/types'; import { LinearUserInput, LinearUserOutput } from '@ticketing/user/services/linear/types'; @@ -173,7 +175,7 @@ export type OriginalTeamInput = | ZendeskTeamInput | FrontTeamInput | GorgiasTeamInput - | JiraTeamInput; + | JiraTeamInput | LinearTeamInput; /* attachment */ export type OriginalAttachmentInput = null; @@ -236,7 +238,7 @@ export type OriginalTeamOutput = | ZendeskTeamOutput | FrontTeamOutput | GorgiasTeamOutput - | JiraTeamOutput; + | JiraTeamOutput | LinearTeamOutput; /* attachment */ export type OriginalAttachmentOutput = diff --git a/packages/api/src/ticketing/team/services/linear/index.ts b/packages/api/src/ticketing/team/services/linear/index.ts new file mode 100644 index 000000000..952af6ad4 --- /dev/null +++ b/packages/api/src/ticketing/team/services/linear/index.ts @@ -0,0 +1,67 @@ +import { Injectable } from '@nestjs/common'; +import { LoggerService } from '@@core/@core-services/logger/logger.service'; +import { PrismaService } from '@@core/@core-services/prisma/prisma.service'; +import { EncryptionService } from '@@core/@core-services/encryption/encryption.service'; +import { TicketingObject } from '@ticketing/@lib/@types'; +import { ApiResponse } from '@@core/utils/types'; +import axios from 'axios'; +import { ActionType, handle3rdPartyServiceError } from '@@core/utils/errors'; +import { ServiceRegistry } from '../registry.service'; +import { ITeamService } from '@ticketing/team/types'; +import { LinearTeamOutput } from './types'; +import { SyncParam } from '@@core/utils/types/interface'; + +@Injectable() +export class LinearService implements ITeamService { + constructor( + private prisma: PrismaService, + private logger: LoggerService, + private cryptoService: EncryptionService, + private registry: ServiceRegistry, + ) { + this.logger.setContext( + TicketingObject.team.toUpperCase() + ':' + LinearService.name, + ); + this.registry.registerService('linear', this); + } + + async sync(data: SyncParam): Promise> { + try { + const { linkedUserId } = data; + + const connection = await this.prisma.connections.findFirst({ + where: { + id_linked_user: linkedUserId, + provider_slug: 'linear', + vertical: 'ticketing', + }, + }); + + const teamQuery = { + "query": "query { teams { nodes { id, name, description } }}" + }; + + let resp = await axios.post( + `${connection.account_url}`, + teamQuery, { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${this.cryptoService.decrypt( + connection.access_token, + )}`, + }, + }); + this.logger.log(`Synced linear teams !`); + + return { + data: resp.data.data.teams.nodes, + message: 'Linear teams retrieved', + statusCode: 200, + }; + } catch (error) { + throw error; + } + } +} + + diff --git a/packages/api/src/ticketing/team/services/linear/mappers.ts b/packages/api/src/ticketing/team/services/linear/mappers.ts new file mode 100644 index 000000000..d298b56a7 --- /dev/null +++ b/packages/api/src/ticketing/team/services/linear/mappers.ts @@ -0,0 +1,59 @@ +import { ITeamMapper } from '@ticketing/team/types'; +import { LinearTeamInput, LinearTeamOutput } from './types'; +import { + UnifiedTicketingTeamInput, + UnifiedTicketingTeamOutput, +} from '@ticketing/team/types/model.unified'; +import { MappersRegistry } from '@@core/@core-services/registries/mappers.registry'; +import { Injectable } from '@nestjs/common'; +import { Utils } from '@ticketing/@lib/@utils'; + +@Injectable() +export class LinearTeamMapper implements ITeamMapper { + constructor(private mappersRegistry: MappersRegistry, private utils: Utils) { + this.mappersRegistry.registerService('ticketing', 'team', 'linear', this); + } + desunify( + source: UnifiedTicketingTeamInput, + customFieldMappings?: { + slug: string; + remote_id: string; + }[], + ): LinearTeamInput { + return; + } + + unify( + source: LinearTeamOutput | LinearTeamOutput[], + connectionId: string, + customFieldMappings?: { + slug: string; + remote_id: string; + }[], + ): UnifiedTicketingTeamOutput | UnifiedTicketingTeamOutput[] { + // If the source is not an array, convert it to an array for mapping + const sourcesArray = Array.isArray(source) ? source : [source]; + + return sourcesArray.map((team) => + this.mapSingleTeamToUnified(team, connectionId, customFieldMappings), + ); + } + + private mapSingleTeamToUnified( + team: LinearTeamOutput, + connectionId: string, + customFieldMappings?: { + slug: string; + remote_id: string; + }[], + ): UnifiedTicketingTeamOutput { + const unifiedTeam: UnifiedTicketingTeamOutput = { + remote_id: team.id, + remote_data: team, + name: team.name, + description: team.description, + }; + + return unifiedTeam; + } +} diff --git a/packages/api/src/ticketing/team/services/linear/types.ts b/packages/api/src/ticketing/team/services/linear/types.ts new file mode 100644 index 000000000..ec9064371 --- /dev/null +++ b/packages/api/src/ticketing/team/services/linear/types.ts @@ -0,0 +1,8 @@ +export type LinearTeam = { + id: string + name: string + description: string +}; + +export type LinearTeamInput = Partial; +export type LinearTeamOutput = LinearTeamInput; \ No newline at end of file diff --git a/packages/api/src/ticketing/team/team.module.ts b/packages/api/src/ticketing/team/team.module.ts index d868b6185..fb61f5bac 100644 --- a/packages/api/src/ticketing/team/team.module.ts +++ b/packages/api/src/ticketing/team/team.module.ts @@ -1,3 +1,5 @@ +import { LinearTeamMapper } from './services/linear/mappers'; +import { LinearService } from './services/linear'; import { BullQueueModule } from '@@core/@core-services/queues/queue.module'; import { IngestDataService } from '@@core/@core-services/unification/ingest-data.service'; import { WebhookService } from '@@core/@core-services/webhooks/panora-webhooks/webhook.service'; @@ -36,6 +38,8 @@ import { TeamController } from './team.controller'; FrontTeamMapper, JiraTeamMapper, GorgiasTeamMapper, + LinearService, + LinearTeamMapper, ], exports: [SyncService, ServiceRegistry, WebhookService], })