@andes/fhir 1.11.1 → 1.12.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/.circleci/config.yml +71 -68
  2. package/.editorconfig +13 -13
  3. package/.env.example +2 -0
  4. package/.github/labeler.yml +10 -10
  5. package/.github/pull_request_template.md +28 -28
  6. package/.github/workflows/build_test.yml +14 -14
  7. package/.github/workflows/has_conflicts.yml +13 -13
  8. package/.vscode/settings.json +2 -0
  9. package/CHANGELOG.md +312 -291
  10. package/LICENSE +674 -674
  11. package/README.md +2 -2
  12. package/coverage/clover.xml +198 -0
  13. package/coverage/coverage-final.json +5 -0
  14. package/coverage/lcov-report/base.css +224 -0
  15. package/coverage/lcov-report/block-navigation.js +87 -0
  16. package/coverage/lcov-report/config.ts.html +136 -0
  17. package/coverage/lcov-report/device.ts.html +193 -0
  18. package/coverage/lcov-report/favicon.png +0 -0
  19. package/coverage/lcov-report/helpers/index.html +116 -0
  20. package/coverage/lcov-report/helpers/patientFactory.ts.html +124 -0
  21. package/coverage/lcov-report/index.html +131 -0
  22. package/coverage/lcov-report/lib/config.ts.html +136 -0
  23. package/coverage/lcov-report/lib/device.ts.html +193 -0
  24. package/coverage/lcov-report/lib/index.html +146 -0
  25. package/coverage/lcov-report/lib/patient.ts.html +1267 -0
  26. package/coverage/lcov-report/patient.ts.html +1207 -0
  27. package/coverage/lcov-report/prettify.css +1 -0
  28. package/coverage/lcov-report/prettify.js +2 -0
  29. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  30. package/coverage/lcov-report/sorter.js +210 -0
  31. package/coverage/lcov.info +410 -0
  32. package/dist/index.js +51 -32
  33. package/dist/index.js.map +1 -1
  34. package/dist/src/data/patient.json +191 -185
  35. package/dist/src/helpers/patientFactory.js +31 -0
  36. package/dist/src/helpers/patientFactory.js.map +1 -0
  37. package/dist/src/lib/allergyIntolerance.js +39 -39
  38. package/dist/src/lib/allergyIntolerance.js.map +1 -1
  39. package/dist/src/lib/bundle.js +25 -22
  40. package/dist/src/lib/bundle.js.map +1 -1
  41. package/dist/src/lib/composition.js +151 -150
  42. package/dist/src/lib/composition.js.map +1 -1
  43. package/dist/src/lib/condition.js +79 -79
  44. package/dist/src/lib/condition.js.map +1 -1
  45. package/dist/src/lib/config.js +20 -22
  46. package/dist/src/lib/config.js.map +1 -1
  47. package/dist/src/lib/config.test.js +12 -12
  48. package/dist/src/lib/config.test.js.map +1 -1
  49. package/dist/src/lib/device.js +38 -38
  50. package/dist/src/lib/device.js.map +1 -1
  51. package/dist/src/lib/device.test.js +9 -9
  52. package/dist/src/lib/device.test.js.map +1 -1
  53. package/dist/src/lib/document-reference.js +106 -103
  54. package/dist/src/lib/document-reference.js.map +1 -1
  55. package/dist/src/lib/immunization.js +67 -67
  56. package/dist/src/lib/medication.js +64 -64
  57. package/dist/src/lib/medication.js.map +1 -1
  58. package/dist/src/lib/medicationRequest.js +102 -99
  59. package/dist/src/lib/medicationRequest.js.map +1 -1
  60. package/dist/src/lib/medicationStatement.js +55 -55
  61. package/dist/src/lib/medicationStatement.js.map +1 -1
  62. package/dist/src/lib/organization.js +90 -90
  63. package/dist/src/lib/organization.js.map +1 -1
  64. package/dist/src/lib/patient.js +378 -360
  65. package/dist/src/lib/patient.js.map +1 -1
  66. package/dist/src/lib/patient.test.js +78 -39
  67. package/dist/src/lib/patient.test.js.map +1 -1
  68. package/dist/src/lib/practitioner.js +160 -160
  69. package/dist/src/lib/practitioner.js.map +1 -1
  70. package/index.ts +31 -31
  71. package/jest.config.js +11 -11
  72. package/package.json +45 -54
  73. package/release.config.js +74 -0
  74. package/src/data/patient.json +190 -184
  75. package/src/helpers/patientFactory.ts +13 -0
  76. package/src/lib/allergyIntolerance.ts +36 -36
  77. package/src/lib/bundle.ts +19 -19
  78. package/src/lib/composition.ts +153 -153
  79. package/src/lib/condition.ts +80 -80
  80. package/src/lib/config.test.ts +13 -13
  81. package/src/lib/config.ts +17 -17
  82. package/src/lib/device.test.ts +9 -9
  83. package/src/lib/device.ts +36 -36
  84. package/src/lib/document-reference.ts +102 -102
  85. package/src/lib/immunization.ts +64 -64
  86. package/src/lib/medication.ts +61 -61
  87. package/src/lib/medicationRequest.ts +100 -100
  88. package/src/lib/medicationStatement.ts +52 -52
  89. package/src/lib/organization.ts +89 -89
  90. package/src/lib/patient.test.ts +62 -38
  91. package/src/lib/patient.ts +394 -374
  92. package/src/lib/practitioner.ts +157 -157
  93. package/tsconfig.test.json +17 -17
  94. package/tslint.json +138 -138
