import { Injectable } from '@nestjs/common' import { classToPlain, plainToClass } from 'class-transformer' import { Anthropometry, Patient } from '../models' import { HttpService } from '../services/http' import { BaseRepository } from './base.repository' import { AnthropometriesFilter } from './types' const BIOIMPEDANCE_FIELDS = [ 'id', 'lower_limit_weight', 'upper_limit_weight', 'total_body_water', 'lower_limit_total_body_water', 'upper_limit_total_body_water', 'bfm', 'lower_limit_bfm', 'upper_limit_bfm', 'smm', 'lower_limit_smm', 'upper_limit_smm', 'bmi', 'lower_limit_bmi', 'upper_limit_bmi', 'pbf', 'lower_limit_pbf', 'upper_limit_pbf', 'ffm_right_arm', 'ffm_left_arm', 'ffm_trunk', 'ffm_right_leg', 'ffm_left_leg', 'bfm_right_arm', 'bfm_left_arm', 'bfm_trunk', 'bfm_right_leg', 'bfm_left_leg', 'score', 'vfl', ] const INSERT = ` mutation insert_anthropometry($object: anthropometries_insert_input!) { insert_anthropometries_one(object: $object) { id bioimpedance_id } } ` const GET_BY_PATIENT_DONE_AT = ` query getByPatientAndDoneAt ($patientId: String!, $doneAt: date!) { anthropometries: anthropometries (where: {patient_id: {_eq: $patientId}, done_at: {_eq: $doneAt}}) { id } } ` const FIND_BY_PATIENT = ` query findByPatient ($patientId: String!) { anthropometries: anthropometries (where: {patient_id: {_eq: $patientId}, bioimpedance_id: {_is_null: false}}, order_by: { done_at: desc }) { id done_at weight height hips waist arm_left_relaxed arm_right_relaxed thigh_left thigh_right bioimpedance { ${BIOIMPEDANCE_FIELDS.join(' ')} } } } ` const FIND_BY_PATIENT_LOGIN = ` query findByPatient ($patientLogin: String!, $withoutBioimpedance: Boolean!) { patients(where: {_or: [{email: {_eq: $patientLogin}}, {document_number: {_eq: $patientLogin}}]}) { email document_number subscription { cancellation_at cancellation_request_at expires_at trial_expires_at } anthropometries: anthropometries (where: {bioimpedance_id: {_is_null: $withoutBioimpedance}}, order_by: { done_at: asc }) { id done_at weight height hips waist arm_left_relaxed arm_right_relaxed thigh_left thigh_right bioimpedance { ${BIOIMPEDANCE_FIELDS.join(' ')} } } } } ` const FIND_BY_BIOIMPEDANCE = ` query findByBioimpedance ($bioimpedanceId: uuid!) { anthropometries (where: {bioimpedance_id: {_eq: $bioimpedanceId}}) { id } } ` const GET = ` query anthropometry($id: uuid!) { anthropometry: anthropometries_by_pk(id: $id) { id patient_id user_id bioimpedance_id done_at } } ` const GET_WITH_BIOIMPEDANCE = ` query anthropometry($id: uuid!) { anthropometry: anthropometries_by_pk(id: $id) { id patient_id user_id bioimpedance_id done_at weight bioimpedance { ${BIOIMPEDANCE_FIELDS.join(' ')} } } } ` const FIND_BY_PATIENT_SINCE = ` query findByPatientAndSince ($patientId: String!, $doneAt: date!) { anthropometries (where: {patient_id: {_eq: $patientId}, done_at: {_gte: $doneAt}}, order_by: { done_at: desc }) { id weight done_at bioimpedance_id bioimpedance { ${BIOIMPEDANCE_FIELDS.join(' ')} } } } ` @Injectable() export class AnthropometryRepository extends BaseRepository { constructor(protected readonly httpService: HttpService) { super(httpService, 'anthropometry') } async create(anthropometry: Anthropometry): Promise<{ id: string; bioimpedance_id: string }> { const object = classToPlain(anthropometry) object.bioimpedance = { data: object.bioimpedance } const { data } = await this.fetchGraphQL({ body: { query: INSERT, variables: { object } }, }) return data.insert_anthropometries_one } async checkIfExistsByPatientAndDoneAt(patientId: string, doneAt: Date): Promise { const { data } = await this.fetchGraphQL({ body: { query: GET_BY_PATIENT_DONE_AT, variables: { patientId, doneAt } }, }) return data.anthropometries.length > 0 } async findByPatient(patientId: string): Promise { const { data } = await this.fetchGraphQL({ body: { query: FIND_BY_PATIENT, variables: { patientId } }, }) return data.anthropometries.length > 0 ? data.anthropometries.map(row => plainToClass(Anthropometry, row)) : [] } async findByPatientLogin(patientLogin: string, filter: AnthropometriesFilter): Promise { const { data } = await this.fetchGraphQL({ body: { query: FIND_BY_PATIENT_LOGIN, variables: { patientLogin, withoutBioimpedance: filter == 'measurements' }, }, }) return data.patients.map(row => plainToClass(Patient, row)).pop() } async findByBioimpedance(bioimpedanceId: string): Promise { const { data } = await this.fetchGraphQL({ body: { query: FIND_BY_BIOIMPEDANCE, variables: { bioimpedanceId } }, }) return data.anthropometries.map(row => plainToClass(Anthropometry, row)).pop() } async get(id: string): Promise { const { data } = await this.fetchGraphQL({ body: { query: GET, variables: { id } }, }) return data?.anthropometry ? Anthropometry.toInstance(data.anthropometry) : null } async getWithBioimpedance(id: string): Promise { const { data } = await this.fetchGraphQL({ body: { query: GET_WITH_BIOIMPEDANCE, variables: { id } }, }) return data?.anthropometry ? Anthropometry.toInstance(data.anthropometry) : null } async findByPatientSince(patientId: string, doneAt: Date): Promise { const { data } = await this.fetchGraphQL({ body: { query: FIND_BY_PATIENT_SINCE, variables: { patientId, doneAt } }, }) return data?.anthropometries ? data.anthropometries.map(row => Anthropometry.toInstance(row)) : [] } }