1. Visión general

El módulo vive en src/app/pages/BancoSangre/ y modela el flujo completo de un banco de sangre: desde el registro de un disponente (donador) hasta la liberación de productos sanguíneos y su entrega a un receptor (paciente que requiere transfusión), más la administración de sedes por la Jefatura de Banco de Sangre (JefeBS).

Todas las rutas son hijas planas de PageComponent (page.routes.ts, líneas 595-653, 801, 828-829, 875). El identificador :id que viaja en casi todas las rutas es el _id del registro de banco de sangre del paciente (referido en el código como idCensur / idbancosangre / idBanco), no el _id del paciente.

Hay 38 componentes repartidos en 7 carpetas por rol:

CarpetaRol / actor# Componentes
rolRecepcionRecepción (registro, disponentes, receptores, almacén)14
rolLaboratorioLaboratorio (estudios disponentes + tipar/cruzar receptores)8
rolJefeBSJefatura Banco de Sangre (sedes)7
rolEnfermeriaEnfermería (signos vitales)2
rolFlebotomiaFlebotomía (extracción)3
rolDoctorDoctor (historia clínica / evolución)3
AlmacenAlmacén (salidas/desechos)1

Servicios backend principales: BancoService (src/app/services/bancodeSangre/banco.service.ts, el más usado por mucho), LaboratorioService, FlebotomiaService, SedesService y PedidosSedesService (estos dos últimos casi no se usan dentro del módulo).

2. Tabla de componentes y rutas

🩸 Flujo del DISPONENTE (donador)

OrdenComponenteRutaQué hace
1BitacoraDisponentesComponentbitacora/disponentesLista de pacientes/disponentes (Recepción), buscador, alta y acceso a ficha
2RegistroDisponentesComponentregistro/disponentesAlta de un nuevo disponente (envuelve app-registrar-disponente)
3VerDisponenteComponentver/disponente/:idFicha del paciente; selecciona servicio "Donaciones" + sede de origen; valida si puede donar
4AutoexclusionComponentautoexclusion/:idCuestionario de 12 preguntas SI/NO; decide DIFERIDO o pasa a Enfermería
5DisponentesBitacoraComponent (Enfermería)disponentes/bitacoraLista de disponentes en etapa Enfermería
6FichaDisponenteComponentficha/disponente/:idCaptura signos vitales; decide DIFERIDO o pasa a Doctor + pide laboratorios
7BitacoraConsultaDisponentesComponent (Doctor)bitacora/consulta/disponentesLista de disponentes en espera de consulta médica
8HistoriaClinicaComponenthistoria/clinica/doctor/:idCuestionario extenso de historia clínica por secciones
9HojaEvolucionDisponenteComponenthoja/evolucion/disponente/:idExploración física + diagnóstico final; decide APTO→Flebotomía o DIFERIDO
10BitacoraFlebotomiaComponentbitacora/flebotomiaLista de disponentes listos para extracción
11DocumentosDonanteFlebotomiaComponentdocumentos/flebotomia/:idCaptura datos de extracción + sube consentimientos firmados; decide pasa a Serología o autoexclusión
12BitacoraLaboratorioComponentbitacora/laboratorios/disponentesLista de disponentes con procesos de laboratorio
13HojaServiciosLabDisponenteComponenthoja/servicios/laboratorio/disponentes/:id"Hub" que muestra estudios pendientes: Grupo y RH/BHC, Serología
14BiometriaLabDisponenteComponent (fuera de BancoSangre)grupo/rh/biometria/hematica/completa/:idCaptura Biometría Hemática Completa + Grupo y RH
15SerologiaLabDisponenteComponentserologia/laboratorio/disponente/:idCaptura resultados serológicos; decide LIBERADO (genera etiquetas QR) o DIFERIDO permanente
16ReaccionesDerivadasComponent ⚠️reacciones/adversasFormulario de reacciones adversas a la donación — incompleto, sin persistencia
17BitacoraSalidasComponent (Almacén)bitacora/salidas/almacenLista de productos del almacén; permite marcar como DESECHADO
BitacoraDiferidosComponentbitacora/diferidosVista de solo lectura de todos los disponentes diferidos
HistoricoDisponenteBSComponenthistorico/disponente/bs/:idHistórico de donaciones de un disponente (desde ver-disponente)
BitacoraAlmacenComponent ⚠️bitacora/almacenPlaceholder — tabla hardcodeada, sin lógica

🏥 Flujo del RECEPTOR (transfusión)

