UNPKG

@accounter/server

Version:
159 lines (146 loc) 5.51 kB
import { GraphQLError } from 'graphql'; import type { ClientIntegrationsInput, Resolvers } from '../../../__generated__/types.js'; import { addGreenInvoiceClient, updateGreenInvoiceClient, } from '../../green-invoice/helpers/green-invoice-clients.helper.js'; import { validateClientIntegrations } from '../helpers/clients.helper.js'; import { BusinessesProvider } from '../providers/businesses.provider.js'; import { ClientsProvider } from '../providers/clients.provider.js'; import type { FinancialEntitiesModule, IInsertClientParams, IUpdateClientParams, } from '../types.js'; export const clientsResolvers: FinancialEntitiesModule.Resolvers & Pick<Resolvers, 'UpdateClientResponse'> = { Query: { client: async (_, { businessId }, { injector }) => { try { const client = await injector.get(ClientsProvider).getClientByIdLoader.load(businessId); if (!client) { throw new GraphQLError(`Client with ID "${businessId}" not found`); } return client; } catch (error) { const message = 'Failed to fetch client'; console.error(message, error); throw new GraphQLError(message); } }, allClients: async (_, __, { injector }) => { try { const matches = await injector.get(ClientsProvider).getAllClients(); return matches; } catch (error) { const message = 'Failed to fetch clients'; console.error(message, error); throw new GraphQLError(message); } }, }, Mutation: { updateClient: async (_, { businessId, fields }, { injector }) => { let updatedIntegrations: ClientIntegrationsInput | undefined = fields.integrations ?? undefined; if (updatedIntegrations) { const currentClient = await injector .get(ClientsProvider) .getClientByIdLoader.load(businessId); if (!currentClient) { throw new GraphQLError(`Client with ID="${businessId}" not found`); } const currentIntegrations = validateClientIntegrations(currentClient.integrations); updatedIntegrations = { ...currentIntegrations, ...updatedIntegrations, }; } const adjustedFields: IUpdateClientParams = { businessId, emails: fields.emails ? [...fields.emails] : undefined, newBusinessId: fields.newBusinessId, integrations: updatedIntegrations, }; try { const [updatedClient] = await injector .get(ClientsProvider) .updateClient({ ...adjustedFields, businessId }) .catch((e: Error) => { const message = `Error updating client ID="${businessId}"`; console.error(`${message}: ${e}`); if (e instanceof GraphQLError) { throw e; } throw new Error(message); }); // update green invoice client if needed await updateGreenInvoiceClient(businessId, injector, undefined, fields); return updatedClient; } catch (e) { return { __typename: 'CommonError', message: `Failed to update client ID="${businessId}": ${(e as Error).message}`, }; } }, insertClient: async (_, { fields }, { injector }) => { try { const newClient: IInsertClientParams = { businessId: fields.businessId, emails: fields.emails ? [...fields.emails] : [], integrations: fields.integrations ?? {}, }; const [insertClient] = await injector.get(ClientsProvider).insertClient(newClient); if (!insertClient) { throw new Error(`No client returned after insertion`); } // create green invoice client record await addGreenInvoiceClient(insertClient.business_id, injector); return insertClient; } catch (e) { console.error(e); return { __typename: 'CommonError', message: `Failed to create Client`, }; } }, }, Client: { id: business => business.business_id, originalBusiness: async (business, _, { injector }) => { const businessMatch = await injector .get(BusinessesProvider) .getBusinessByIdLoader.load(business.business_id); if (!businessMatch) { throw new GraphQLError('Business not found'); } return businessMatch; }, emails: business => business.emails ?? [], integrations: business => business, }, ClientIntegrations: { id: business => `${business.business_id}-integrations`, hiveId: business => validateClientIntegrations(business.integrations).hiveId ?? null, linearId: business => validateClientIntegrations(business.integrations).linearId ?? null, slackChannelKey: business => validateClientIntegrations(business.integrations).slackChannelKey ?? null, notionId: business => validateClientIntegrations(business.integrations).notionId ?? null, workflowyUrl: business => validateClientIntegrations(business.integrations).workflowyUrl ?? null, }, LtdFinancialEntity: { clientInfo: async (business, _, { injector }) => { const client = await injector.get(ClientsProvider).getClientByIdLoader.load(business.id); return client || null; }, }, UpdateClientResponse: { __resolveType: (obj, _context, _info) => { if ('__typename' in obj && obj.__typename === 'CommonError') return 'CommonError'; return 'Client'; }, }, };