Skip to content

[FEATURE] Códigos jerárquicos de variantes de Supply (BASE-SUFIJO semántico por tipo) #2

Description

@vgpastor

Parte de la épica GlobalEmergency/ResponseGrid#228 (catálogo maestro Supply). Continúa GlobalEmergency/ResponseGrid#216 (dominio, variantes vía variantOfId + attributes).

Problema o valor

Hoy toda alta de insumo —base o variante— consume un código de primer nivel del catálogo (PREFIX-NNNN) de la secuencia global supply_code_seq. Resultado: las variantes "gastan" códigos de catálogo y no hay jerarquía visible entre una base y sus variantes.

Ejemplo real (alta del folleto Cáritas San Bernardino):

  • MED-0058 Guantes quirúrgicos estériles (base)
  • MED-0059 / MED-0060 / MED-0061 → tallas 7.0 / 7.5 / 8.0

Lo natural sería que la variante cuelgue de su base con un sufijo semántico según el tipo de insumo:

  • MED-0058-70 / MED-0058-75 / MED-0058-80 (guantes → talla)
  • medicación → dosis + envase (p. ej. …-500MG-VIAL)
  • solución/suero → concentración + volumen (NaCl 0.9% 500 ml)
  • sutura → material + calibre (nylon 2-0)
  • fórmula infantil → etapa

Estado actual (por qué no se puede hoy ni por datos ni por la API)

  1. Invariante de dominio Supply: code ~ ^[A-Z]{3}-\d{4}$MED-0058-70 no valida.
  2. Allocator (CreateSupply): asigna getCategoryPrefix() + nextval('supply_code_seq') a todo insumo; no distingue base de variante.
  3. code es inmutable (no editable por PATCH; CreateSupplyDto no tiene campo code) → las variantes ya creadas no se pueden recodificar por la API.

Propuesta

  • Relajar la invariante a ^[A-Z]{3}-\d{4}(-[A-Z0-9]+)?$ (sufijo opcional → retrocompatible con las variantes actuales sin sufijo).
  • CreateSupply: si viene variantOfId, derivar code = \${base.code}-${sufijo}`en vez de consumirnextval`. La base sigue igual.
  • Estrategia de sufijo por tipo (a definir): función que, a partir de la categoría/atributos de la variante, produzca el sufijo. Ejemplos:
    • guantes (attributes.talla) → 70/75/80
    • medicación (dosis, envase) → 500MG-VIAL
    • solución (concentracion, volumen) → 09-500ML
    • sutura (material, calibre) → NYLON-20
    • Fallback correlativo por base (-1/-2/-3) cuando no haya regla para ese tipo.
  • Backfill: recodificar las variantes existentes y liberar los números de primer nivel que consumieron.

Variantes ya creadas a recodificar (del alta del folleto)

Actual Base Propuesto (según estrategia)
MED-0056 / MED-0057 MED-0055 Insulina tipo NPH / regular
MED-0059 / MED-0060 / MED-0061 MED-0058 Guantes quirúrgicos estériles talla 70 / 75 / 80
MED-0067 / MED-0068 MED-0066 Solución salina (NaCl) concentración 09 / 20 (+ volumen)
MED-0070 / MED-0071 / MED-0072 MED-0069 Sutura quirúrgica nylon-20 / nylon-30 / seda-20
HYG-0079 / HYG-0080 / HYG-0081 HYG-0012 Fórmula para bebé etapa 1 / 2 / 3

Criterios de aceptación

  • La invariante de Supply admite el sufijo opcional; los códigos base y las variantes sin sufijo existentes siguen siendo válidos.
  • Al crear una variante (variantOfId presente), el código es <codBase>-<sufijo> y no consume supply_code_seq.
  • Estrategia de sufijo pluggable por tipo/categoría, con fallback correlativo determinista y único por base.
  • Índice único de code respetado (colisión de sufijo dentro de una misma base → error de dominio claro).
  • Migración/proceso de backfill que recodifica las variantes de la tabla y libera los números de primer nivel.
  • domain/ y application/ sin imports de @nestjs/*/drizzle (ESLint).

Preguntas abiertas / decisiones de producto

  • Regla de sufijo por tipo: ¿semántica derivada del atributo (más legible) o correlativo simple -1/-2/-3 (universal)? El interés de producto es la semántica por tipo (guantes→talla, medicación→dosis+envase…).
  • ¿Sufijos anidados para variantes de varios ejes (concentración y volumen), p. ej. MED-0066-09-500ML?

Contexto

Detectado como feedback de producto durante el alta del catálogo del folleto de donaciones Cáritas — San Bernardino de Siena, donde las 13 variantes creadas recibieron códigos de primer nivel en lugar de colgar de su base.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions