@phenyxhealth/sdk 1.0.15 → 1.1.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.
- package/.claude/phenyx-sdk.md +477 -0
- package/README.md +13 -6
- package/package.json +2 -1
- package/src/PhenyxApi.js +0 -12
- package/types/index.d.ts +0 -11
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
# PhenyxHealth SDK - Asistente de desarrollo
|
|
2
|
+
|
|
3
|
+
Estoy trabajando en un proyecto JavaScript/TypeScript que usa `@phenyxhealth/sdk`, el SDK oficial de PhenyxHealth para gestionar sistemas de radioterapia.
|
|
4
|
+
|
|
5
|
+
Usa la siguiente referencia completa de la API para ayudarme a escribir codigo correcto, eficiente y siguiendo los patrones del SDK.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Instalacion
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @phenyxhealth/sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Imports disponibles
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
import {
|
|
19
|
+
PhenyxSDK, // Clase principal
|
|
20
|
+
checkGlobals, // Validar configuracion global
|
|
21
|
+
beSureGlobalExists, // Asegurar elementos globales
|
|
22
|
+
beSureDoctorExists, // Validar/crear doctores
|
|
23
|
+
beSureLinacsExists, // Validar/crear LINACs
|
|
24
|
+
today, // Fecha actual YYYY-MM-DD
|
|
25
|
+
formatDate, // Date -> YYYY-MM-DD
|
|
26
|
+
formatDateString, // DD/MM/YYYY -> YYYY-MM-DD
|
|
27
|
+
} from '@phenyxhealth/sdk';
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## PhenyxSDK - Clase principal
|
|
33
|
+
|
|
34
|
+
### Propiedades de instancia
|
|
35
|
+
|
|
36
|
+
| Propiedad | Tipo | Descripcion |
|
|
37
|
+
|-----------|------|-------------|
|
|
38
|
+
| `apiToken` | `string \| null` | Token JWT de autenticacion |
|
|
39
|
+
| `apiHost` | `string \| null` | URL base de la API |
|
|
40
|
+
| `user` | `UserInfo \| null` | Info del usuario autenticado |
|
|
41
|
+
| `config` | `Record<string, any>` | Configuracion del cliente |
|
|
42
|
+
| `globalInfo` | `GlobalInfo[] \| null` | Info global del sistema |
|
|
43
|
+
| `activeTables` | `any[] \| null` | Tablas activas |
|
|
44
|
+
| `doctors` | `HumanResourceData[]` | Lista de doctores/fisicos medicos |
|
|
45
|
+
| `defaultDuration` | `Record<string, string>` | Duraciones por defecto de sesiones |
|
|
46
|
+
| `defaultCompatibleLinacs` | `Array<{id, name}>` | LINACs compatibles por defecto |
|
|
47
|
+
| `oars` | `any[]` | Lista de Organs At Risk |
|
|
48
|
+
|
|
49
|
+
### Metodos estaticos
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Generar UUID v4
|
|
53
|
+
PhenyxSDK.newId(): string
|
|
54
|
+
|
|
55
|
+
// Generar color RGB contrastante aleatorio ("R, G, B")
|
|
56
|
+
PhenyxSDK.getContrastingColor(): string
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Autenticacion
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// Login - inicializa la instancia con token, globalInfo, doctors, etc.
|
|
63
|
+
await api.login({ apiHost: string, user: string, password: string }): Promise<void>
|
|
64
|
+
|
|
65
|
+
// Obtener token JWT actual
|
|
66
|
+
api.getToken(): string | null
|
|
67
|
+
|
|
68
|
+
// Habilitar/deshabilitar logs HTTP
|
|
69
|
+
api.showLogs(showLogs: boolean): void
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Informacion global
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// Recuperar info global del servidor
|
|
76
|
+
await api.retrieveGlobalInfo(): Promise<GlobalInfo[]>
|
|
77
|
+
|
|
78
|
+
// Recuperar tablas activas
|
|
79
|
+
await api.retrieveActiveTables(): Promise<any[]>
|
|
80
|
+
|
|
81
|
+
// Recuperar configuracion por defecto
|
|
82
|
+
await api.retrieveDefaults(): Promise<Object>
|
|
83
|
+
|
|
84
|
+
// Recuperar lista de OARs
|
|
85
|
+
await api.retrieveOars(): Promise<any[]>
|
|
86
|
+
|
|
87
|
+
// Obtener info global por tipo
|
|
88
|
+
api.getGlobalInfo(globalType: GlobalType): GlobalInfo | undefined
|
|
89
|
+
|
|
90
|
+
// Obtener elemento especifico de info global
|
|
91
|
+
api.getGlobalInfoElement(globalType: GlobalType, elementName: string): GlobalInfoElement | undefined
|
|
92
|
+
|
|
93
|
+
// Obtener ID de elemento global por nombre
|
|
94
|
+
api.getGlobalInfoElementId(globalType: GlobalType, elementName: string): string | null
|
|
95
|
+
|
|
96
|
+
// Actualizar info global
|
|
97
|
+
// IMPORTANTE: El servidor reasigna los IDs de los elementos nuevos al guardar.
|
|
98
|
+
// Despues de llamar a updateGlobalInfo, debes volver a llamar a getGlobalInfo()
|
|
99
|
+
// para obtener los IDs reales asignados por el servidor.
|
|
100
|
+
await api.updateGlobalInfo(globalTypeId: string, data: any): Promise<void>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Pacientes
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// Obtener todos los pacientes
|
|
107
|
+
await api.getPatients(): Promise<PatientData[]>
|
|
108
|
+
|
|
109
|
+
// Obtener datos clinicos de un paciente
|
|
110
|
+
await api.getPatient(id: string): Promise<PatientData>
|
|
111
|
+
|
|
112
|
+
// Crear paciente - retorna el ID del paciente creado
|
|
113
|
+
await api.createPatient(data: CreatePatientData): Promise<string>
|
|
114
|
+
|
|
115
|
+
// Eliminar paciente
|
|
116
|
+
await api.deletePatient(id: string): Promise<void>
|
|
117
|
+
|
|
118
|
+
// Crear cambio de estado
|
|
119
|
+
await api.createPatientStateChanges({
|
|
120
|
+
formDataId: string, // ID del caso
|
|
121
|
+
date?: string, // Fecha YYYY-MM-DD
|
|
122
|
+
humanResourceId?: string, // ID del doctor responsable
|
|
123
|
+
nextStateCode: string // Codigo del siguiente estado
|
|
124
|
+
}): Promise<void>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Recursos humanos
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Obtener todos los recursos humanos
|
|
131
|
+
await api.getHumanResources(): Promise<HumanResourceData[]>
|
|
132
|
+
|
|
133
|
+
// Crear recurso humano
|
|
134
|
+
await api.createHumanResource({ name, typeId, agenda }): Promise<void>
|
|
135
|
+
|
|
136
|
+
// Buscar doctor por nombre
|
|
137
|
+
api.getDoctorIdByName(name: string): string | null
|
|
138
|
+
api.getDoctorTypeIdByName(name: string): string | null
|
|
139
|
+
api.getDoctorTypeNameByName(name: string): string | null
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Equipos/Recursos
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Obtener tipos de recursos
|
|
146
|
+
await api.getResourcesTypes(): Promise<any[]>
|
|
147
|
+
|
|
148
|
+
// Obtener todos los recursos (LINACs, etc)
|
|
149
|
+
await api.getResources(): Promise<ResourceData[]>
|
|
150
|
+
|
|
151
|
+
// Crear recurso
|
|
152
|
+
await api.createResource({ name, author?, typeId, agenda }): Promise<void>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Lookups de elementos
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
api.getSendingDepartmentIdByName(name: string): string // throws si no existe
|
|
159
|
+
api.getCei9IdByName(name: string): string // throws si no existe
|
|
160
|
+
api.getCie10IdByName(name: string): string // throws si no existe
|
|
161
|
+
api.getCie10CodeExists(name: string): boolean
|
|
162
|
+
api.getElementIdByName(type: string, name: string): string | null
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### QA y estados
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
api.getQaStatus(section: any): string | null
|
|
169
|
+
api.getRewiewedStatus(status: string): any[]
|
|
170
|
+
api.getSortedQa(qa: any): any[]
|
|
171
|
+
await api.updateSectionQaStatus(qa: any, formDataId: string): Promise<void>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Constantes del SDK
|
|
177
|
+
|
|
178
|
+
### `api.globalTypes` - 20 tipos de configuracion global
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
api.globalTypes.humanResources
|
|
182
|
+
api.globalTypes.sendingDepartment
|
|
183
|
+
api.globalTypes.cie10 // Codigos CIE-10
|
|
184
|
+
api.globalTypes.treatmentClass
|
|
185
|
+
api.globalTypes.treatmentSubClass
|
|
186
|
+
api.globalTypes.treatmentTechnique
|
|
187
|
+
api.globalTypes.treatmentType
|
|
188
|
+
api.globalTypes.treatmentGoal
|
|
189
|
+
api.globalTypes.treatmentParticles
|
|
190
|
+
api.globalTypes.noTreatmentReasons
|
|
191
|
+
api.globalTypes.ctSimProtocols
|
|
192
|
+
api.globalTypes.linacsAllocationCriteria
|
|
193
|
+
api.globalTypes.sessionDurationCriteria
|
|
194
|
+
api.globalTypes.contouringTools
|
|
195
|
+
api.globalTypes.fractionationTypes
|
|
196
|
+
api.globalTypes.dosimetryCalculationMethods
|
|
197
|
+
api.globalTypes.dosimetrySecondaryCalculationMethods
|
|
198
|
+
api.globalTypes.tps
|
|
199
|
+
api.globalTypes.treatmentVerificationProtocols
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### `api.allStatus` - 16 estados de workflow
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
api.allStatus.NOTSTARTED
|
|
206
|
+
api.allStatus.COMPLETED
|
|
207
|
+
api.allStatus.INPROGRESS
|
|
208
|
+
api.allStatus.ONREQUEST
|
|
209
|
+
api.allStatus.READYTOSTART
|
|
210
|
+
api.allStatus.DONE
|
|
211
|
+
api.allStatus.REVIEWED
|
|
212
|
+
api.allStatus.VALIDATED
|
|
213
|
+
api.allStatus.PEERREVIEWING
|
|
214
|
+
api.allStatus.PEERREVIEWED
|
|
215
|
+
api.allStatus.DONEMAIN
|
|
216
|
+
api.allStatus.DONESECONDCALCULATION
|
|
217
|
+
api.allStatus.STARTPROPOSED
|
|
218
|
+
api.allStatus.STARTCONFIRMED
|
|
219
|
+
api.allStatus.CANCELED
|
|
220
|
+
api.allStatus.CANCELLED
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Funciones de validacion (standalone)
|
|
226
|
+
|
|
227
|
+
### `beSureDoctorExists(api, doctors)`
|
|
228
|
+
Valida que los doctores existan en el sistema. Si no existen, los crea automaticamente.
|
|
229
|
+
|
|
230
|
+
```javascript
|
|
231
|
+
const doctors = await beSureDoctorExists(api, [
|
|
232
|
+
{ name: 'Dr. Garcia', hrGroup: 'RadOnc' }, // Radiation Oncologist
|
|
233
|
+
{ name: 'Dr. Lopez', hrGroup: 'MedPhys' }, // Medical Physicist
|
|
234
|
+
]);
|
|
235
|
+
// Retorna: HumanResourceData[]
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### `beSureLinacsExists(api, linacs)`
|
|
239
|
+
Valida que los LINACs existan. Si no, los crea.
|
|
240
|
+
|
|
241
|
+
```javascript
|
|
242
|
+
const linacs = await beSureLinacsExists(api, ['LINAC-01', 'LINAC-02']);
|
|
243
|
+
// Retorna: ResourceData[]
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### `checkGlobals(api, globalType, extraValues?)`
|
|
247
|
+
Valida que los valores globales existan. Si no, los crea.
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
await checkGlobals(api, api.globalTypes.treatmentType, ['IMRT', 'VMAT', 'SRS']);
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### `beSureGlobalExists(api, currentList, toBeList)`
|
|
254
|
+
Nivel mas bajo: asegura que elementos especificos existan en una lista global.
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
const treatmentTypes = api.getGlobalInfo(api.globalTypes.treatmentType);
|
|
258
|
+
await beSureGlobalExists(api, treatmentTypes, ['IMRT', 'VMAT']);
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Utilidades de fecha
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
today() // "2026-02-16" (fecha actual)
|
|
267
|
+
formatDate(new Date()) // "2026-02-16" (Date -> string)
|
|
268
|
+
formatDateString('16/02/2026') // "2026-02-16" (DD/MM/YYYY -> YYYY-MM-DD)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Interfaces TypeScript principales
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
interface LoginCredentials {
|
|
277
|
+
apiHost: string;
|
|
278
|
+
user: string;
|
|
279
|
+
password: string;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
interface PatientData {
|
|
283
|
+
id: string;
|
|
284
|
+
name: string;
|
|
285
|
+
birthDate: string;
|
|
286
|
+
sendingDepartmentId?: string;
|
|
287
|
+
cie10Id?: string;
|
|
288
|
+
[key: string]: any;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
interface CreatePatientData {
|
|
292
|
+
name: string;
|
|
293
|
+
birthDate: string;
|
|
294
|
+
sendingDepartmentId?: string;
|
|
295
|
+
cie10Id?: string;
|
|
296
|
+
[key: string]: any;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
interface HumanResourceData {
|
|
300
|
+
id: string;
|
|
301
|
+
name: string;
|
|
302
|
+
typeId: string;
|
|
303
|
+
typeName: string;
|
|
304
|
+
agenda: AgendaItem[];
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
interface DoctorValidation {
|
|
308
|
+
name: string;
|
|
309
|
+
hrGroup: 'RadOnc' | 'MedPhys';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
interface ResourceData {
|
|
313
|
+
id: string;
|
|
314
|
+
name: string;
|
|
315
|
+
typeId: string;
|
|
316
|
+
author: string;
|
|
317
|
+
agenda: AgendaItem[];
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
interface GlobalInfo {
|
|
321
|
+
id: string;
|
|
322
|
+
name: string;
|
|
323
|
+
typeName: string;
|
|
324
|
+
elements: GlobalInfoElement[];
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
interface GlobalInfoElement {
|
|
328
|
+
id: string;
|
|
329
|
+
name: string;
|
|
330
|
+
color: string;
|
|
331
|
+
createdAt: string;
|
|
332
|
+
updatedAt: string;
|
|
333
|
+
isDeleted: boolean;
|
|
334
|
+
modality: string;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
interface GlobalType {
|
|
338
|
+
type: string;
|
|
339
|
+
name: string;
|
|
340
|
+
values?: Record<string, string>;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
interface StateChangeParams {
|
|
344
|
+
formDataId: string;
|
|
345
|
+
date?: string;
|
|
346
|
+
humanResourceId?: string | null;
|
|
347
|
+
nextStateCode: string;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
interface AgendaItem {
|
|
351
|
+
id: string;
|
|
352
|
+
date: string;
|
|
353
|
+
startTime: string;
|
|
354
|
+
endTime: string;
|
|
355
|
+
description?: string;
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Patrones comunes
|
|
362
|
+
|
|
363
|
+
### Setup basico
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
const api = new PhenyxSDK();
|
|
367
|
+
await api.login({ apiHost: HOST, user: USER, password: PASS });
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Crear paciente completo
|
|
371
|
+
|
|
372
|
+
```javascript
|
|
373
|
+
const patientId = await api.createPatient({
|
|
374
|
+
name: 'Juan Perez',
|
|
375
|
+
birthDate: '1975-03-15',
|
|
376
|
+
sendingDepartmentId: api.getSendingDepartmentIdByName('Oncologia'),
|
|
377
|
+
cie10Id: api.getCie10IdByName('C78.9'),
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
await api.createPatientStateChanges({
|
|
381
|
+
formDataId: patientId,
|
|
382
|
+
date: today(),
|
|
383
|
+
humanResourceId: api.getDoctorIdByName('Dr. Garcia'),
|
|
384
|
+
nextStateCode: api.allStatus.INPROGRESS,
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Configurar clinica
|
|
389
|
+
|
|
390
|
+
```javascript
|
|
391
|
+
await beSureDoctorExists(api, [
|
|
392
|
+
{ name: 'Dr. Garcia', hrGroup: 'RadOnc' },
|
|
393
|
+
{ name: 'Dr. Lopez', hrGroup: 'MedPhys' },
|
|
394
|
+
]);
|
|
395
|
+
|
|
396
|
+
await beSureLinacsExists(api, ['LINAC-01', 'LINAC-02']);
|
|
397
|
+
|
|
398
|
+
await checkGlobals(api, api.globalTypes.treatmentType, ['IMRT', 'VMAT', 'SRS']);
|
|
399
|
+
await checkGlobals(api, api.globalTypes.treatmentGoal, ['Curative', 'Palliative']);
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Crear elementos globales con dependencias entre si
|
|
403
|
+
|
|
404
|
+
Cuando creas elementos en un globalInfo, debes enviar un `id` (con `PhenyxSDK.newId()`), pero el servidor **ignora ese id y asigna uno nuevo**. Por lo tanto, despues de `updateGlobalInfo()` debes volver a obtener los datos con `getGlobalInfo()` para tener los IDs reales. Esto es critico cuando necesitas referenciar los elementos recien creados (ej: crear subclases que apuntan a clases).
|
|
405
|
+
|
|
406
|
+
```javascript
|
|
407
|
+
// 1) Obtener el global y añadir elementos
|
|
408
|
+
const treatmentClass = api.getGlobalInfo(api.globalTypes.treatmentClass);
|
|
409
|
+
|
|
410
|
+
treatmentClass.elements.push({
|
|
411
|
+
id: PhenyxSDK.newId(), // obligatorio enviarlo, pero el servidor lo va a reemplazar
|
|
412
|
+
name: 'Radioterapia Externa',
|
|
413
|
+
color: PhenyxSDK.getContrastingColor(),
|
|
414
|
+
createdAt: new Date().toISOString(),
|
|
415
|
+
updatedAt: new Date().toISOString(),
|
|
416
|
+
isDeleted: false,
|
|
417
|
+
modality: '',
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// 2) Guardar
|
|
421
|
+
await api.updateGlobalInfo(treatmentClass.id, treatmentClass);
|
|
422
|
+
|
|
423
|
+
// 3) OBLIGATORIO: Recargar para obtener los IDs reales del servidor
|
|
424
|
+
const createdClasses = api.getGlobalInfo(api.globalTypes.treatmentClass);
|
|
425
|
+
|
|
426
|
+
// 4) Ahora si puedes usar los IDs reales para crear elementos que los referencian
|
|
427
|
+
const parentClass = createdClasses.elements.find(e => e.name === 'Radioterapia Externa');
|
|
428
|
+
const treatmentSubClass = api.getGlobalInfo(api.globalTypes.treatmentSubClass);
|
|
429
|
+
|
|
430
|
+
treatmentSubClass.elements.push({
|
|
431
|
+
id: PhenyxSDK.newId(),
|
|
432
|
+
name: 'IMRT',
|
|
433
|
+
treatmentClass: parentClass.id, // ID real del servidor
|
|
434
|
+
color: PhenyxSDK.getContrastingColor(),
|
|
435
|
+
createdAt: new Date().toISOString(),
|
|
436
|
+
updatedAt: new Date().toISOString(),
|
|
437
|
+
isDeleted: false,
|
|
438
|
+
modality: '',
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
await api.updateGlobalInfo(treatmentSubClass.id, treatmentSubClass);
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Flujo QA
|
|
445
|
+
|
|
446
|
+
```javascript
|
|
447
|
+
const doctorId = api.getDoctorIdByName('Dr. Lopez');
|
|
448
|
+
|
|
449
|
+
// Listo para QA -> Peer reviewing -> Peer reviewed -> Validado
|
|
450
|
+
for (const status of [
|
|
451
|
+
api.allStatus.READYTOSTART,
|
|
452
|
+
api.allStatus.PEERREVIEWING,
|
|
453
|
+
api.allStatus.PEERREVIEWED,
|
|
454
|
+
api.allStatus.VALIDATED,
|
|
455
|
+
]) {
|
|
456
|
+
await api.createPatientStateChanges({
|
|
457
|
+
formDataId: patientId,
|
|
458
|
+
date: today(),
|
|
459
|
+
humanResourceId: doctorId,
|
|
460
|
+
nextStateCode: status,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## Notas importantes
|
|
468
|
+
|
|
469
|
+
- `PhenyxSDK` es un alias de `PhenyxApi` (se exporta como default y como named export `PhenyxSDK`)
|
|
470
|
+
- `login()` inicializa automaticamente: `globalInfo`, `activeTables`, `doctors`, `defaultDuration`, `defaultCompatibleLinacs`, y `oars`
|
|
471
|
+
- Los metodos `get*ByName` buscan en los datos ya cargados en memoria (no hacen llamadas HTTP)
|
|
472
|
+
- Los metodos `getSendingDepartmentIdByName`, `getCei9IdByName`, `getCie10IdByName` lanzan Error si no encuentran el elemento
|
|
473
|
+
- `getContrastingColor()` y `newId()` son metodos estaticos - se usan sin instancia: `PhenyxSDK.newId()`
|
|
474
|
+
- **IDs en GlobalInfo**: Al hacer `push` de un elemento nuevo a `globalInfo.elements`, debes enviar un `id` (el servidor da error si no lo envias), pero el servidor lo ignora y asigna su propio ID. Siempre haz `getGlobalInfo()` despues de `updateGlobalInfo()` si necesitas referenciar los elementos creados
|
|
475
|
+
- Las funciones de validacion (`beSureDoctorExists`, `beSureLinacsExists`, `checkGlobals`) crean automaticamente los recursos que no existan
|
|
476
|
+
- El SDK usa ESM (`"type": "module"` en package.json)
|
|
477
|
+
- Compatible con Node.js >= 16
|
package/README.md
CHANGED
|
@@ -244,9 +244,6 @@ const color = getContrastingColor(); // '244, 67, 54' (formato RGB)
|
|
|
244
244
|
// Obtener ID de departamento emisor
|
|
245
245
|
const deptId = api.getSendingDepartmentIdByName("Oncología");
|
|
246
246
|
|
|
247
|
-
// Obtener ID de código CEI9
|
|
248
|
-
const cei9Id = api.getCei9IdByName("C78.9");
|
|
249
|
-
|
|
250
247
|
// Obtener ID de código CIE10
|
|
251
248
|
const cie10Id = api.getCie10IdByName("C78.9");
|
|
252
249
|
```
|
|
@@ -354,7 +351,6 @@ const processPatient = async () => {
|
|
|
354
351
|
name: "Juan Pérez",
|
|
355
352
|
birthDate: "1980-01-15",
|
|
356
353
|
sendingDepartmentId: api.getSendingDepartmentIdByName("Oncología"),
|
|
357
|
-
cei9Id: api.getCei9IdByName("C78.9"),
|
|
358
354
|
cie10Id: api.getCie10IdByName("C78.9"),
|
|
359
355
|
});
|
|
360
356
|
|
|
@@ -388,10 +384,9 @@ try {
|
|
|
388
384
|
}
|
|
389
385
|
|
|
390
386
|
try {
|
|
391
|
-
const cei9Id = api.getCei9IdByName("C00.0");
|
|
392
387
|
const cie10Id = api.getCie10IdByName("C00.0");
|
|
393
388
|
} catch (error) {
|
|
394
|
-
console.error("Código
|
|
389
|
+
console.error("Código CIE10 no encontrado:", error.message);
|
|
395
390
|
}
|
|
396
391
|
```
|
|
397
392
|
|
|
@@ -408,6 +403,18 @@ const patient: PatientData = await api.getPatient("id");
|
|
|
408
403
|
const doctors: HumanResourceData[] = await api.getHumanResources();
|
|
409
404
|
```
|
|
410
405
|
|
|
406
|
+
## Uso con Claude Code
|
|
407
|
+
|
|
408
|
+
Si usas [Claude Code](https://claude.com/claude-code) para desarrollar, este SDK incluye un archivo de referencia completa de la API que puedes cargar automaticamente en tu proyecto.
|
|
409
|
+
|
|
410
|
+
Agrega la siguiente linea en el `CLAUDE.md` de tu proyecto:
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
@node_modules/@phenyxhealth/sdk/.claude/phenyx-sdk.md
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Esto le dara a Claude Code el contexto completo de la API del SDK: todos los metodos, interfaces TypeScript, constantes, patrones de uso y notas importantes para que te asista correctamente al escribir codigo con `@phenyxhealth/sdk`.
|
|
417
|
+
|
|
411
418
|
## Contribución
|
|
412
419
|
|
|
413
420
|
Las contribuciones son bienvenidas. Please:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phenyxhealth/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "SDK oficial para PhenyxHealth - Sistema integral de gestión de radioterapia. Incluye gestión de pacientes, recursos humanos, equipos médicos y configuración global.",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"src/",
|
|
13
13
|
"types/",
|
|
14
|
+
".claude/",
|
|
14
15
|
"README.md"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
package/src/PhenyxApi.js
CHANGED
|
@@ -62,10 +62,6 @@ class PhenyxApi {
|
|
|
62
62
|
type: 'Global',
|
|
63
63
|
name: 'Sending Department',
|
|
64
64
|
},
|
|
65
|
-
cei9: {
|
|
66
|
-
type: 'Global',
|
|
67
|
-
name: 'CEI9',
|
|
68
|
-
},
|
|
69
65
|
cie10: {
|
|
70
66
|
type: 'Global',
|
|
71
67
|
name: 'CIE10',
|
|
@@ -428,14 +424,6 @@ class PhenyxApi {
|
|
|
428
424
|
return sendingDepartment.id;
|
|
429
425
|
}
|
|
430
426
|
|
|
431
|
-
getCei9IdByName = (name) => {
|
|
432
|
-
const cei9 = this.getGlobalInfoElement(this.globalTypes.cei9, name);
|
|
433
|
-
if (!cei9) {
|
|
434
|
-
throw new Error(`CEI9 ${name} not found`);
|
|
435
|
-
}
|
|
436
|
-
return cei9.id;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
427
|
/**
|
|
440
428
|
* Obtiene el ID de un CIE10 por nombre
|
|
441
429
|
* @param {string} name - Nombre del CIE10
|
package/types/index.d.ts
CHANGED
|
@@ -36,7 +36,6 @@ declare module "@phenyxhealth/sdk" {
|
|
|
36
36
|
name: string;
|
|
37
37
|
birthDate: string;
|
|
38
38
|
sendingDepartmentId?: string;
|
|
39
|
-
cei9Id?: string;
|
|
40
39
|
cie10Id?: string;
|
|
41
40
|
[key: string]: any;
|
|
42
41
|
}
|
|
@@ -127,7 +126,6 @@ declare module "@phenyxhealth/sdk" {
|
|
|
127
126
|
name: string;
|
|
128
127
|
birthDate: string;
|
|
129
128
|
sendingDepartmentId?: string;
|
|
130
|
-
cei9Id?: string;
|
|
131
129
|
cie10Id?: string;
|
|
132
130
|
[key: string]: any;
|
|
133
131
|
}
|
|
@@ -220,7 +218,6 @@ declare module "@phenyxhealth/sdk" {
|
|
|
220
218
|
globalTypes: {
|
|
221
219
|
humanResources: GlobalType;
|
|
222
220
|
sendingDepartment: GlobalType;
|
|
223
|
-
cei9: GlobalType;
|
|
224
221
|
cie10: GlobalType;
|
|
225
222
|
treatmentClass: GlobalType;
|
|
226
223
|
treatmentSubClass: GlobalType;
|
|
@@ -416,14 +413,6 @@ declare module "@phenyxhealth/sdk" {
|
|
|
416
413
|
*/
|
|
417
414
|
getCie10IdByName(name: string): string;
|
|
418
415
|
|
|
419
|
-
/**
|
|
420
|
-
* Obtiene el ID de un CIE10 por nombre
|
|
421
|
-
* @param name Nombre del CIE10
|
|
422
|
-
* @returns ID del CIE10
|
|
423
|
-
* @throws Error si no se encuentra el CIE10
|
|
424
|
-
*/
|
|
425
|
-
getCie10IdByName(name: string): string;
|
|
426
|
-
|
|
427
416
|
/**
|
|
428
417
|
* Obtiene el estado de peer review formateado
|
|
429
418
|
* @param status Estado a formatear
|