import { Controller, Post, Body, UseGuards, Headers } from '@nestjs/common' import { classToPlain, plainToClass } from 'class-transformer' import { isNil } from 'lodash' import { Accounts, Credits } from '../domain' import { AuthTokenResult, Patient } from '../../../models' import { AppHeadersParams, BaseEventParams, Event } from '../../../params' import { BasicAuthorizationGuard } from '../../../guards' import { PatientService } from '../../../services' import { AddCreditByCampaignParams, SendTokenParams, SignUpParams, ValidateTokenParams } from './params' @UseGuards(BasicAuthorizationGuard) @Controller('patients') export class PatientsController { constructor( private readonly accounts: Accounts, private readonly credits: Credits, private readonly patientService: PatientService, ) {} @Post('sign_up') async signUp(@Body() { input }: SignUpParams, @Headers() { os }: AppHeadersParams): Promise { const patient = plainToClass(Patient, classToPlain(input.patient)) return await this.accounts.createPatientAndSendToken(patient, { appSignature: input.app_signature, os }) } @Post('send_token') async sendToken(@Body() { input }: SendTokenParams, @Headers() { os }: AppHeadersParams): Promise { return await this.accounts.sendTokenToPatient(input.login, { appSignature: input.app_signature, os }) } @Post('validate_token') async validateToken(@Body() { input }: ValidateTokenParams): Promise { return { token: await this.accounts.validatePatientToken(input.login, input.token) } } @Post('check_pending_credits') async checkPendingCredits(@Body() { event }: BaseEventParams): Promise { await this.credits.finishPendingCredits(event.data.new || event.data.row) } @Post('check_sign_up') async checkSignUp(@Body() { event }: BaseEventParams): Promise { if (!this.isManuallyEvent(event) && !this.checkIfPatientDoFirstSignUp(event)) return await this.credits.earnBioimpedanceCredit(event.data.new || event.data.row) } @Post('add_credit_by_campaign') async addCreditByCampaign( @Body() { input, session_variables }: AddCreditByCampaignParams, ): Promise<{ success: boolean }> { return { success: await this.credits.addByCampaign(session_variables['x-hasura-user-id'], input.campaign_value) } } @Post('/cache') async cache(@Body() { event }: BaseEventParams): Promise { const patient = event.data.new || event.data.row await this.patientService.createPatientCache(patient) } private checkIfPatientDoFirstSignUp = (event: Event): boolean => isNil(event.data.old?.sign_up_at) && !isNil(event.data.new.sign_up_at) private isManuallyEvent = (event: Event): boolean => isNil(event.data.new) && !isNil(event.data.row) }