Admin · Fletes FCL · multicontenedor y multiproveedor
¿Cuántos proveedores? ¿Cuántos contenedores? De un vistazo.
Un cliente pide ocho contenedores a tres fábricas, una naviera, un BL y una sola factura.
El admin de hoy sabe de un contenedor por flete, un equipo por flete, la naviera como texto libre y ninguna
relación entre la orden y su proveedor. La propuesta: el alta entiende 8x40HQ, los números se pegan en bloque,
la naviera es un catálogo, y los dos contadores viven en la cabecera de cada flete.
InformaciónContenedores 8BL y naviera 1Envíos 3SeguimientoPago
Carga por órdenes3 órdenes · 3 proveedores
YH
Yiwu Huaxing Commodity Co.
Yiwu, Zhejiang · 29.3068, 120.0754
ORD-9127 · 4 contenedores Factura INV-2026-0912 · única
FL
Foshan Lumina Lighting
Foshan, Guangdong · 23.0218, 113.1219
ORD-9131 · 3 contenedores
GM
GZ Metalcraft Ltd.
Guangzhou, Guangdong · 23.1291, 113.2644
ORD-9140 · 1 contenedor
TarifaCotizado
Flete FCL · 6 × 40' HC 6 × $2,850$17,100
Flete FCL · 2 × 20' DRY 2 × $1,900$3,800
Gestión aduanal$1,200
Total del flete$22,100
01Hoy: un contenedor, un equipo, una naviera escrita a mano
evidencia · plan §1–§2
El FCL v1 (PRs #618 a #624) hizo bien una cosa: un contenedor exclusivo por flete, con reserva, sello, VGM y evidencias.
Lo que no puede decir es cuántos son. Freight.containerId apunta a uno; requestedEquipmentType es un solo valor;
la naviera es un campo de texto en el contenedor; la orden no sabe quién la despacha.
Ruta del contenedor🚢 Marítimo · Shekou → La Guaira
N° de contenedorpendiente · RSV-2026-0917-04
texto libre
Sin asignar
Sin asignar
Flete vinculado
Un contenedor completo lleva un solo flete. No se asignan ni se mueven fletes desde aquí.
Ver flete vinculado
Copy tomado de apps/admin/lib/i18n/locales/es.json: freights.fields.equipment, freights.create.fcl.containerCode*,
containers.detail.context.carrier*, containers.reservation.*. Los bloques son freight-cargo-block.tsx,
fcl-equipment-picker.tsx y container-context-block.tsx.
Hoy
Las dos preguntas no tienen dónde vivir
Un contenedor por flete.Freight.containerId único; el trigger exige exactamente uno.
Un equipo por flete.requestedEquipmentType no puede decir 6x40HQ + 2x20.
Naviera en texto libre sobre el contenedor; sin catálogo, sin SCAC, sin filtro.
La orden no tiene proveedor.Order.supplierId no existe; Supplier es catálogo de sourcing.
No hay BL. La única mención es el copy de subida de evidencias.
Contar es abrir. Para saber cuántos son, se abren las órdenes una por una.
Proveedores
—
Contenedores
1
Fletes por 8 cajas
8
Propuesta
Un flete, un cliente, una factura. N contenedores.
El contenedor apunta al flete.Container.freightId para FCL; Freight.containerId queda para LCL (opción C).
Equipo por contenedor. El alta entiende 8x40HQ y crea ocho reservas; el texto nunca se guarda.
Naviera como catálogo (Carrier), espejada al contenedor para que la búsqueda no se rompa.
Proveedor en la orden y ubicación en la ficha: ciudad, provincia, dirección, lat/long.
BL con sus contenedores. Un BL ampara 1..N contenedores del mismo flete; booking antes del número.
Dos contadores en la cabecera de todo flete FCL, siempre visibles.
Proveedores
3
Contenedores
8
Fletes por 8 cajas
1
02Alta: la notación de operaciones, tal cual se escribe
plan §4.2 · §5.1
Samuel escribe 8x40HQ en WhatsApp. El campo Equipo acepta exactamente eso, y también 6x40HQ + 2x20;
debajo aparece lo que entendió, como chips con stepper, y el resumen en vivo. Los números de contenedor se pegan como llegan
en el correo de la naviera: uno por línea, con comas o con espacios. Cada fila se valida sola; una inválida no frena a las otras siete.
Propuesta · /freights/create · toggle FCL
Fletes · Crear flete · /freights/create
Crear flete FCL
Distribuidora Rondón C.A. · corredor China · Shekou → La Guaira
Full container · FCL
Equipopor contenedor
6x40HQ + 2x20
Alias: 40HQ · 40HC · 40'HC → 40' HC. 40 · 40GP · 40DV → 40' DRY. 20 · 20GP → 20' DRY. Reefer y open top se rechazan con mensaje.
6 × 40' HC−+2 × 20' DRY−+0 × 40' DRY−+
8 contenedores · 6 × 40' HC · 2 × 20' DRY · se crean 8 reservas
Navieraopcional en el alta · crea el booking
ms
CHMSC · Mediterranean ShippingMSCU
DKMaerskMAEU
CNCOSCO ShippingCOSU
FRCMA CGMCMDU
JPONE · Ocean Network ExpressONEY
Crear naviera «ms…»
Si eliges la naviera aquí, el flete nace con un BL en estado booking sin número, y la naviera se espeja a los 8 contenedores.
Números de contenedoropcional · pega la lista como te llegó
Saltos de línea, comas o espacios. Se normalizan a mayúsculas y se validan con el dígito de control ISO 6346. Cada número se asigna a la siguiente reserva pendiente de su tipo.
MSCU5217340→ 40' HC · reserva 1
MEDU7349126→ 40' HC · reserva 2
MSCU8801240→ 40' HC · reserva 3
TCLU6402812→ 40' HC · reserva 4
MSDU2298168→ 20' DRY · reserva 7
MSCU3119080dígito de control inválido: ¿MSCU3119089?
MSCU4992071ya existe en MG-FL-2377 · CONTAINER_CODE_EXISTS
3 reservas quedan pendientes de número2 × 40' HC · 1 × 20' DRY
5 asignados · 1 inválido · 1 duplicadolos válidos se guardan igual
CargaCarga declaradaÓrdenes
Orden
Proveedor
Factura
Bultos
ORD-9127
Yiwu Huaxing · Yiwu
INV-2026-0912
42
ORD-9131
Foshan Lumina · Foshan
INV-2026-0912
18
ORD-9140
sin proveedor
INV-2026-0912
6
ORD-9102
GZ Metalcraft · Guangzhou
INV-2026-0877
11
3 órdenes·2 proveedores·1 sin proveedoruna factura para los 8 contenedores
Tarifauna fila base por tipo de equipo · cantidad desde Equipo
Flete FCL · 6 × 40' HC 6 × $2,8502,850.00$17,100
Flete FCL · 2 × 20' DRY 2 × $1,9001,900.00$3,800
Gestión aduanal1,200.00$1,200
Total del flete$22,100
Si después del alta se añade un contenedor de un tipo nuevo, ese grupo vuelve a Sin tarifa y se muestra en rojo. Nunca se recalcula solo.
CancelarCrear flete · 8 reservas
Un solo POST con Idempotency-Key: flete + cotización + 8 reservas + BL (booking) + carga + outbox. Todo o nada. La respuesta trae
containers: [{ id, reservationReference, code, requestedEquipmentType, status, version }]. Tope propuesto por alta: 60 contenedores (pregunta 10).
03Resumen: los dos contadores, en sus tres estados
plan §3.1 · §5.2
Los contadores van en la cabecera, antes del estado y de la tarifa, porque son la pregunta que se hace primero.
Proveedores se cuenta por orden (distintos supplierId) o se lee de la declaración cuando la carga es DECLARED.
Contenedores es el mismo número en ambas fuentes, con el desglose que operaciones necesita: identificados, reservas pendientes, y por equipo.
Cuando no se sabe, se muestra —: nunca un cero inventado.
Yiwu Huaxing · YiwuFoshan Lumina · FoshanORD-9140 sin proveedor
Contenedores
8 8 × 40' HC
8 identificados2 BL · 2 salidas
Fuente carga declarada supplierCount declarado por el cliente · o desconocido
Proveedores
3 declarado por el cliente
Sin nombres: la declaración solo lleva el conteo (pregunta 9)
Proveedores
— desconocido
El cliente no lo declaró. Vacío no es cero.
Los mismos dos números se repiten en /freights como columnas «Prov.» y «Cont.», en el PDF del flete («Proveedores declarados: 3» · tabla «Contenedores (8)») y en el resumen del cliente («8 contenedores · 5 identificados»).
04Contenedores: la pestaña nueva del flete
plan §5.2
Una fila por contenedor. La referencia siempre existe; el número aparece cuando la naviera lo asigna. Equipo solicitado y confirmado
van juntos porque la regla de v1 sigue: la solicitud nunca se copia como confirmación. Desde aquí se pegan números (mismo componente que el alta)
y se añade una reserva más, siempre antes de LOADING y con revalidación de tarifa.
InformaciónContenedores 8BL y naviera 1Envíos 3SeguimientoPago
Estado del flete = el contenedor menos avanzado, sin contar cancelados (pregunta 3)3/8 con incidencia → badge en el flete, no cambia su estado
En /containers/[id] no hay rediseño: se añade el bloque «Flete y BL» (flete vinculado · contenedor 3 de 8 · BL y naviera) y «Equipo solicitado» de solo lectura junto al confirmado. Identificar equipo, sello, VGM, evidencias, escalas y cierre ya son por contenedor.
05Capacidad: el contenedor se llena con las órdenes
plan §4.9 · §5.7
La suma de los CBM de las órdenes que van dentro de un contenedor es su presupuesto de volumen. En vez de una cifra,
la caja se dibuja de lado y se llena desde el piso con cada orden asignada. Cuatro estados, siempre con la cifra al lado:
vacío, en curso, casi lleno a partir del 85 % y sobre capacidad cuando el sobrante asoma por encima del techo.
La capacidad es la útil de planificación por equipo (28 · 58 · 68 m³); la nominal queda en el tooltip.
Decisión de Carlos · 22 sep 2026«Me gusta una mezcla de estos dos»: la silueta en la pestaña Contenedores y la pila al asignar una orden quedan cerradas como patrón. Sobre capacidad nunca bloquea: motivo obligatorio, guardado en la asignación, rojo hasta que cambie; no toca el estado operativo ni la cotización (pregunta 19, decidida). Siguen abiertas 16, 17, 18 y 20: las cifras de capacidad y los umbrales son provisionales hasta Samuel.
Decidido · pestaña Contenedores · una silueta por caja · los cuatro estados
InformaciónContenedores 8BL y naviera 1Envíos 3SeguimientoPago
398,5 de 464 m³ · 86 % del flete · 153 m³ sin asignar
Vista lateral: puertas a la derecha, corrugado vertical, el nivel marcado con la cifra en marino. El relleno es una altura en porcentaje (--h);
el sobrante es un bloque rayado en rojo que asoma por encima del techo. Sin JavaScript: los estados son CSS.
Decidido · asignar una orden · la orden se apila como un bloque
3/8 MSCU8801240 · antes
40' HC · 68 m³
ORD-9127 · a · 28 m³
ORD-9127 · b · 13 m³
41 m³
41/ 68 m³ · 60 %En curso
3/8 MSCU8801240 · después
40' HC · 68 m³
ORD-9131 · 22 m³
ORD-9127 · a · 28 m³
ORD-9127 · b · 13 m³
ORD-9131 · 22 m³
63 m³
63/ 68 m³ · 93 %Casi lleno
Asignar ORD-9131 · Foshan Lumina · 175 m³ (22 en esta parte) · ¿a qué contenedor?
3/8 · MSCU8801240 · 40' HC41 → 63 de 68 · casi lleno
1/8 · MSCU5217340 · 40' HC41 → 63 de 68 · casi lleno
5/8 · pendiente · 40' HC0 → 22 de 68 · en curso
7/8 · MSDU2298168 · 20' DRY31,5 → 53,5 de 28 · sobre capacidad · pide motivo
Sobre capacidad nunca bloquea: pide un motivo, lo guarda en la asignación y deja el contenedor en rojo hasta que cambie. No toca el estado operativo ni la cotización. Decidido por Carlos el 22 sep (pregunta 19).
Propuesta · cabecera del flete · presupuesto de volumen
245,5 m³ asignados · 153 m³ sin asignar (ORD-9131) · 0 órdenes sin CBM2 casi llenos · 1 sobre capacidad · 3 vacíos
Regla
Propuesta
Qué CBM cuenta
Order.cbm (medido en recepción, el que ya suman los rollups) manda; si es null, Order.enteredCbm (declarado) como estimado, en tono claro y con «est.»; sin ninguno, la orden no llena nada y se cuenta como «sin CBM». En DECLARED, FreightCargoDeclaration.volumeM3 a nivel de flete.
Capacidad por equipo
Constante en packages/shared/src/fcl.ts, sin migración. Útil de planificación 28 · 58 · 68 m³ (nominal 33,2 · 67,7 · 76,4, fichas ISO 668). Cifras provisionales hasta que Samuel las confirme.
Con N contenedores
La orden llena el contenedor al que se asigna (OrderContainerAllocation + cbm). Entera por defecto; reparto opcional por m³. Lo no asignado se ve como bolsa a nivel de flete, nunca se reparte solo. Con N = 1 la asignación es implícita.
Umbrales
Vacío 0 · En curso < 85 % · Casi lleno 85–100 % · Sobre capacidad > 100 %. Mismos umbrales para el rollup del flete.
Sobre capacidad decidido
Aviso blando con motivo obligatorio; el rojo se queda. Nunca bloqueo duro, nunca afecta al estado del contenedor ni a la tarifa. Decisión de Carlos, 22 sep.
06BL y naviera: un documento que ampara ocho cajas
plan §4.3 · §5.2
El BL nace como booking cuando se elige la naviera y se completa con su número al zarpar: es el mismo registro.
Ampara 1..N contenedores del mismo flete; un contenedor solo puede estar en un BL. La naviera del BL se espeja a
Container.carrier para que la búsqueda global y el índice trigram sigan funcionando.
La factura comercial es una sola para el flete y vive donde ya vivía: Freight.invoiceFiles.
InformaciónContenedores 8BL y naviera 1Envíos 3SeguimientoPago
Un contenedor solo puede estar en un BL. Si el flete zarpa en dos buques, se crea un segundo BL y se reparten las casillas (pregunta 1).
Documentosdel flete
Factura comercial una para todo el flete
NúmeroINV-2026-0912
Cubre8 contenedores · 3 órdenes
ArchivoINV-2026-0912.pdf
Packing list
PL-huaxing.pdfPL-lumina.pdfPL-metalcraft.pdf
Cabecera del PDFGET /freights/:id/document
MG-FL-2481 · Contenedor completo 8 × 40' HC · Naviera MSC · BL MEDUGZ4471020 Tabla «Contenedores (8)» con referencia, número, equipo y BL.
07Proveedores: la orden sabe quién despacha, y desde dónde
plan §4.4 · §5.5 · fase 1
Es la pieza más pequeña y la primera: Order.supplierId opcional, y la ficha del proveedor gana ubicación propia
(ciudad, provincia, dirección, lat/long). No pasa por Address, que exige la geografía venezolana sembrada. El combobox ya existe
(supplier-combobox.tsx) y hoy solo lo usan cotizaciones y búsquedas. Aplica a LCL y AIR también: responde la misma pregunta en todos los modos.
Órdenes · Nueva orden · admin y client
Distribuidora Rondón C.A.
hua
CNYiwu Huaxing Commodity Co.Yiwu · 12 órdenes
CNHuaxing Plastics Ltd.Guangzhou · 2 órdenes
Crear proveedor «hua…» · nombre, país y ciudad
INV-2026-0912
42
Opcional y detrás de un flag en el client hasta validar el copy (R8). Las órdenes históricas quedan «sin proveedor».
Las métricas del proveedor (getMetrics) hoy solo cuentan opciones de sourcing; pasan a sumar órdenes. La asignación orden ↔ contenedor (qué proveedor va en qué caja) queda para la fase 4, si la pregunta 4 lo pide.
08Listas: las dos columnas donde se busca primero
plan §5.4
En /freights, «Prov.» y «Cont.» para filas FCL; LCL y AIR muestran «—» en Cont. y el filtro por naviera aplica a todos.
En /containers, las filas FCL dicen a qué flete pertenecen y en qué posición («3/8»), con la naviera y el filtro por BL.
/freights filtro · Naviera: MSC
Código
Cliente
Modo
Ruta
Prov.
Cont.
Naviera
Estado
Total
MG-FL-2481
Distribuidora Rondón
FCL
Shekou → La Guaira
3
8 · 5 id.
MSC
En tránsito
$22,100
MG-FL-2477
Ferretería El Cerro
FCL
Ningbo → Puerto Cabello
1
2
COSCO
Reserva
$5,600
MG-FL-2469
Importadora Vélez
LCL
Yiwu → La Guaira
2
—
MSC
Listo para retiro
$1,240
MG-FL-2452
Textiles Mara
AIR
Guangzhou → Caracas
1
—
—
Entregado
$880
/containers filtro · BL: MEDUGZ4471020
N° de contenedor
Flete
Naviera
BL
Origen
Destino
Salida
Estatus
MSCU5217340
MG-FL-2481 · 1/8
MSC
MEDUGZ4471020
Shekou
La Guaira
24 sep
En tránsito
MEDU7349126
MG-FL-2481 · 2/8
MSC
MEDUGZ4471020
Shekou
La Guaira
24 sep
En tránsito
MSCU8801240
MG-FL-2481 · 3/8
MSC
MEDUGZ4471020
Shekou
La Guaira
24 sep
Demorado
pendienteRSV-2026-0917-08
MG-FL-2481 · 5/8
MSC
MEDUGZ4471020
Shekou
La Guaira
—
Reserva
Búsqueda global: el número de BL y el nombre de la naviera entran en SearchService. La naviera ya está indexada en containers.carrier; por eso se espeja en vez de moverse.
09Decisiones, fases y lo que Carlos tiene que contestar
plan §4 · §7 · §8
Nada de esto se construye hasta que las preguntas tengan respuesta. La fase 1 es aditiva y responde ya la pregunta de los proveedores:
se propone arrancarla mientras se decide el resto.
Decisión de diseño
Por qué
Dos contadores fijos en la cabecera del flete
Son las dos preguntas de operaciones; van antes que el estado y la tarifa. Se repiten en listas, PDF y cliente.
Equipo como texto 6x40HQ + 2x20 + chips con stepper
La notación es la de Samuel; el stepper cubre a quien no la conoce. Se persiste por contenedor, nunca como texto.
Pegar números con validación por fila
Un BL trae ocho números; el error de uno no puede frenar los otros siete. Duplicado y dígito de control se explican en la fila.
Naviera = catálogo Carrier con creación en línea, espejada al contenedor
«La naviera importa»: catálogo para filtrar y buscar; espejo para no romper el índice trigram ni la búsqueda global.
Un BL con sus contenedores; una factura por flete
Hechos de Samuel. El BL nace como booking y se completa al zarpar. La factura ya vive en Freight.invoiceFiles.
Proveedor por orden y ubicación en la ficha del proveedor
Idea 1 de Carlos. Address exige geografía venezolana; una fábrica en Yiwu no cabe ahí.
«—» cuando no se sabe; «pendiente» en reservas
Regla del contrato v1: null es desconocido, nunca 0 por defecto.
Silueta en Contenedores + pila al asignar; sobrecapacidad con motivo y sin bloqueo decidido · 22 sep
Carlos: «me gusta una mezcla de estos dos». El llenado se lee de un vistazo, no en una cifra. Quedan provisionales la capacidad útil por equipo (28 · 58 · 68 m³), el CBM autoritativo y el umbral del 85 %.
Estado del flete = contenedor menos avanzado
Evita que el flete oscile cuando un contenedor avanza y otro retrocede. Incidencias como badge, no como estado.
1
Proveedor–orden
Order.supplierId, ubicación en Supplier, supplierCount en la declaración, combobox en órdenes, contador Proveedores.
solo aditivo · preguntas 9, 11, 15
2
N contenedores
Container.freightId, equipo por contenedor, trigger v2, parser 8x40HQ, pestaña Contenedores, pegar números, tarifa por tipo, PDF con tabla.
preguntas 2, 3, 8, 10, 13, 14
3
BL y naviera
Carrier + BillOfLading, espejo al contenedor, pestaña BL, filtros, búsqueda, PDF, cliente y notificación.
preguntas 1, 5, 6, 12
4
Orden ↔ contenedor
OrderContainerAllocation con cbm: qué órdenes van dentro de cada caja y cuánto la llenan. Deja de ser opcional si el llenado se quiere con N > 1.
preguntas 4, 20 · 19 decidida
5
Aceptación v2
Concurrencia con N contenedores, no regresión LCL/AIR, QA visual es/en/zh, evidencia bajo verification/v2/.
cierra 2–4
¿Un flete puede repartir contenedores en varios zarpes / BL? Este diseño lo permite. Si siempre es un zarpe, el BL cuelga del flete.
¿Vínculo en el contenedor (C) o tabla de unión (B)?recomendado C
Estado del flete con N contenedores: ¿el menos avanzado? ¿DELIVERED exige todos?recomendado mínimo
¿Hace falta saber qué proveedor va en qué caja o bastan los dos conteos?
Lista inicial de navieras y quién puede crear una desde el combobox.
¿Solo MBL o también HBL? ¿El booking se captura en el mismo registro?
Factura única: ¿en Freight.invoiceFiles con órdenes opcionales, o una orden por proveedor?
Alias de notación además de 40HQ (40HC, 40'HC, 20GP, 40DV). ¿Reefer y open top se rechazan con mensaje?
Proveedores en DECLARED: ¿basta el conteo o hay que nombrarlos?
Tope por alta: propuesta 60. ¿Casos reales por encima?
Ubicación del proveedor: ¿pin manual, geocodificación automática o solo texto? ¿Para qué se usará lat/long?
Visibilidad al cliente: ¿ve BL, naviera, buque y estado por contenedor? ¿Ve el nombre de sus proveedores?
Reutilización de un número físico en un viaje nuevo: v1 lo prohíbe. ¿Se reabre?
Tarifa: ¿una fila base por tipo con cantidad, o una sola fila con importe total?recomendado por tipo
¿Autorizas arrancar la fase 1 mientras se deciden las demás?
CBM autoritativo: ¿Order.cbm medido manda y enteredCbm solo estima, o al revés hasta que la orden llegue al almacén? ¿Y una orden sin ninguno?recomendado cbm
Tabla de capacidades: ¿valen 28 · 58 · 68 m³ útiles (nominal 33,2 · 67,7 · 76,4) o operaciones planifica con otras? ¿Override por contenedor?
Umbral de «casi lleno»: ¿85 % o 90 %? ¿Distinto para el 20'?recomendado 85
Sobre capacidad: aviso blando con motivo obligatorio, sin bloqueo; el rojo se queda hasta que la asignación cambie.decidida · 22 sep
Reparto de una orden entre contenedores: ¿entera por defecto con reparto opcional por m³, o siempre entera? ¿El «sin asignar» lo ve el cliente?
Lo que no se propone — conversión FCL↔LCL, equipos especiales (reefer, open top, flat rack), mercancía peligrosa, demoras automáticas, integración API con navieras, cambios estructurales a QuotationLineItem. Todo sigue fuera de alcance como en v1.
Lo que se conserva de v1 — idempotencia, outbox, versiones optimistas, pricingState, evidencias por contenedor, FCL_PENDING. Se reutiliza por contenedor sin tocarlo.
Un flete, un cliente, una factura. Ocho contenedores.
Tres proveedores y ocho cajas se leen en la cabecera antes de abrir nada. La notación de operaciones entra tal cual se escribe,
los números se pegan en bloque, la naviera se elige, el BL sabe qué ampara y cada caja muestra cuánto le cabe todavía. Cinco fases; la primera, sin riesgo.