Saltar al contenido
DispensAI

CAT-001

Alta de producto padre

Registrar un nuevo tipo de medicina en el catálogo de la organización, de modo que pueda recibir formatos y quedar disponible para la asignación de lotes y la posterior dispensación.

CAT-001 — Alta de producto padre

1. Objetivo

Definir el procedimiento mediante el cual el administrador de catálogo de la organización sin fines de lucro registra un nuevo tipo de medicina en el sistema. El registro del producto padre es el primer eslabón de la cadena de trazabilidad: sin él, no puede existir un formato de presentación ni una asignación de lote.

2. Alcance

Aplica a toda incorporación de un nuevo tipo de medicina al catálogo activo de la organización. No aplica a la edición de fichas existentes (CAT-002) ni a la creación de formatos de presentación (CAT-003).

3. Definiciones

  • Producto padre: registro en la tabla products con parent_product_id = NULL. Define el tipo de medicina. No tiene stock ni lote propio: esos atributos viven en sus hijos (formatos).
  • Formato: producto hijo en products con parent_product_id apuntando al padre. Contiene unit_grams, stock y lot_inventory_id.
  • Catálogo: conjunto de productos padres activos en el tenant.

4. Roles y responsables

RolResponsabilidad
Admin catálogoÚnico rol autorizado para crear productos padres. Verificado por profile.role = "admin" en la server action.

5. Disparador de inicio

La organización resuelve incorporar un tipo de medicina que hoy no figura en su catálogo. El administrador de catálogo ingresa a /admin/medicina y selecciona la opción de nueva medicina.

6. Requisitos previos

  1. El usuario ha iniciado sesión con rol admin en el panel de la organización.
  2. La medicina a registrar no existe aún en el catálogo activo (verificación manual; sin restricción de unicidad de nombre en base de datos — ver §17).
  3. Se cuenta con la denominación técnica correcta de la medicina.

7. Entradas

Datos del producto padre, cargados en el formulario de nueva medicina:

  • Nombre de la medicina.
  • Descripción.
  • Sucursal (branch_id).
  • Estado inicial.

No hay documentos adjuntos ni datos de socios en este flujo: las entradas son exclusivamente información de catálogo de la organización.

8. Procedimiento paso a paso

  1. Acceso al módulo de catálogo. El administrador ingresa a /admin/medicina y selecciona la opción de nueva medicina.

  2. Carga de datos del producto padre. El sistema presenta un formulario con los campos mínimos: nombre de la medicina, descripción, sucursal (branch_id) y estado inicial. El administrador completa los campos y confirma.

  3. Registro en base de datos. La server action createMedicine valida la sesión y el rol del usuario (profile.role = "admin"). Si la validación falla, retorna { error: "No autorizado" } sin operar. Si pasa, inserta el registro en products con parent_product_id = NULL.

  4. Disponibilidad del producto padre. El sistema redirige al listado de medicinas y el nuevo producto padre aparece disponible para la creación de formatos.

9. Puntos de control

Punto de controlTipoEvidencia
Autenticación activaAuth check en server actionsupabase.auth.getUser() en createMedicine
Rol adminRole check en server actionprofile.role !== "admin" → error (CONFIRMADO)
Inserción en productsDB writeServer action retorna { error } si falla; no lanza

10. Criterios de decisión

Este protocolo resuelve una sola cosa: si el producto padre queda registrado o no registrado.

SituaciónResultado
Sesión activa, rol admin y campos mínimos completosProducto padre registrado en products con active = true y parent_product_id = NULL; visible en /admin/medicina; habilitado para recibir formatos (CAT-003)
Falta sesión o el rol no es adminNo registrado; la server action retorna error antes de operar
La inserción en base de datos fallaNo registrado; la server action retorna { error } con el código de la base

11. Excepciones y escalamiento

Caminos de error del sistema:

SituaciónRespuesta del sistema
Usuario sin sesiónLa server action retorna error antes de operar
Usuario con rol no admin{ error: "No autorizado" }
Error de base de datos{ error: "Error al crear..." } con código; log en consola del servidor

Envío duplicado del formulario. No hay mecanismo de idempotencia confirmado para la creación de producto padre. Dos envíos del formulario generan dos filas en products. La unicidad depende de la UI o del operador (ver §17). Ante un duplicado detectado, el administrador de catálogo da de baja la ficha sobrante y deja constancia del motivo; no se borra el registro.

Escalamiento. Un error de base de datos persistente se escala al responsable de TI de la organización. La creación no se fuerza por vías directas a la base de datos: hacerlo saltearía la guarda de rol de la server action.

12. Registros generados

  • Fila en la tabla products con parent_product_id = NULL.
  • No se generan documentos clínicos ni PDFs.
  • No se genera evento en iso_system_events — ver brecha 1 en §17.

13. Indicadores

IndicadorFórmulaMetaFuente
Productos padre con al menos un formato activoPadres con ≥1 hijo activo ÷ total de padres activos≥ 90 %Tabla products
Tiempo entre alta del padre y primer formato disponibleFecha del primer hijo − fecha del padre≤ 5 días hábilesTabla products

14. Riesgos y controles

RiesgoControlTipo
Creación de producto padre por un usuario sin autorizaciónGuarda profile.role !== "admin" en createMedicine (§9)Preventivo
Alta de producto padre sin rastro de autoría ni fecha auditableSin control en el sistema — brecha 1 declarada en §17. Mitigación operativa: el administrador de catálogo deja constancia del alta en el registro interno de la organizaciónCorrectivo
Dos productos padre con el mismo nombre en el mismo tenantSin control en base de datos — brecha 2 declarada en §17. Mitigación operativa: verificación manual del catálogo antes del alta (§6, requisito 2)Detectivo
Trazabilidad ambigua por nombre ante una discrepancia de inventarioRevisión del catálogo contra lot_product_assignments (LOT-001)Detectivo
Aparecer como establecimiento comercialEl catálogo registra medicina de la organización, no oferta de venta. No se publican precios ni condiciones de compra en este flujoPreventivo

