# Schema Nickel para `inventory` (Stock + MovimientoStock + TransferenciaStock).

let positive_int = std.contract.from_predicate (fun n =>
  std.is_number n && n > 0
) in

let non_negative_int = std.contract.from_predicate (fun n =>
  std.is_number n && n >= 0
) in

let non_empty_string = std.contract.from_predicate (fun s =>
  std.is_string s && std.string.length s > 0
) in

let razon_movimiento = std.contract.from_predicate (fun s =>
  std.is_string s && std.array.elem s ["recepcion", "despacho", "ajuste"]
) in

let non_zero_int = std.contract.from_predicate (fun n =>
  std.is_number n && n != 0
) in

{
  Stock = {
    id | String,
    sku_id | non_empty_string,
    ubicacion | non_empty_string,
    cantidad | non_negative_int,
  },

  MovimientoStock = {
    id | String,
    stock_id | String,
    delta | non_zero_int,
    razon | razon_movimiento,
    timestamp | String,
  },

  # Patrón obligatorio para record + cross-field predicate: chain
  # via Sequence (aplicar `from_predicate` directo al record rebota
  # con "missing definition").
  TransferenciaStock = std.contract.Sequence [
    {
      id | String,
      source_stock_id | String,
      dest_stock_id | String,
      sku_id | non_empty_string,
      cantidad | positive_int,
      timestamp | String,
    },
    std.contract.from_predicate (fun r =>
      r.source_stock_id != r.dest_stock_id
    ),
  ],
}