OrdenComponenteRutaQué hace
1ReceptoresComponentreceptoresLista de pedidos/hojas de servicio de receptores
2HojaServicioReceptorComponenthojaservicios/receptor/:id"Hub" del pedido: estado de 4 subprocesos (documentos, tipar/cruzar, histórico, entrega)
3DocumentosReceptorComponentdocumentos/receptorSube/consulta documentos médicos del receptor
4TiparCruzarComponent (rolLaboratorio)tiparcruzaPrueba de compatibilidad ABO/Rh + cruce con disponentes/bolsas (guardado deshabilitado)
5EntregaProductosComponentproductos/receptorCatálogo de hemoderivados → carrito de compra
6OrdenCompraComponentorden/productosCheckout/pago (envuelve app-pagos-censur)
7DocumentosReceptorFirmadosComponentagregar/docuemtos/recpetor/firmadosSube documentos/consentimientos firmados tras el pago
EntregaProductosSanguineosComponententrega/productos/sanguineosGenera PDFs de etiqueta de urgencia + carta responsiva (sin backend)

🏢 Jefatura Banco de Sangre / Sedes

ComponenteRutaEstado
SedesbsComponentlistado/sedes/banco/sangre✅ Funcional — lista sedes
DetalleSedeComponentdetalle/sede/:id⚠️ Parcial — datos de sede OK, tabla de pedidos hardcodeada
AgregarSedeComponentagregar/sede/bs⚠️ Incompleto — form completo pero el guardado al backend está comentado
FISedeComponentficha/identificacion/sede⚠️ Placeholder vacío
BitacoraNoAptosODiferidosComponentbitacora/no-aptos⚠️ Placeholder, tabla estática
HojaServicioReceptorBSComponenthoja/servicio/receptor⚠️ Placeholder, tabla estática
OrdenreceptoresComponentorden/servicio/receptores⚠️ Placeholder, tabla estática
ComponenteRutaEstado
NuevoEstudioLabComponentnuevo/estudios/lab✅ Funcional — alta de tipos de estudio de laboratorio
HistoricoEstudiosDisponenteComponenthistorico/estudios/disponente⚠️ Placeholder estático
BitacoraPedidosComponentbitacora/hoja/de/servicios⚠️ Parcial — datos reales del paciente pero columnas de estatus hardcodeadas
HojaServiciosLabsComponent (hoja-servicios)sin ruta❌ Código muerto — no referenciado en ninguna parte

3. Modelo de datos / entidades clave

Paciente (PacientesService) ├─ disponente: boolean / receptor: boolean → mismo registro puede ser ambos ├─ tipoDeSangre, curp, datos generales, dirección └─ idbancosangre / idCensur → registro "BancoSangre" (1:1 por proceso) ├─ proceso: 'enfermeria' | 'doctor' | 'FLEBOTOMIA' | 'serologia' | 'FINALIZADO' | 'DIFERIDO' ├─ estatus: 'DIFERIDO' | ... ├─ cuestionario (autoexclusión), signosvitales, historiaclinica, │ hojadeevolucion, flebotomia, serologia ├─ diferido[]: { motivo, tiempoDiferir, fecha_final } └─ pedido (si es receptor): { estudios[], productos[], status }

Los PDFs (etiquetas QR "LIBERADO"/"NO LIBERADO", etiqueta de urgencia, declaratoria responsiva) se generan en el cliente con jspdf, no por el backend.

4. Diagrama de flujo — Disponente (donador)

