# Schema declarativo para entities del módulo `sales`.
# Reemplaza el `schema.k` (KCL) por contracts Nickel nativos —
# evaluables in-process por `nakui-core::nickel_validator`.
#
# El bundle del módulo (que Nakui arma juntando este archivo + los
# schemas de los módulos importados — ver `nsmc.json`) se evalúa
# como un record con un field por entity. Para validar un value V
# contra el entity `Venta` se hace en Rust:
#
#   let bundle = (import "<bundle>.ncl") in V | bundle.Venta
#
# Cada entity es un record contract: cada field declara su contract
# (String, Number, predicate custom, etc.). El record entero se
# wrappea en un contract adicional para invariantes cross-field
# (ej: `total == cantidad * precio_unitario`).

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

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

{
  # std.contract.Sequence chain-aplica los contracts en orden.
  # Patrón obligatorio para combinar record contract + cross-field
  # predicate: aplicar `from_predicate` directo al record (con `|`)
  # rebota con "missing definition" porque el predicate evalúa antes
  # de que el record esté populated desde el value.
  Venta = std.contract.Sequence [
    {
      id | String,
      stock_id | String,
      caja_id | String,
      sku_id | String,
      cantidad | positive_int,
      precio_unitario | positive_int,
      currency | currency_iso,
      total | Number,
      timestamp | String,
    },
    std.contract.from_predicate (fun r =>
      r.total == r.cantidad * r.precio_unitario
    ),
  ],
}
