Este es un recorrido de producto, no el caso de ninguna clínica real: describe cómo se mueve -y dónde se desconecta de la norma- el alta de un usuario dentro de FaunaWare hasta que emite una receta de controlados. La pregunta que resuelve es concreta: ¿en qué paso exacto el sistema deja de preguntar si esa cuenta tiene una cédula profesional detrás, según lo visto en en FaunaWare, cualquier usuario con rol "doctor" puede recetar morfina sin acreditar cédula profesional?
Esquema del recorrido · ilustración, no es una pantalla del sistema
- 1. El clinic-admin da de alta a un usuario con rol "doctor"El alta sólo pide correo, nombre y el rol; no exige vincular una ficha de médico ni una cédula.
- 2. Ese usuario abre el módulo de recetas
@RequireRoles('doctor')es la única barrera del endpoint de emisión. - 3. Elige un medicamento controlado, grupo I (morfina)El sistema pide un folio especial -texto libre- porque el grupo lo exige.
- 4. El servidor busca al emisor en la tabla de médicos, por correo
medicoDelEmisor()sólo leeidyfull_name; nuncaprofessional_license. - 5. No encuentra ficha de médico, o la encuentra sin cédulaDevuelve
{ id: null, fullName: null }sin lanzar ningún error. - 6. La receta se emite igual, con folio de texto libre
issue()insertadoctor_id: nully usaauth.usernamecomo nombre; HTTP 201.
1-3. El rol abre la puerta; el folio sólo valida formato
Cuando el clinic-admin da de alta a un nuevo usuario con rol "doctor", el formulario de POST /identity/users pide correo, nombre y contraseña -no pide, ni permite adjuntar, una cédula profesional-. Con ese rol, el usuario ya puede abrir PrescriptionsController.issue() (services/clinical/src/prescriptions/prescriptions.controller.ts:39-47), cuya única barrera es @RequireRoles('doctor') y el permiso encounters:write. Si el medicamento es controlado de grupo I, II o III, el sistema exige un specialFolio (prescriptions.service.ts:75-84) -pero acepta cualquier texto no vacío, sin verificarlo contra un recetario real emitido por la autoridad-.
4-6. Nadie preguntó por la cédula, y la receta sale de todos modos
medicoDelEmisor() (services/clinical/src/common/medico-del-emisor.ts:55-85) busca en la tabla doctors por el correo de quien hace la petición, pero sólo proyecta id y full_name -la columna professional_license ni siquiera está en el SELECT-. Si no hay coincidencia, o si la hay pero corresponde a una ficha sin cédula capturada, la función devuelve el resultado igual, sin distinguir un caso del otro y sin lanzar ningún error. PrescriptionsService.issue() toma ese resultado tal cual: si id es null, inserta la receta con doctor_id: null y usa auth.username como nombre de respaldo (líneas 94-95, 105). La receta se persiste, y el endpoint responde 201.
| Parada | ¿Se comprueba la cédula profesional del emisor? |
|---|---|
| 1. Alta del usuario con rol "doctor" | No -el formulario no pide cédula ni ficha de médico |
2. Endpoint de emisión (@RequireRoles('doctor')) | No -sólo valida el rol de acceso |
3. Folio especial para controlados (specialFolio) | No -valida que el texto no esté vacío, no que sea un folio real |
4. Búsqueda del emisor (medicoDelEmisor()) | No -sólo proyecta id y full_name |
5. Persistencia de la receta (issue()) | No -inserta igual con doctor_id: null |
Puedes estimar la exposición de este hallazgo, con tus propios números, en la calculadora de exposición por receta de estupefacientes sin acreditación profesional.
Preguntas frecuentes
¿Por qué FaunaWare no exige cédula al dar de alta el rol "doctor"?
El rol es un mecanismo de control de acceso al sistema (qué pantallas y endpoints puede usar una cuenta), no un mecanismo de acreditación profesional. El hallazgo es que ese mismo rol es el único requisito para recetar estupefacientes, donde la ley sí exige acreditación.
¿Agregar la validación del folio contra un catálogo real resuelve todo el hallazgo?
Resuelve el formato de la receta especial, pero no la identidad: si medicoDelEmisor() sigue sin comprobar professional_license, una cuenta sin ficha de médico podría seguir recetando aunque el folio fuera perfectamente válido.
¿FaunaWare corrige esto automáticamente?
No, hoy no. Es un hallazgo verificado en el código y en las pruebas actuales, no una función ya resuelta.
Ve el recorrido completo en tu propia demo
Te mostramos en vivo el alta del usuario y la emisión de la receta.
Agenda una demo gratis