Privacidad. Los datos de este flujo son información de catálogo de la organización, no datos personales de socios. No aplica tratamiento de datos sensibles.

15. Normativa y referencias

NormaReferenciaQué cubre en este protocolo
ISO 9001:2015§8.5.2Identificación y trazabilidad: el producto padre es el identificador raíz de la cadena
ISO 9001:2015§8.5.4Preservación: la ficha del padre preserva la identidad de la medicina a lo largo del ciclo
Ley 20.000Custodia y trazabilidadLa sustancia debe identificarse unívocamente desde su ingreso al catálogo
Decreto 84/2015 MINSALRegistro de dispensaciónEl producto padre es el primer eslabón del registro que sostiene cada dispensación

El cumplimiento de estas normas no está certificado por ninguna autoridad. Este protocolo declara qué controles ejecuta la organización, no que un tercero los haya auditado.

16. Anexos y formularios vinculados

  • Creación de formato / presentación ([[wiki/entities/dispensai/protocolos/CAT-003]])
  • Edición de ficha de medicina ([[wiki/entities/dispensai/protocolos/CAT-002]])
  • Asignación de lote a producto ([[wiki/entities/dispensai/protocolos/LOT-001]])

17. Implementación en el sistema

El protocolo está implementado en su paso de registro. La autorización está en la server action; no existe restricción de base de datos que impida la creación de duplicados por nombre.

Elemento del protocoloDónde vive
Guardia de autenticación (paso 3)supabase.auth.getUser() en createMedicine — server action "use server"
Guardia de rol admin (paso 3)profile.role !== "admin" → { error: "No autorizado" } en createMedicine
Inserción en products sin parent_product_id (paso 3)Tabla products, columna parent_product_id = NULL
Visibilidad en panel (paso 4)Ruta /admin/medicina, revalidatePath tras inserción

Brechas conocidas:

  1. Sin evento ISO al crear producto padre. Confirmado por lectura del archivo app/actions/medicines.ts: createMedicine no contiene llamada a logISOSystemEvent. Sólo updateMedicine emite eventos ISO (product_stock_changed, product_updated). El alta de un producto padre no deja rastro en iso_system_events. Si el catálogo se audita, no hay evento que identifique quién creó el producto ni cuándo. El audit trail de inventario comienza con un hueco en su primer paso.

  2. Sin restricción de unicidad de nombre de producto padre en base de datos. No se encontró un UNIQUE sobre products.name en las migraciones revisadas. Dos productos padres con el mismo nombre en el mismo tenant son posibles si la UI no lo impide. La trazabilidad por nombre queda ambigua ante una discrepancia de inventario.

Brecha observada en auditoría 2026-08-31

  • Ruta no encontrada exacta: /admin/medicina/nueva — puede ser variante (singular/plural, /admin vs /dashboard) o ruta renombrada. Acción correctora: actualizar el frontmatter con la ruta real que usa el sistema.

18. Historial de versiones

VersiónFechaCambioAutor
1.02026-08-28Versión inicial. Redactada desde la corrida de evidencia 2026-08-28-CAT-LOT. Dos brechas declaradas.Catálogo
1.12026-08-29Cierre de INFERIDO: confirmada la guarda profile.role !== "admin" en createMedicine (ya figuraba CONFIRMADO en §9). Confirmada la ausencia de logISOSystemEvent en createMedicine por lectura directa de app/actions/medicines.ts (brecha 1 pasa de INFERIDO a CONFIRMADO). Sin UNIQUE en products.name — confirmado sin hallazgo en migraciones (brecha 2 CONFIRMADO). Estado ascendido a Vigente.Catálogo
1.22026-08-29Realineamiento estructural al contrato del catálogo (_template.md): los 18 títulos de sección pasan a los de la plantilla y el contenido se redistribuye según lo que cada sección exige. Definiciones pasan de §4 a §3; roles de §5 a §4; requisitos previos de §6 a §6 con su título de contrato. Se escriben desde cero §5 Disparador de inicio y §7 Entradas, ambas derivadas de la evidencia ya presente en §8. Los criterios de éxito pasan a §10 Criterios de decisión; caminos de error e idempotencia se consolidan en §11 Excepciones y escalamiento; §14 pasa de privacidad a Riesgos y controles conservando la declaración de privacidad. El antiguo §3 Marco normativo se absorbe en §15, que ya cubría las mismas tres normas. Sin cambios en §17: las dos brechas se mantienen íntegras con su evidencia.Catálogo
1.0+audit-2026-08-312026-08-31Detectados gaps en auditoría: /admin/medicina/nueva. §17 actualizada para documentar la brecha con evidencia de código. Estado documental sin cambio.Auditoría automática

Documentos asociados

  • Ficha de producto
  • Especificación técnica de la medicina

Registros y evidencia

  • Registro de creación en tabla products
  • Sin evento ISO al crear producto padre (brecha confirmada — createMedicine no llama a logISOSystemEvent)

Indicadores

  • % de productos padre con al menos un formato activo
  • Tiempo entre alta de padre y primer formato disponible

Normativa y referencias

  • Ley 20.000
  • ISO 9001:2015 §8.5.2
  • ISO 9001:2015 §8.5.4

Dónde deja rastro en el sistema

Rutas
  • /admin/medicina
  • /admin/medicina/nueva
Tablas
  • products