Guía de catálogo y trazabilidad
Plataforma agnóstica de catálogo + trazabilidad. El kernel (artículos, fichas versionadas, lotes, producción, genealogía, recall) es universal. La organización aporta su preset: dimensiones, tipos, estados, plantillas, formatos de código, todo configurable sin tocar TypeScript. Hoy está cargado el preset Demo.
#Empieza aquí
Si es tu primera vez, haz este recorrido en cinco minutos para entender de qué va el modelo. Cada paso es un click.
- 01
Mira un artículo real
Abre el primer artículo del listado. Verás su tipo, sus dimensiones de clasificación (en el preset Demo son α, familia, categoría, variedad, envase) y los lotes asociados. Algunos tienen varias versiones de ficha técnica.
Ir al catálogo - 02
Sigue un lote completo
Entra a un lote producido y mira su genealogía: qué lotes de materia prima se consumieron para producirlo, cuándo y en qué planta. El formato del código viene del
Ir a loteslot_code_templatedeclarado en el preset. - 03
Lanza una producción
Crea una OP nueva: el wizard te sugiere los lotes a consumir por FEFO (filtrado por estados con flag
Nueva produccióneligibleForFefo) según la receta, y crea todo (lotes salida, movimientos, genealogía y eventos) en una sola transacción.
#Kernel vs preset: la decisión arquitectónica
Todo lo conceptual (las 3 capas, la genealogía, FEFO, la trazabilidad forward/backward, las CTE) vive en el kernel. Todos los valores concretos (tipos, estados, dimensiones, formatos de código, plantillas) viven en el preset de cada organización.
- Articulo + FichaVersion + Lote (3 capas)
- Producción transaccional multi-output
- Genealogía DAG padre→hijo
- BFS forward/backward + recall
- FEFO automático según flag de estado
- Motor de plantillas con campos tipados
- Motor de lot code con templates
- Resolver polimórfico de plantilla
Cualquier empresa lo usa idéntico.
- Tipos de artículo (PT/SE/MP… o UVA/MOSTO/VINO…)
- Dimensiones (familia, variedad… o D.O., cosecha…)
- Estados (cuarentena/liberado o aging/bottling)
- Transiciones permitidas entre estados
- Templates de código de lote y OP
- Plantillas técnicas + reglas de matching
- Maestros (familias, plantas, envases, marcas…)
- Catálogos de opciones (multiselects)
Vive bajo src/presets/demo/.
#Las tres capas del modelo
Para entender el resto de la guía basta interiorizar esta idea: el modelo separa tres capas con distinto ciclo de vida y distinto grado de mutabilidad. Este patrón es kernel — todas las organizaciones lo comparten.
Identidad estable
Articulo / SKUPT000001MELOCOTÓN EN ALMÍBAR LATA 1KGVersión técnica
FichaVersionP26-R2brix 19, almíbar 18-20Instancia física
LoteMEL-FRC-12626-A950 kg · 6 may · planta FRC#Dimensiones de clasificación configurables
La jerarquía de clasificación de un artículo (familia, categoría, variedad, envase, o cualquier otra que la organización declare) vive en la tabla dimension_definition. El número, los nombres y la cadena padre→hijo son datos, no código.
Cada artículo combina α (un scope opcional como campaña / vintage / release window) con N dimensiones declaradas por la organización en dimension_definition. Hoy el preset Demo tiene cargadas 4 dimensiones:
01familiaGran familia comercial del producto.
- Tabla maestra
- familia
- Depende de
- (raíz)
- Tipo
- core · columna espejo en
articulo
02categoriaCategoría dentro de la familia. Junto a L1 selecciona la plantilla técnica.
- Tabla maestra
- categoria
- Depende de
- familia
- Tipo
- core · columna espejo en
articulo
03variedadVariedad o ingrediente principal reconocible por el operario.
- Tabla maestra
- variedad
- Depende de
- categoria
- Tipo
- core · columna espejo en
articulo
04envaseEnvase concreto del SKU (referencia al maestro de envases).
- Tabla maestra
- envase
- Depende de
- (raíz)
- Tipo
- core · columna espejo en
articulo
#Tipos de artículo
El tipo dispara las reglas operacionales: qué dimensiones son obligatorias, si entra a producción, si aplica clasificación, qué unidad por defecto se usa al recibir. Antes era un enum literal; ahora vive en article_type.
| Code | Label | Flujo prod. | Aplica clasif. | Dim. requeridas | Unidad |
|---|---|---|---|---|---|
| PT | PT · Producto Terminado | producible | sí | alpha, familia, categoria, variedad, envase | kg |
| SE | SE · Semielaborado | ambos | sí | — | kg |
| MP | MP · Materia Prima | no_producible | no | — | kg |
| ENV | ENV · Envase | no_producible | no | — | uds |
| AUX | AUX · Auxiliar | no_producible | no | — | uds |
| MAQUILA | MAQUILA | no_producible | no | — | kg |
#Estados configurables (lotes, fichas, artículos, OP)
Cada entidad relevante (lote, ficha técnica, artículo, orden de producción) tiene una tabla *_state con metadata (color, label, flags). Los lotes además tienen lot_state_transition que declara qué transiciones son legales.
cuarentena- Recién creado. No elegible para FEFO. Espera firma de calidad.
liberado- Listo para usar. Único estado elegible para FEFO y consumo.
bloqueado- Calidad rechaza por algún motivo. No se puede usar hasta desbloquear.
reservado- Apartado para un pedido o producción concreta.
consumido- Cantidad llegó a 0. Se conserva para trazabilidad.
caducado- Pasó la fecha de caducidad. Deja de ser usable.
Flags operacionales de los estados de lote
El kernel mira flags, no nombres. Las acciones cambian comportamiento según estos booleanos declarados en lot_state:
eligibleForFefo— entra al cálculo FEFO al sugerir consumos. En Demo: sololiberado.consumesStock— bloquea inventario para otra OP (caso reservado).isInitial— el estado al que entra un lote nuevo recién recibido o producido.isTerminal— estados finales (consumido, caducado). Excluidos de "próxima caducidad" y otras agregaciones.
#Códigos de lote y OP: motor de templates
El formato del código de lote no es fijo. Vive en la tabla lot_code_template con placeholders. El preset cargado declara los suyos; una bodega podría declarar BORDX-CABERNET-2024-001 con cambiar una fila.
XXXTres letras del L3 (ingrediente principal)
YYYCódigo de la planta productora
ZZZZZDía del año (3 dígitos) + año (2 dígitos)
ALetra de orden diaria por planta
Placeholders soportados por el motor
El motor genérico vive en src/lib/lot-code-engine.ts. Reconoce los siguientes placeholders y los sustituye en orden:
{variety:N}Code del L3 (variedad) recortado o padded a N caracteres{plant:N}Code de planta a N caracteres{family:N}Code de familia (L1) a N caracteres{julian}Día juliano del año (3 dígitos){year:2|4}Año en 2 o 4 dígitos{vintage}Alias semántico de {year:4} (bodegas){month}, {day}Mes y día en 2 dígitos{seq:alpha}Secuencia A,B,…,Z,AA,AB,…{seq:num:N}Secuencia numérica padded a N dígitos{prefix:X}Texto literalEstrategias de secuencia
per_day_per_plant— la secuencia se reinicia cada día y cada planta. Mocitos producción.per_day_global— reinicia por día. Mocitos compras.per_year_global— reinicia por año. Mocitos OPs.per_template— nunca reinicia (incremental).
#Versionado de ficha técnica
A media campaña cambias un parámetro técnico (por ejemplo, el grado de almíbar). En lugar de sobrescribir, creas una nueva revisión y dejas la anterior intacta para que los lotes históricos sigan apuntando a ella.
01 ene 2026activaP26-R1 entra en vigor
Brix 17, almíbar 17. Se producen los primeros lotes con esta ficha.
03 mar 2026loteProducción OP-2026-00001
Lote MEL-FRC-06226-A apunta a P26-R1.
03 mar 2026inmutableP26-R1 queda inmutable
Como ya tiene un lote referenciándola, se bloquea para edición.
15 jun 2026borradorNueva revisión P26-R2
El equipo técnico decide subir el almíbar a 18-20 y eliminar ascórbico. Crean nueva revisión en borrador.
15 jun 2026activaActivación de P26-R2
validFrom=15 jun. El sistema cierra automáticamente P26-R1 convalidTo=15 jun.06 jul 2026ambasProducción posterior
Lote MEL-FRC-18726-A apunta a P26-R2. El lote de marzo sigue apuntando a R1.
Inmutabilidad
En cuanto un lote referencia una ficha, esta queda marcada como inmutable. Ya no se puede editar: si necesitas cambiar algo, creas una revisión nueva. El editor de ficha lo refleja: cuando entras a una ficha inmutable se muestra en modo solo-lectura.
No-overlap por scope
Solo puede haber una ficha activa a la vez para el mismo artículo + scope. Al activar la R2, el sistema cierra automáticamente la R1 con validTo = R2.validFrom. Por defecto el scope es global; se puede ampliar a planta, cliente o marca cuando hace falta.
#Plantillas técnicas y reglas de matching
Cada plantilla declara qué dimensiones (y opcionalmente qué valores) debe tener un artículo para que se le aplique. El resolver es polimórfico: una plantilla puede tener 1, 2 o N reglas, y siempre gana la más específica.
plantilla "CONSERVA + FRUTAS"
└─ plantilla_match_rule
├─ dim_familia expected = ref_CONSERVA
└─ dim_categoria expected = ref_FRUTASLa plantilla aplica cuando un artículo tiene ambos valores en sus article_dimension_value. Una bodega declararía 3 reglas (familia + categoria + variedad) y el resolver funciona idéntico.
Algoritmo del resolver
- Carga los ADV (dimension values) del artículo.
- Para cada plantilla, comprueba que todas sus reglas se satisfacen contra los ADV.
- Entre las candidatas, gana la que tiene más reglas (más específica). A igualdad, determinístico por nombre.
- Devuelve
plantillaId+activeVersionId.
#FEFO automático en el wizard de producción
Cuando lanzas una producción, el wizard sugiere los lotes a consumir por FEFO (caducidad ascendente). Solo entran los lotes con flag eligibleForFefo=true; el resto se ignora.
FEFO automático
First-Expired-First-Out: cuando entra un pedido o se lanza una producción, el motor propone los lotes ordenados por caducidad ascendente. Solo entran al cálculo lotes cuyo lot_state.eligibleForFefo es true; cuarentena, bloqueado y caducado se excluyen. En el wizard de producción tienes el botón Sugerir entradas según receta + FEFO que rellena las líneas automáticamente.
Transición inicial: cuarentena
Todo lote nuevo entra por defecto al estado marcado con isInitial=true en lot_state (en el preset Demo: cuarentena). El botón Liberar aplica la transición declarada en lot_state_transition y crea evento de traza. Si la organización define un estado intermedio (validacion, aging), el flujo se ajusta solo.
#Trazabilidad: forward, backward y recall
La trazabilidad es la red de relaciones padre→hijo entre lotes que la producción va dejando. Permite responder a tres preguntas críticas en alimentación.
Backward: desde el lote raíz subes a sus tres padres. Forward: cuando este lote se consuma en otra OP, sus hijos aparecen al otro lado.
- Backward · ¿de qué está hecho este lote?
- Sube por la genealogía. Útil para auditorías y reclamaciones de cliente: dado un finished good, sabes qué materia prima llevó.
- Forward · ¿dónde acabó este lote?
- Baja por la genealogía. Útil para retiradas y para entender el destino: dado un MP sospechoso, sabes qué finished goods contaminó.
- Recall · ¿qué tengo que retirar?
- Forward + cruce con movimientos de envío + cálculo de stock vivo. Te dice: lotes en almacén, lotes en cliente, kg totales.
#Uso general de la aplicación
Qué hay en el menú lateral
- Catálogo · Artículos / Envases / Plantillas
- El maestro de artículos con sus dimensiones configurables (familia, categoría, variedad, envase…), los envases como entidad maestro propia (con vida útil y combinaciones permitidas) y las plantillas técnicas resueltas vía
plantilla_match_rule. - Operaciones · Lotes / Producción / Recetas
- Cada lote es una instancia física con código generado por el
lot_code_templateaplicable. La producción consume lotes y crea otros en una sola transacción, dejando genealogía padre→hijo. - Trazabilidad · Trazar / Impacto retirada
- Selecciona un lote y mira hacia arriba (entradas que lo formaron) o hacia abajo (descendientes producidos). El recall calcula el impacto de retirar un lote sospechoso.
- Administración · Maestros / Catálogos / Seed
- Vista de los maestros (familias, categorías, variedades, marcas, plantas, proveedores, clientes) y los catálogos de opciones. El botón Reset recarga el preset activo.
Convenciones de la UI
- Los badges de tipo (PT, SE, MP… en Demo) leen su label y color desde la tabla
article_type. La org puede renombrarlos. - Los badges de estado (lote, ficha, artículo, OP) leen su color desde la respectiva tabla
*_statey muestran sudescriptioncomo tooltip. - Cualquier código en monoespaciado es un identificador estable. Un click siempre lleva a su detalle.
- Asterisco rojo = campo obligatorio.
Reset y persistencia
Si te lías o quieres empezar limpio, ve a Admin → Preset / Reset y pulsa Recargar preset. Vuelves a tener el preset Demo completo. También puedes ejecutar bun run db:reset en el terminal. Los cambios que hagas en la app son persistentes entre recargas; solo se pierden con el reset.
#El preset Demo cargado
Esto es lo que la organización aportó. Si se intercambia el preset, todos estos valores cambian sin recompilar.
Tipos de artículo declarados
6 tipos: PT, SE, MP, ENV, AUX, MAQUILA. Cada uno con sus reglas de activación, defaults de aprovisionamiento y unidad por defecto. Editables en article_type.
Estados de lote
8 estados: borrador, cuarentena, liberado, bloqueado, reservado, consumido, caducado, descartado. El estado inicial es cuarentena; los eligibleForFefo entran a producción. Transiciones declaradas en lot_state_transition.
Plantillas y reglas de matching
Las plantillas del preset están listadas en /plantillas con un resumen de las reglas que las disparan (familia=X, categoria=Y, etc.). Editar el preset cambia tanto las plantillas como sus reglas en bloque.
Decisiones del preset Demo
- α + dimensiones jerárquicas
- El wizard recorre las dimensiones declaradas en el orden de su sortOrder. La campaña α vive como atributo separado del SKU y se replica en cada versión de ficha. Renombrable y reorganizable.
- Plantilla específica por combinación de reglas
- CONSERVA + FRUTAS tiene los 15 campos del Excel multiselect (corte, líquido de gobierno, calibre, calidad, marca, etc.). El resolver matchea por reglas (familia=CONSERVA, categoria=FRUTAS) en plantilla_match_rule.
- Maestro de envases
- Los envases están dados de alta una sola vez. La vida útil vive en el envase, no en el SKU. Al recibir un lote comprado, la caducidad se sugiere automáticamente sumando la vida útil del envase a la fecha de producción.
- Combinaciones envase × familia × categoría
- El wizard rechaza combinaciones imposibles. Todo está parametrizado en envase_combinacion.
- Plantas autorizadas por SKU
- Las plantas están como maestro. Aparecen como plantas autorizadas a producir en el SKU y como segmento del código de lote según el template configurado.
- Make-or-buy en SE
- Los semielaborados pueden tener simultáneamente fabricar=sí y comprar=sí (caso típico: purés en bidón que se compran a terceros o se fabrican internamente).
- Maquila / customer_owned
- Los lotes marcados como customer_owned aparecen con badge MAQUILA pero no se cuentan como inventario propio.
- Cambio de ficha a media campaña
- PT000001 trae P26-R1 (cerrada con validTo) y P26-R2 (activa). Los lotes antiguos siguen apuntando a R1 mientras los nuevos van contra R2.
#Onboardear otra empresa
Toda la configuración descrita arriba se carga desde un preset. Para añadir otra empresa, basta con crear su preset bajo src/presets/<codigo>/ y cargarlo. No se toca TypeScript del kernel.
- 1. Crear el directorio del preset
src/presets/winery/(por ejemplo) con la misma estructura quesrc/presets/demo/:index.ts,data.ts,types.ts,states.ts,dimensions.ts,lot-templates.ts,templates.ts,articles.ts,operations.ts. - 2. Declarar los maestros en
data.ts: plantas, familias, categorías, variedades, marcas, proveedores, clientes, envases, option catalogs. - 3. Declarar tipos y estados en
types.tsystates.tscon sus flags (requiredDimensions, isInitial, eligibleForFefo, etc.) y transiciones para lote. - 4. Declarar dimensiones en
dimensions.ts: las 4 core (familia, categoria, variedad, envase) renombradas a tu gusto, y las extra (denominación origen, región…) conisCore=false. - 5. Declarar templates de lote en
lot-templates.ts: cualquier formato con placeholders del motor. - 6. Declarar plantillas técnicas en
templates.tscon sus reglas de matching (dimensión + valor esperado). - 7. (Opcional) artículos y operaciones de demo en
articles.tsyoperations.tspara tener datos al arrancar. - 8. Activar el preset editando
src/db/seed.ts: cambiarloadPreset(mocitosPreset)porloadPreset(wineryPreset). - 9. Branding cosmético en
.env.local: ajustarNEXT_PUBLIC_PLATFORM_NAME,NEXT_PUBLIC_DEMO_ORG_NAME. - 10. Reset con
bun run db:reset. La app aparece con los maestros, dimensiones, estados, plantillas y lot code formats del nuevo preset, totalmente funcional.
#Flujos paso a paso
Cada flujo está pensado para validar una decisión concreta del modelo. Si los recorres todos enteros, entiendes el mockup. Los ejemplos usan datos del preset cargado.
Crear un artículo desde cero
Verificar la cascada dinámica de dimensiones y la validación de packaging compatibility.
- 1.Ve a Artículos → Crear artículo.
- 2.Paso 1 · Tipo: selecciona uno de los tipos declarados (en el preset Mocitos: PT). El tipo determina qué dimensiones son obligatorias para activar.
- 3.Paso 2 · Identidad: pon un código (p. ej. PT000999) y nombre. Las dimensiones cascadean según parent_dimension_code declarado.
- 4.El selector L4 (envase) solo muestra envases compatibles según envase_combinacion. La vida útil del envase se muestra debajo.
- 5.Paso 3 · Plantilla común: rellena lo que quieras. Plantas autorizadas, marca, certificaciones, alérgenos.
- 6.Paso 4 · Resumen y crear: el artículo se crea en el estado isInitial declarado. Verás su detalle.
Rellenar la ficha técnica con la plantilla del Excel
Comprobar que los multiselects del Excel CONSERVA + FRUTAS se cargan y se guardan tipados.
- 1.Abre /articulos y entra a un PT con familia CONSERVA y categoría FRUTAS.
- 2.En la pestaña Versiones, pulsa Nueva revisión. Pon α=P26, R=R1 y validFrom=hoy.
- 3.Se abre el editor. Rellena variedad de fruta, calibre, calidad, corte, líquido de gobierno, peso escurrido, brix, pH, valor F, laminado, marca, línea, receta. El campo Tags es multiselect.
- 4.Pulsa Guardar y activar. La ficha pasa a estado activa.
- 5.Vuelve al artículo: en la pestaña Ficha activa verás los valores con badges de los multiselects.
Recibir un lote comprado del proveedor
Validar la herencia del lote del proveedor, el código PRV-…, la fase de cuarentena y la firma de calidad.
- 1.Ve a Lotes → Recepción.
- 2.Selecciona MP000001 (MELOCOTÓN FRESCO ANDROS), proveedor Frutas del Sur, lote del proveedor (libre, p. ej. ANDROS-2660/B), planta FRC.
- 3.Cantidad 1000 kg, ownership owned. La caducidad se sugiere automáticamente desde la vida útil del envase.
- 4.Pulsa Recibir lote. Se crea con código PRV-ZZZZZ-A en estado cuarentena, con su movimiento y evento de trazabilidad.
- 5.En el detalle del lote, pulsa Liberar de cuarentena. Pasa a liberado, queda firmado por calidad y se registra evento liberacion_calidad.
Lanzar una orden de producción multi-output
Validar la transaccionalidad: una sola operación crea OP, lotes salida, movimientos consumo, genealogía y eventos.
- 1.Ve a Producción → Nueva.
- 2.Selecciona PT000001, planta FRC. Aparece automáticamente la ficha activa P26-R2 y la receta v1.
- 3.Cantidad objetivo 1000 kg. Pulsa Sugerir entradas según receta + FEFO: se rellenan tres lotes en orden de caducidad ascendente.
- 4.En Salidas: añade una salida principal (PT000001, 950 kg) y una scrap (PT000001, 50 kg). El sistema genera lotes con código MEL-FRC-ZZZZZ-A.
- 5.Pulsa Lanzar producción. En la confirmación se ve la OP con todos los lotes consumidos y producidos.
Trazar un lote forward y backward
Comprobar que la BFS recorre la genealogía correctamente en ambos sentidos.
- 1.Ve a Trazabilidad → Trazar lote.
- 2.Busca un lote MP recibido. En la pestaña Forward verás el árbol de producciones que lo consumieron.
- 3.Cambia a un lote PT. En Backward verás los lotes MP/EN que lo formaron.
- 4.En la pestaña Completo verás el árbol entero con el lote seleccionado destacado.
Calcular impacto de retirada
Validar el caso regulatorio de recall: dado un lote sospechoso, ¿qué tengo en stock y qué he enviado?
- 1.Ve a Trazabilidad → Impacto retirada.
- 2.Selecciona el lote MP de melocotón fresco.
- 3.Verás Resumen con los lotes afectados aguas abajo, el stock vivo total y los envíos a clientes.
- 4.El árbol forward muestra qué lotes se contaminaron a partir del sospechoso.
- 5.La tabla Lotes con stock remanente lista cada hijo y cuántos kg/uds hay aún para retirar.
Inspeccionar el maestro de envases
Comprobar que envase es entidad maestro propia, no copiada en cada SKU.
- 1.Ve a Envases y entra a LATA 1KG.
- 2.Verás la ficha física (material, capacidad, tara, uds/caja, cajas/palet, vida útil) y las combinaciones permitidas.
- 3.Abajo aparece la lista de SKUs que la usan. Si pinchas, vas al artículo correspondiente.
#Glosario
- Kernel
- Núcleo agnóstico de la plataforma. Define las 3 capas, la genealogía, FEFO, trazabilidad, motor de plantillas y motor de lot codes. Todas las organizaciones lo usan idéntico.
- Preset
- Paquete declarativo (en
src/presets/<codigo>/) con los maestros, tipos, estados, dimensiones, plantillas y datos seed de una organización concreta. Hoy: Demo. - α (alfa)
- Scoping period del artículo (campaña / vintage / release window). Atributo libre. Mocitos usa P25, P26, P27. Una bodega usaría años (2020, 2021…).
- article_type
- Tabla de tipos de artículo. Cada fila declara flags (requiredDimensions, flujoProduccion, defaultUnit…) que el motor consulta en lugar de comparar strings hardcoded.
- dimension_definition
- Tabla de dimensiones de clasificación declaradas por la organización. Soporta cadena padre→hijo vía
parent_dimension_code. - article_dimension_value
- Pares (artículo, dimensión, valor) que asocian las dimensiones concretas de cada SKU. Permite añadir dimensiones extra sin tocar el schema de articulo.
- lot_state / lot_state_transition
- Estados de lote configurables con flags
eligibleForFefo, consumesStock, isInitial, isTerminaly transiciones declarativas validadas en server actions. - lot_code_template
- Templates de generación de códigos de lote y OP, con placeholders
{variety:3},{plant:3},{julian},{vintage},{seq:alpha|num}. - plantilla_match_rule
- Reglas (dimensión = valor) que disparan una plantilla técnica cuando se aplican al artículo. Resolver polimórfico: gana la más específica.
- Versión de ficha
- Snapshot técnico inmutable una vez consumido por un lote. Código
α-Rn(ej. P26-R1, P26-R2). - Lote
- Instancia física producida o recibida. Apunta a la ficha y receta exactas. Su estado dicta qué acciones aplica.
- Genealogía
- Aristas padre→hijo entre lotes. Permite trazabilidad forward/backward.
- FEFO
- First-Expired-First-Out. El kernel filtra lotes por flag
eligibleForFefoy los ordena por caducidad. - Maquila
- Material físicamente en almacén pero propiedad del cliente. Convención de Mocitos para
ownership=customer_owned. - Recall
- Cálculo del impacto de retirar un lote: descendientes + stock vivo + envíos a clientes.
- Scope
- Ámbito de aplicación de una ficha. Por defecto global.
- Inmutabilidad
- Una ficha o receta queda bloqueada para edición en cuanto un lote la referencia.
- OP
- Orden de Producción. Operación atómica que consume lotes de entrada y crea lotes de salida con genealogía.
#Problemas frecuentes
No me deja seleccionar un envase en el wizard de artículo
No me deja activar un artículo
article_type.requiredDimensions del tipo elegido y comprueba que esos campos estén rellenos. El error te dice qué falta. Si quieres cambiar qué es obligatorio para un tipo, edita esa columna en article_type.La ficha no me deja editar valores
La producción me da error de cantidad insuficiente
El árbol de trazabilidad sale vacío
Quiero añadir un estado de lote nuevo (ej. aging)
lot_state con su color y flags, y declara las transiciones en lot_state_transition (from → to). La UI mostrará automáticamente el badge nuevo y el botón de la transición cuando el lote esté en el estado origen. Ver ejemplo en docs/refactor-plan.md.Quiero cambiar el formato del código de lote
lot_code_template.template con tu formato. Placeholders disponibles: {variety:N}, {plant:N}, {julian}, {year:2|4}, {vintage}, {month}, {day}, {seq:alpha|num:N}. La sequence_strategy dicta cuándo reinicia el contador.Quiero empezar de cero
bun run db:reset.Empieza creando tu primer artículo
El wizard te lleva por los cuatro pasos: tipo, clasificación, plantilla común y revisión. En menos de un minuto verás cómo se comporta el modelo con tus propios datos.