flowchart TD
    A[bitacora/disponentes\nLista de pacientes] -->|AGREGAR| B[registro/disponentes\nAlta disponente]
    A -->|ver paciente| C[ver/disponente/:id\nSelecciona Donaciones + sede]
    C -->|validacionDonacion = NUEVO/DISPONIBLE| D[autoexclusion/:id\n12 preguntas]
    C -->|proceso = FINALIZADO| X1[("❌ NO APTO\n(fin)")]
    C -->|tiene donaciones previas| H[historico/disponente/bs/:id]

    D -->|alguna respuesta = riesgo| DIF1[("🚫 DIFERIDO\n(fin)")]
    D -->|todo OK → proceso=enfermeria| E[disponentes/bitacora\nEnfermería]

    E --> F[ficha/disponente/:id\nSignos vitales]
    F -->|fuera de rango| DIF2[("🚫 DIFERIDO")]
    F -->|OK → proceso=doctor\n+ pide laboratorios| G[bitacora/consulta/disponentes\nDoctor]

    G --> I[historia/clinica/doctor/:id\nHistoria clínica]
    I -->|sección riesgo| DIF3[("🚫 DIFERIDO")]
    I -->|OK| J[hoja/evolucion/disponente/:id\nExploración + diagnóstico]

    J -->|candidato_donacion = NO| DIF4[("🚫 DIFERIDO")]
    J -->|APTO → proceso=FLEBOTOMIA| K[bitacora/flebotomia]

    K --> L[documentos/flebotomia/:id\nDatos extracción + consentimiento]
    L -->|no firma| DIF5[("🚫 Autoexclusión")]
    L -->|firma → proceso=serologia\nimprime NO LIBERADO| M[bitacora/laboratorios/disponentes]

    M --> N[hoja/servicios/laboratorio/disponentes/:id\nHub estudios]
    N --> O[grupo/rh/biometria/hematica/completa/:id\nBiometría + Grupo/RH]
    N --> P[serologia/laboratorio/disponente/:id\nSerología]

    P -->|alguna prueba REACTIVA| DIF6[("🚫 DIFERIDO 100 años\n(producto se desecha)")]
    P -->|7/7 NO REACTIVO\nproceso=FINALIZADO| Q[("✅ LIBERADO\nimprime etiqueta QR\n→ inventario")]

    Q -.-> R[bitacora/salidas/almacen\nAlmacén: salida/desecho de productos]
        
Nota: reacciones/adversas (RAD) debería poder dispararse en cualquier punto durante/después de la flebotomía, pero hoy no está conectado al backend (solo UI).

5. Diagrama de flujo — Receptor (transfusión)

flowchart TD
    A[receptores\nLista de pedidos] --> B[hojaservicios/receptor/:id\nHub del pedido]

    B --> C[documentos/receptor\nDocumentos médicos]
    B --> D["tiparcruza (Lab)\nTipar y Cruzar vs disponentes compatibles"]
    B --> E[productos/receptor\nCatálogo → carrito]
    B --> F[historico/...\nHistórico]

    E --> G[orden/productos\nPago - app-pagos-censur]
    G -->|carrito.total = 0\ncambioEstadoCensur → 'reacciones transfucionales'| H[agregar/docuemtos/recpetor/firmados\nSube consentimientos firmados]
    H --> I[("✅ Fin del proceso\n→ /")]

    J[entrega/productos/sanguineos\nEtiqueta urgencia + Declaratoria PDF] -.standalone, sin id.-> J
        
⚠️ tiparcruza: la lógica de búsqueda de disponentes compatibles funciona, pero el guardado final (datosTiparyCruzar) está comentado, por lo que el resultado no persiste ni navega de vuelta al hub.

6. Diagrama de flujo — Jefatura Banco de Sangre (sedes)

flowchart TD
    A[listado/sedes/banco/sangre\nSedesbsComponent ✅] -->|tarjeta sede| B[detalle/sede/:id\nDetalleSedeComponent ⚠️]
    A -->|AGREGAR SEDE| C[agregar/sede/bs\nAgregarSedeComponent ⚠️ guardado deshabilitado]
    C -.iría a.-> A

    D[ficha/identificacion/sede ⚠️ vacío]
    E[bitacora/no-aptos ⚠️ placeholder]
    F[hoja/servicio/receptor (BS) ⚠️ placeholder]
    G[orden/servicio/receptores ⚠️ placeholder]
        

7. Casos de uso

CU-01 — Registrar y procesar una donación de sangre

Recepción registra al disponente → lo evalúa (autoexclusión) → Enfermería toma signos vitales → Doctor evalúa historia clínica y hace diagnóstico → Flebotomía extrae la sangre → Laboratorio analiza biometría/grupo/serología → el producto queda LIBERADO (apto para transfusión) o se desecha si hay reactividad.

CU-02 — Diferir/rechazar a un disponente

En cualquiera de los 5 puntos de control (autoexclusión, signos vitales, historia clínica, evolución/diagnóstico, serología), si el disponente no cumple criterios, se calcula un motivo y tiempo de diferimiento (fechaMayor toma el plazo más largo entre todas las causas detectadas) y se marca estatus: 'DIFERIDO'. Queda visible en bitacora/diferidos y, a nivel jefatura, en bitacora/no-aptos (este último aún no conectado).

CU-03 — Atender un pedido de transfusión para un receptor

Recepción ve el pedido (receptores → hub hojaservicios/receptor), sube documentos médicos, Laboratorio realiza tipaje y cruce con disponentes compatibles, Recepción agrega productos al carrito, cobra (orden/productos) y finalmente sube los documentos firmados por el receptor.

