Library for consuming Afya Digital Prescription Engine - Frontend integration
Previous version status:
Version | Status |
---|---|
1.x |
deprecated |
2.x |
deprecated |
3.x |
deprecated |
# npm
npm install @afyadigital/rx-engine --save
# yarn
yarn add @afyadigital/rx-engine
#pnpm
pnpm add @afyadigital/rx-engine
Renders the RX Engine App, given a configuration object
Property | Type | Default | Description |
---|---|---|---|
target |
string |
- | Selector of target element to render the app |
auth |
Object { token }
|
- | Authentication info object |
auth.token |
string |
- | Physician token(*) |
initialValue |
Object { appointment, patient, medications }
|
- | Info used on app initialization |
initialValue.appointment |
Object { id }
|
- | Appointment info object |
initialValue.appointment.id |
string |
- | Appointment id on host application |
initialValue.patient |
Object { id, name, address }
|
- | Patient info object (optional) |
initialValue.patient.id |
string |
- | Patient id on host application |
initialValue.patient.name |
string |
- | Patient name on host application |
initialValue.patient.civilName |
string |
- | Patient civil name on host application |
initialValue.patient.address |
string |
- | Patient address on host application (optional) |
initialValue.patient.phone |
string |
- | Patient phone on host application (optional), eleven digits of length |
initialValue.patient.email |
string |
- | Patient email on host application (optional) |
initialValue.patient.cpf |
string |
- | Patient cpf on host application (optional) |
initialValue.patient.height |
string |
- | Patient height on host application (optional), in centimeters (cm) |
initialValue.patient.weight |
string |
- | Patient weight on host application (optional), in kilos (kg) |
initialValue.patient.motherName |
string |
- | Patient mother name on host application (optional) |
initialValue.medications |
Array of objects [{ type, title, patientInstruction, printType }]
|
- | Medication info object |
initialValue.medications[<index>].type |
string |
- | Medication type (e.g: product, substance or freeText) |
initialValue.medications[<index>].id |
string |
- | Medication id sent from external partner (optional if type is freeText) |
initialValue.medications[<index>].title |
string |
- | Medication title sent from external partner |
initialValue.medications[<index>].patientInstruction |
string |
- | Medication instructions for patient, sent from external partner |
initialValue.medications[<index>].printType |
string |
- | Medication prescription type (e.g: simple, special and antimicrobial) sent from partner |
initialValue.medications[<index>].quantity |
string |
- | Medication quantity sent from external (optional)partner |
initialValue.medications[<index>].unit |
string |
- | Medication quantity unit sent from external (optional) partner |
initialValue.medications[<index>].subtitle |
string |
- | Medication subtitle sent from external partner (required just if type is product) |
initialValue.medications[<index>].description |
string |
- | Medication description sent from external partner (required just if type is product) |
initialValue.medications[<index>].laboratoryName |
string |
- | Medication laboratory sent from external partner(required just if type is product) |
initialValue.medications[<index>].category |
string |
- | Medication category sent from external partner (required just if type is product) |
initialValue.medications[<index>].maxPrice |
string |
- | Medication maximun price sent from external partner (required just if type is product) |
initialValue.medications[<index>].available |
string |
- | Medication availability sent from partner (required just if type is product) |
* Get the physician authentication token through our api
Example:
/** Create a configuration to render the Prescription Engine */
// AppEnvOptions = 'production' | 'development'
const appEnv = "development";
const config: EngineConfig = {
// target element selector. example: <div id="rx-engine"></div>
target: `#rx-engine`,
// physician authentication token
auth: { token: 'jwt-token' },
initialValue: {
appointment: {
id: '123'
}
// patient identification and name to create a prescription with
patient: {
id: '123',
name: 'Jhon Doe',
civilName: 'Jhonnie',
address: 'Foo Bar',
phone: '45999999999',
email: 'patient@email.com',
cpf: '682.733.635-20',
height: "179",
weight: "90",
motherName: 'Jhoana Doe'
},
// medications that could be imported from an external partner
medications: [
{
type: 'freeText',
title: 'Test Med',
patientInstruction: '1 pill every morning for 10 days';
printType: 'simple';
}
]
},
}
/** Render it on your target element */
render(config, env)
Clean previous mounted app and listeners
unmount();
API so you can register to events from prescription app. Make sure to render
the app before subscribing to events.
name | description | payload |
---|---|---|
'app:init' |
on app initialization | null |
'app:revokedToken' |
when physician token is expired/invalid | null |
'prescription:saved' |
when user saves the prescription | SavedPrescriptionEventPayload |
'prescription:itemAdded' |
when user adds another item to prescription | PrescriptionItemEventPayload |
'printConfig:saved' |
when user saves the print config | SavedPrintConfigEventPayload |
type FreeTextItem = {
title: string;
patientInstruction: string;
quantity: number;
unit: string;
};
type MedicationItem = FreeTextItem & {
id: string;
};
type PrescriptionItemEventPayload = {
type: 'product' | 'substance' | 'freeText';
origin: 'user' | 'integration';
data: FreeTextItem | MedicationItem;
};
Example:
import { events } from '@afyadigital/rx-engine'
const doSomething = (prescriptionItem) => { ... }
// register a callback function to an event
events.listen('prescription:itemAdded', doSomething)
// remove an event listener
events.remove('prescription:itemAdded', doSomething)
// remove all listeners
events.cleanup()
type Patient = {
name: string;
externalId: string;
address?: string;
phone?: string;
email?: string;
cpf?: string;
height?: string;
weight?: string;
motherName?: string;
};
type UserInput = {
patientInstruction: string;
quantity?: number;
unit?: string;
printType: PrintTypeEnum; // simple | special | antimicrobial
};
type FreeText = {
type: 'freeText';
title: string;
} & UserInput;
type Product = {
type: 'product';
id: string;
title: string;
subtitle: string;
description: string;
laboratoryName: string;
category: string;
maxPrice: string;
available: boolean;
} & UserInput;
type Substance = {
type: 'substance';
id: string;
title: string;
} & UserInput;
type PrescriptionItem = FreeText | Product | Substance;
export type Exam = {
id: string;
code: string;
term: string;
};
export type PrescritableExam = {
quantity: number;
exam: Exam;
};
export type ExamPage = {
items: PrescritableExam[];
clinicalIndication?: string;
};
export type VaccineBase = {
title: string;
patientInstruction: string;
quantity: number;
};
export type VaccineProduct = {
id: string;
type: 'product';
} & VaccineBase;
export type VaccineFreeText = {
type: 'freeText';
} & VaccineBase;
export type Vaccine = VaccineProduct | VaccineFreeText;
export type VaccinePage = {
items: Vaccine[];
};
export type Lme = {
patient: {
fullName: string;
height: string;
isCapable: boolean;
mothersName: string;
weight: string;
responsibleName?: string;
filledBy: {
responsible:
| 'patient'
| 'patientMother'
| 'responsible'
| 'physician'
| 'other';
name?: string;
cpf?: string;
};
skinColor: 'branca' | 'preta' | 'parda' | 'amarela' | 'indigena';
ethnicity?: string;
document: {
type: 'cpf' | 'cns';
value: string;
};
email: string;
phone: string;
};
org: {
cnes: string;
name: string;
};
physician: {
name: string;
cns: string;
};
treatments: LmeTreatment[];
};
export type LmeTreatment = {
id: string;
cid10: string;
diagnostic: string;
solicitationDate: string;
anamnese: string;
exams: {
id: string;
term: string;
code: string;
type: string;
quantity: number;
}[];
medications: {
months: string[];
name: string;
id: string;
type: string;
}[];
onTreatment: boolean;
treatmentReport?: string;
pdfUrl: string; // LME prescription pdf
examUrl?: string; // prescription pdf for all exams
protocols?: string[]; // terms prescriptions
prescriptions?: {
// LME medications prescriptions
simple: LmeMedicationPrescription;
special: LmeMedicationPrescription[];
antimicrobial: LmeMedicationPrescription[];
};
};
export type LmeMedicationPrescription = {
id: string;
pdfUrl: string;
prescriptionDate: string;
quantity: number;
medications: string[];
};
export type SavedPrescriptionEventPayload = {
id: string;
patient: Patient;
issuedAt?: string;
items: PrescriptionItem[];
exams: ExamPage[];
vaccines: VaccinePage[];
pdfUrl?: string;
lme?: Lme;
};
After engine app was initialized (check 'app:init'
event above), you can dispatch events on the engine.
type ItemFreeText = {
title: string;
type: 'freeText';
patientInstruction: string;
quantity: number;
unit: string;
};
type ItemMedication = {
id: string;
type: 'product' | 'substance';
patientInstruction: string;
quantity: number;
unit: string;
};
export type PrescriptionItem = ItemFreeText | ItemMedication;
Usage example:
import { commands, events } from '@afyadigital/rx-engine';
const onInit = async () => {
await commands.addPrescriptionItem({
title: 'Paracetamol',
type: 'freeText',
patientInstruction: 'tomar 2x ao dia com intervalo de 4 horas',
quantity: 2,
unit: 'comprimidos',
});
};
events.listen('app:init', onInit);
savePrescriptionItem(item: SaveItemMedication)
: Adds item into prescription or save to add in next prescription.
export type SaveItemMedication = {
id: string;
type: 'product' | 'substance';
patientInstruction: string;
quantity: number;
highlight: {
title: string;
subtitle?: string;
};
unit: {
singular: string;
plural: string;
};
title: string;
subtitle: string;
description: string;
laboratoryName: string;
category: string;
maxPrice: string;
available: string | boolean;
listType: string;
prescriptionType: string;
ean1: string;
};
Usage example:
import { commands, events } from '@afyadigital/rx-engine';
const onInit = async () => {
commands.savePrescriptionItem({
id: '11a111bc-de12-461b-b0fe-62e7a8f83cb0',
highlight: {
title: '<mark>Neosaldina</mark>',
},
unit: {
singular: 'comprimido',
plural: 'comprimidos',
},
type: 'product',
title: 'Neosaldina',
subtitle: 'Comprimido revestido • 60 un',
description:
'Dipirona 300 mg + Mucato de Isometepteno 30 mg + Cafeína 30 mg',
laboratoryName: 'Takeda',
category: 'Referência',
maxPrice: '60,03',
available: true,
listType: '',
prescriptionType: '',
ean1: '7896641810985',
patientInstruction: '',
quantity: 0,
});
};
events.listen('app:init', onInit);
Usage example:
import { commands, events } from '@afyadigital/rx-engine';
events.listen('revokedToken', async () => {
const token = await getPhysicianToken(); // check physician login below*
await commands.updateToken(token);
});
enum TrackActivityClickEnum {
MenuPep = 'menuPep',
}
type TrackUserActivityEvent = {
click: TrackActivityClickEnum;
};
Usage example:
import { commands } from '@afyadigital/rx-engine'
const handleClick = () => {
commands.trackUserActivity({ click: TrackActivityClickEnum.MenuPep })
}
return (
<MenuItem>
<Button onClick={handleClick}>Prescrição</Button>
</MenuItem>
)
import { useEffect } from 'react'
import { render, unmount } from '@afyadigital/rx-engine'
import type { EngineConfig } from '@afyadigital/rx-engine'
const TARGET_ID = 'rx-engine-container'
function AfyaPrescription() {
useEffect(() => {
const config: EngineConfig = {
target: `#${TARGET_ID}`,
auth: { token: 'physician-auth-token' },
initialValue: {
patient: {
id: '123',
name: 'Jhon Doe',
civilName: 'Jonnie',
address: 'Foo Bar',
phone: '45999999999',
email: 'patient@email.com',
cpf: '682.733.635-20',
height: '179',
weight: '90',
motherName: 'Jhoana Doe',
},
},
}
render(config)
return () => unmount()
}, [])
return <div id={TARGET_ID} />
}