import { Injectable } from '@nestjs/common' import { first, isEmpty, isNil } from 'lodash' import { plainToClass, classToPlain } from 'class-transformer' import { addHours } from 'date-fns' import { validate } from 'uuid' import { CampaignMessage } from '../models' import { keepNumbers } from '../utils' import { HttpService } from '../services/http' import { BaseRepository } from './base.repository' const MULTI_QUERY_PREFIX = 'campaignmessage' const ATTRIBUTES = ` id content cell_phone document_number received_at sent_at type user_id ` const ALL = ` query campaignMessage { campaign_message { ${ATTRIBUTES} } } ` const INSERT = ` mutation insertCampaignMessage($campaign_message: campaign_message_insert_input!) { insert_campaign_message_one(object: $campaign_message) { id } } ` const FIND_BY_ID = (values: Array) => { const attrs = values.reduce((previous, current) => { const value = first(current.split('/')) if (isNil(value) || isEmpty(value) || !validate(value)) return previous return `${previous} ${MULTI_QUERY_PREFIX}${keepNumbers(value)}: campaign_message(where: {id: {_eq: "${value}"}}) { ...campaignMessageFields }` }, '') if (isEmpty(attrs)) return null return ` fragment campaignMessageFields on campaign_message { id } query findCampaignMessages { ${attrs} } ` } const UPDATE_DELIVERY_RELATED_FIELDS = (values: Array) => ` mutation updateCampaignMessages { ${values.reduce( (previous, current) => ` ${previous} ${MULTI_QUERY_PREFIX}${keepNumbers(current.id)}: update_campaign_message(where: {id: {_eq: "${current.id}"}}, _set: { received_at: ${current.received_at ? `"${current.received_at?.toISOString()}"` : 'null'}, delivery_status: "${current.delivery_status}", delivery_details: "${current.delivery_details}"}) { affected_rows } `, '', )} } ` const GET = ` query findCampaignMessage($id: uuid = "") { campaign_message(where: {id: {_eq: $id}}) { ${ATTRIBUTES} } } ` @Injectable() export class CampaignMessageRepository extends BaseRepository { constructor(protected readonly httpService: HttpService) { super(httpService, 'campaign_message') } async all(): Promise> { const { data } = await this.fetchGraphQL({ body: { query: ALL }, }) return (data.campaign_message || []).map(campaignMessage => plainToClass(CampaignMessage, campaignMessage)) } async updateDeliveryRelatedFields(campaignMessages: Array): Promise { await this.fetchGraphQL({ body: { query: UPDATE_DELIVERY_RELATED_FIELDS( campaignMessages.map(campaignMessage => classToPlain(campaignMessage) as CampaignMessage), ), }, }) } async create(campaignMessage: CampaignMessage): Promise { const qv = { campaign_message: classToPlain(campaignMessage) } const { data } = await this.fetchGraphQL({ body: { query: INSERT, variables: qv }, }) return data.insert_campaign_message_one.id } async findById(values: Array): Promise<{ [key: string]: CampaignMessage }> { const query = FIND_BY_ID(values) if (!query) return {} const { data } = await this.fetchGraphQL({ body: { query, }, }) return Object.keys(data).reduce((previous, key) => { if (isEmpty(data[key])) return previous return { ...previous, [data[key][0].id]: plainToClass(CampaignMessage, data[key][0]), } }, {}) } async get(id: string): Promise { const { data } = await this.fetchGraphQL({ body: { query: GET, variables: { id } }, }) return isEmpty(data.campaign_message) ? null : plainToClass(CampaignMessage, data.campaign_message[0]) } async scheduleCheckPushConversion(patientsToCheckPushConversion: Array): Promise { const { data } = await this.createScheduledEvent( '{{ACTIONS_HANDLER_URL}}/bioimpedances/check_push_conversion', addHours(new Date(), 1), 'patients to check push conversion', { patient_ids: patientsToCheckPushConversion, }, [ { name: 'Authorization', value: `Bearer ${globalThis.secret.hasura_graphql.access_token}`, }, ], ) return data } }