CU-04 — Gestión de sedes (Jefatura BS)

El jefe de Banco de Sangre visualiza el listado de sedes afiliadas, consulta el detalle de cada una y puede (en teoría) dar de alta nuevas sedes con su información fiscal y documentos.

CU-05 — Mantenimiento de catálogo de estudios

Un usuario de laboratorio define nuevos tipos de estudio (nuevo/estudios/lab) con sus valores de referencia, que luego se usan en biometria-lab-disponente y serologia-lab-disponente.

CU-06 — Control de almacén

Almacén consulta bitacora/salidas/almacen y marca productos como DESECHADO cuando corresponde.

8. Flujo end-to-end (resumen narrativo)

  1. Recepción registra al disponente (registro/disponentes) → aparece en bitacora/disponentes.
  2. Se abre su ficha (ver/disponente/:id), se elige el servicio "Donaciones" y una sede de origen → si es válido, pasa a autoexclusion/:id.
  3. El disponente responde el cuestionario de 12 preguntas. Si hay riesgo → DIFERIDO (fin). Si no → proceso = 'enfermeria' y aparece en disponentes/bitacora.
  4. Enfermería toma signos vitales (ficha/disponente/:id). Si están fuera de rango → DIFERIDO. Si no → se solicitan laboratorios (Grupo y RH, BHC, Serología), se imprimen etiquetas, proceso = 'doctor'.
  5. Doctor llena la historia clínica (historia/clinica/doctor/:id, por secciones con distintos umbrales de riesgo) → si pasa, continúa a hoja/evolucion/disponente/:id (exploración física + diagnóstico). Si el diagnóstico indica candidato_donacion = 'NO'DIFERIDO; si es 'SI'proceso = 'FLEBOTOMIA'.
  6. Flebotomía captura datos de la extracción y sube el consentimiento firmado (documentos/flebotomia/:id). Si firma → proceso = 'serologia', se imprime etiqueta "NO LIBERADO". Si no firma → autoexclusión/diferido.
  7. Laboratorio revisa el hub de estudios (hoja/servicios/laboratorio/disponentes/:id) → captura Biometría + Grupo y RH (grupo/rh/biometria/hematica/completa/:id) y Serología (serologia/laboratorio/disponente/:id).
  8. Si las 7 pruebas serológicas son NO REACTIVO → producto LIBERADO, se genera etiqueta QR, proceso = 'FINALIZADO', y el disponente queda automáticamente diferido 3 meses (regla estándar post-donación). Si alguna es REACTIVADIFERIDO permanente (100 años) y el producto se marca para desecho.
  9. En paralelo, el receptor (paciente que necesita transfusión) sigue su propio flujo desde receptores → hub hojaservicios/receptor/:id → documentos, tipar/cruzar (busca disponentes/productos compatibles vía /disponentes/grupoyrh), carrito de productos, pago y documentos firmados.
  10. Almacén controla la salida/desecho de los productos liberados (bitacora/salidas/almacen).
  11. Jefatura BS administra las sedes afiliadas (listado/sedes/banco/sangre, detalle/sede/:id, agregar/sede/bs).

9. Hallazgos importantes (calidad / pendientes)

ComponenteProblema
BitacoraAlmacenComponent (bitacora/almacen)Tabla 100% hardcodeada, sin servicio conectado
HojaServiciosLabsComponent (hoja-servicios)Código muerto, no referenciado en ninguna ruta ni plantilla
HistoricoEstudiosDisponenteComponentPlaceholder estático con una fila de ejemplo
BitacoraPedidosComponent (bitacora/hoja/de/servicios)Carga pacientes reales pero columnas de estatus/proceso/motivo están hardcodeadas
ReaccionesDerivadasComponentUI completa pero enviar() y getDisponente() están comentados — no persiste
TiparCruzarComponentBúsqueda de compatibles funciona, pero guardar() (POST /analisis/tipeycruce) está comentado; método/técnico/cédula hardcodeados
FISedeComponent, HojaServicioReceptorBSComponent, OrdenreceptoresComponent, BitacoraNoAptosODiferidosComponentPlaceholders vacíos o con datos de ejemplo, sin servicio
AgregarSedeComponentFormulario completo y validado, pero el POST /crear/sede/bs está comentado
DetalleSedeComponentTabla de "pedidos de sede" hardcodeada; getVenSede() se llama pero el resultado no se asigna
EntregaProductosComponentgetProductosAlmacen() se llama pero su resultado no se usa (solo console.log)