@@ -1,52 +1,52 @@
1
- /**
2
- * Encode de Medicamentos from ANDES to FHIR
3
- * @param {} medicationStatement
4
- */
5
- // Muy incompleto hay que mejorarlo mucho todavía
6
- export function encode(patientReference, medicationReference, prestacionMedicamento) {
7
- return {
8
- resourceType: 'MedicationStatement',
9
- status: (prestacionMedicamento.valor.estado === 'activo') ? 'active' : 'inactive',
10
- id: prestacionMedicamento._id, // El código de la prestación donde está el registro del contexto de porque está consumiendo el medicamento
11
- effectiveDateTime: prestacionMedicamento.createdAt,
12
- medicationCodeableConcept: {
13
- coding: [
14
- {
15
- system: 'http://snomed.info/sct',
16
- code: prestacionMedicamento.concepto.conceptId,
17
- display: prestacionMedicamento.concepto.term
18
- }
19
- ]
20
- },
21
- meta: {
22
- profile: [
23
- 'http://hl7.org/fhir/uv/ips/StructureDefinition/medication-ips'
24
- ]
25
- },
26
- // extension: null,
27
- // identifier: '', // Business identifier, not a resource identifier
28
- subject: {
29
- reference: patientReference
30
- },
31
- medicationReference: {
32
- reference: medicationReference
33
- },
34
- // context: null, // Encounter | Episode of care (podría ser el informe del encuentro o lo que definamos que brinda más información sobre el por qué)
35
- dosage: [
36
- {
37
- text: prestacionMedicamento.valor, // indicación
38
- route: { coding: [{ system: 'http://standardterms.edqm.eu', code: prestacionMedicamento._id, display: prestacionMedicamento.nombre }] },
39
- timing: { coding: { system: 'http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation', code: 'QD', display: 'Diario' } }
40
- }
41
- ],
42
- // effectivePeriod: { // Esta parte se podría calcular entre la fecha de la prestación y la cant. de tiempo que se indica, pero hay problemas
43
- // en este registro ya que no siempre está la unidad de tiempo (dias, mes, etc) hay q ver si no es un bug.
44
- // start: '2015-03'
45
- // },
46
- text: {
47
- status: 'generated',
48
- div: `<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative with Details</b></p><p><b>id</b>: Medicacion </p><p><b>meta</b>: </p><p><b>text</b>: ${prestacionMedicamento.concepto.term}</p></div>`
49
- }
50
- };
51
- }
52
-
1
+ /**
2
+ * Encode de Medicamentos from ANDES to FHIR
3
+ * @param {} medicationStatement
4
+ */
5
+ // Muy incompleto hay que mejorarlo mucho todavía
6
+ export function encode(patientReference, medicationReference, prestacionMedicamento) {
7
+ return {
8
+ resourceType: 'MedicationStatement',
9
+ status: (prestacionMedicamento.valor.estado === 'activo') ? 'active' : 'inactive',
10
+ id: prestacionMedicamento._id, // El código de la prestación donde está el registro del contexto de porque está consumiendo el medicamento
11
+ effectiveDateTime: prestacionMedicamento.createdAt,
12
+ medicationCodeableConcept: {
13
+ coding: [
14
+ {
15
+ system: 'http://snomed.info/sct',
16
+ code: prestacionMedicamento.concepto.conceptId,
17
+ display: prestacionMedicamento.concepto.term
18
+ }
19
+ ]
20
+ },
21
+ meta: {
22
+ profile: [
23
+ 'http://hl7.org/fhir/uv/ips/StructureDefinition/medication-ips'
24
+ ]
25
+ },
26
+ // extension: null,
27
+ // identifier: '', // Business identifier, not a resource identifier
28
+ subject: {
29
+ reference: patientReference
30
+ },
31
+ medicationReference: {
32
+ reference: medicationReference
33
+ },
34
+ // context: null, // Encounter | Episode of care (podría ser el informe del encuentro o lo que definamos que brinda más información sobre el por qué)
35
+ dosage: [
36
+ {
37
+ text: prestacionMedicamento.valor, // indicación
38
+ route: { coding: [{ system: 'http://standardterms.edqm.eu', code: prestacionMedicamento._id, display: prestacionMedicamento.nombre }] },
39
+ timing: { coding: { system: 'http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation', code: 'QD', display: 'Diario' } }
40
+ }
41
+ ],
42
+ // effectivePeriod: { // Esta parte se podría calcular entre la fecha de la prestación y la cant. de tiempo que se indica, pero hay problemas
43
+ // en este registro ya que no siempre está la unidad de tiempo (dias, mes, etc) hay q ver si no es un bug.
44
+ // start: '2015-03'
45
+ // },
46
+ text: {
47
+ status: 'generated',
48
+ div: `<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative with Details</b></p><p><b>id</b>: Medicacion </p><p><b>meta</b>: </p><p><b>text</b>: ${prestacionMedicamento.concepto.term}</p></div>`
49
+ }
50
+ };
51
+ }
52
+
@@ -1,89 +1,89 @@
1
- import { getDominio, makeUrl } from './config';
2
-
3
- /**
4
- * Encode a organization from ANDES to FHIR
5
- * @param {} organization
6
- */
7
- export function encode(organization) {
8
- let data = organization;
9
- if (data) {
10
- let identificadores: any[] = data.codigo.sisa ? [{
11
- assigner: 'sisa',
12
- value: data.codigo.sisa
13
- }] : [];
14
- if (data.codigo.cuie) {
15
- identificadores.push({
16
- assigner: 'cuie',
17
- value: data.codigo.cuie
18
- });
19
- }
20
- if (data.codigo.remediar) {
21
- identificadores.push({
22
- assigner: 'remediar',
23
- value: data.codigo.remediar
24
- });
25
- }
26
- if (data.codigo.sips) {
27
- identificadores.push({
28
- assigner: 'sips',
29
- value: data.codigo.sips
30
- });
31
- }
32
- identificadores.push({
33
- system: makeUrl('Organization'),
34
- value: data._id
35
- });
36
-
37
- let contactos = data.contacto ? data.contacto.map(unContacto => {
38
- let cont = {
39
- resourceType: 'ContactPoint',
40
- value: unContacto.valor,
41
- rank: unContacto.ranking,
42
- };
43
- switch (unContacto.tipo) {
44
- case 'fijo':
45
- cont['system'] = 'phone';
46
- break;
47
- case 'celular':
48
- cont['system'] = 'phone';
49
- break;
50
- case 'email':
51
- cont['system'] = 'email';
52
- break;
53
- }
54
- return cont;
55
- }) : [];
56
- // Parsea direcciones
57
- let direcciones = data.direccion ? [{
58
- resourceType: 'Address',
59
- postalCode: data.direccion.codigoPostal ? data.direccion.codigoPostal : '',
60
- line: [data.direccion.valor],
61
- city: data.direccion.ubicacion.localidad ? data.direccion.ubicacion.localidad.nombre : '',
62
- state: data.direccion.ubicacion.provincia ? data.direccion.ubicacion.provincia.nombre : '',
63
- country: data.direccion.ubicacion.pais ? data.direccion.ubicacion.pais.nombre : '',
64
- }] : [];
65
-
66
- // Armamos la organizacion FHIR
67
- let organizacionFHIR = {
68
- id: data.id,
69
- resourceType: 'Organization',
70
- identifier: identificadores,
71
- active: data.activo ? data.activo : null,
72
- type: [{
73
- resourceType: 'CodeableConcept',
74
- text: data.tipoEstablecimiento ? data.tipoEstablecimiento.nombre : null,
75
- }],
76
- name: data.nombre ? data.nombre : null, // Name used for the organization
77
- };
78
- if (contactos.length > 0) { // A contact detail for the organization
79
- organizacionFHIR['telecom'] = contactos;
80
- }
81
-
82
- if (direcciones) { // An address for the organization
83
- organizacionFHIR['address'] = direcciones;
84
- }
85
- return organizacionFHIR;
86
- } else {
87
- return null;
88
- }
89
- }
1
+ import { getDominio, makeUrl } from './config';
2
+
3
+ /**
4
+ * Encode a organization from ANDES to FHIR
5
+ * @param {} organization
6
+ */
7
+ export function encode(organization) {
8
+ let data = organization;
9
+ if (data) {
10
+ let identificadores: any[] = data.codigo.sisa ? [{
11
+ assigner: 'sisa',
12
+ value: data.codigo.sisa
13
+ }] : [];
14
+ if (data.codigo.cuie) {
15
+ identificadores.push({
16
+ assigner: 'cuie',
17
+ value: data.codigo.cuie
18
+ });
19
+ }
20
+ if (data.codigo.remediar) {
21
+ identificadores.push({
22
+ assigner: 'remediar',
23
+ value: data.codigo.remediar
24
+ });
25
+ }
26
+ if (data.codigo.sips) {
27
+ identificadores.push({
28
+ assigner: 'sips',
29
+ value: data.codigo.sips
30
+ });
31
+ }
32
+ identificadores.push({
33
+ system: makeUrl('Organization'),
34
+ value: data._id
35
+ });
36
+
37
+ let contactos = data.contacto ? data.contacto.map(unContacto => {
38
+ let cont = {
39
+ resourceType: 'ContactPoint',
40
+ value: unContacto.valor,
41
+ rank: unContacto.ranking,
42
+ };
43
+ switch (unContacto.tipo) {
44
+ case 'fijo':
45
+ cont['system'] = 'phone';
46
+ break;
47
+ case 'celular':
48
+ cont['system'] = 'phone';
49
+ break;
50
+ case 'email':
51
+ cont['system'] = 'email';
52
+ break;
53
+ }
54
+ return cont;
55
+ }) : [];
56
+ // Parsea direcciones
57
+ let direcciones = data.direccion ? [{
58
+ resourceType: 'Address',
59
+ postalCode: data.direccion.codigoPostal ? data.direccion.codigoPostal : '',
60
+ line: [data.direccion.valor],
61
+ city: data.direccion.ubicacion.localidad ? data.direccion.ubicacion.localidad.nombre : '',
62
+ state: data.direccion.ubicacion.provincia ? data.direccion.ubicacion.provincia.nombre : '',
63
+ country: data.direccion.ubicacion.pais ? data.direccion.ubicacion.pais.nombre : '',
64
+ }] : [];
65
+
66
+ // Armamos la organizacion FHIR
67
+ let organizacionFHIR = {
68
+ id: data.id,
69
+ resourceType: 'Organization',
70
+ identifier: identificadores,
71
+ active: data.activo ? data.activo : null,
72
+ type: [{
73
+ resourceType: 'CodeableConcept',
74
+ text: data.tipoEstablecimiento ? data.tipoEstablecimiento.nombre : null,
75
+ }],
76
+ name: data.nombre ? data.nombre : null, // Name used for the organization
77
+ };
78
+ if (contactos.length > 0) { // A contact detail for the organization
79
+ organizacionFHIR['telecom'] = contactos;
80
+ }
81
+
82
+ if (direcciones) { // An address for the organization
83
+ organizacionFHIR['address'] = direcciones;
84
+ }
85
+ return organizacionFHIR;
86
+ } else {
87
+ return null;
88
+ }
89
+ }
@@ -1,38 +1,62 @@
1
- import * as patient from '../data/patient.json';
2
- import { encode } from './patient';
3
- describe('encode patient from ANDES to FHIR R4', () => {
4
- test('Verify basic data', () => {
5
- expect(encode(patient).resourceType).toBe('Patient');
6
- expect(encode(patient).identifier[0].value).toBe('42910660');
7
- expect(encode(patient).identifier[0].system).toBe('http://www.renaper.gob.ar/dni');
8
- expect(encode(patient).active).toBe(true);
9
- expect(encode(patient).name[0].use).toBe('official');
10
- expect(encode(patient).name[0].resourceType).toBe('HumanName');
11
- expect(encode(patient).name[0].family).toContain('PERINGA');
12
- expect(encode(patient).name[0].family).toContain('PONCE');
13
- expect(encode(patient).name[0].given).toContain('AGUSTIN');
14
- expect(encode(patient).name[0].text).toBe('HUGO AGUSTIN PERINGA PONCE');
15
- expect(encode(patient).gender).toBe('male');
16
- expect(encode(patient).birthDate).toBe('1979-11-14');
17
- });
18
- test('Verify patient with contact information', () => {
19
- // Phone;
20
- expect(encode(patient).telecom[0].resourceType).toBe('ContactPoint');
21
- expect(encode(patient).telecom[0].value).toBe('4462221');
22
- expect(encode(patient).telecom[0].system).toBe('phone');
23
- // Address;
24
- expect(encode(patient).address[0].resourceType).toBe('Address');
25
- expect(encode(patient).address[0].postalCode).toBe('8300');
26
- expect(encode(patient).address[0].line).toContain('Enrique Santos Discepolo 1856');
27
- expect(encode(patient).address[0].city).toBe('NEUQUEN');
28
- expect(encode(patient).address[0].state).toBe('Neuquén');
29
- expect(encode(patient).address[0].country).toBe('Argentina');
30
- });
31
- test('Verify patient with relationships', () => {
32
- expect(encode(patient).contact[0].relationship[0].text).toBe('hijo/a');
33
- expect(encode(patient).contact[0].name.resourceType).toBe('HumanName');
34
- expect(encode(patient).contact[0].name.family).toContain('PERINGA');
35
- expect(encode(patient).contact[0].name.given).toContain('JOSEFINA');
36
- });
37
- });
38
-
1
+ import * as patient from '../data/patient.json';
2
+ import { decode, encode } from './patient';
3
+ import { createPatient } from '../helpers/patientFactory';
4
+
5
+ describe('encode patient from ANDES to FHIR R4', () => {
6
+ test('Verify basic data', () => {
7
+ expect(encode(patient).resourceType).toBe('Patient');
8
+ expect(encode(patient).identifier[0].value).toBe('42910660');
9
+ expect(encode(patient).identifier[0].system).toBe('http://www.renaper.gob.ar/dni');
10
+ expect(encode(patient).active).toBe(true);
11
+ expect(encode(patient).name[0].use).toBe('official');
12
+ expect(encode(patient).name[0].resourceType).toBe('HumanName');
13
+ expect(encode(patient).name[0].family).toContain('PERINGA');
14
+ expect(encode(patient).name[0].family).toContain('PONCE');
15
+ expect(encode(patient).name[0].given).toContain('AGUSTIN');
16
+ expect(encode(patient).name[0].text).toBe('HUGO AGUSTIN PERINGA PONCE');
17
+ expect(encode(patient).gender).toBe('male');
18
+ expect(encode(patient).birthDate).toBe('1979-11-14');
19
+ });
20
+ test('Verify patient with contact information', () => {
21
+ // Phone;
22
+ expect(encode(patient).telecom[0].resourceType).toBe('ContactPoint');
23
+ expect(encode(patient).telecom[0].value).toBe('4462221');
24
+ expect(encode(patient).telecom[0].system).toBe('phone');
25
+ // Address;
26
+ expect(encode(patient).address[0].resourceType).toBe('Address');
27
+ expect(encode(patient).address[0].postalCode).toBe('8300');
28
+ expect(encode(patient).address[0].line).toContain('Enrique Santos Discepolo 1856');
29
+ expect(encode(patient).address[0].city).toBe('NEUQUEN');
30
+ expect(encode(patient).address[0].state).toBe('Neuquén');
31
+ expect(encode(patient).address[0].country).toBe('Argentina');
32
+ });
33
+ test('Verify patient with relationships', () => {
34
+ expect(encode(patient).contact[0].relationship[0].text).toBe('hijo/a');
35
+ expect(encode(patient).contact[0].name.resourceType).toBe('HumanName');
36
+ expect(encode(patient).contact[0].name.family).toContain('PERINGA');
37
+ expect(encode(patient).contact[0].name.given).toContain('JOSEFINA');
38
+ });
39
+
40
+ test('Maneja paciente con estado validado', () => {
41
+ const paciente = createPatient({ estado: 'validado' });
42
+ const fhir = encode(paciente);
43
+ expect(fhir.extension?.some(t => t.valueCode === 'validado')).toBeTruthy();
44
+ });
45
+
46
+ test('Maneja paciente con estado temporal', () => {
47
+ const paciente = createPatient({ estado: 'temporal' });
48
+ const fhir = encode(paciente);
49
+ expect(fhir.extension?.some(t => t.valueCode === 'temporal')).toBeTruthy();
50
+ });
51
+
52
+ test('Maneja paciente con estado nulo', () => {
53
+ const paciente = createPatient({ estado: null });
54
+ const fhir = encode(paciente);
55
+ expect(fhir.extension?.some(t => t.valueCode === 'temporal')).toBeTruthy();
56
+ });
57
+
58
+ it('Verifica organización que crea paciente', () => {
59
+ const fhir = encode(patient);
60
+ expect(fhir.managingOrganization.display).toContain('LABORATORIO');
61
+ });
62
+ });