chore: absorbe nakui (ERP matemático) en modules/nakui

- crates/modules/nakui/core/: el crate nakui-core (4 bins, tests).
  Deps directas (serde, rhai, surrealdb, petgraph, sha2, uuid, tokio,
  thiserror v1) — no convertidas a workspace = true en esta pasada.
- crates/modules/nakui/modules/{inventory,sales,treasury}/: datos
  declarativos del dominio (nsmc.json, schema.k, morphisms/) que el
  crate consume — no son crates.

cargo check -p nakui-core: 0 errores.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-05-08 05:49:58 +00:00
parent 53dbdf0f1d
commit 4d50bfc587
49 changed files with 11953 additions and 40 deletions
@@ -0,0 +1,52 @@
// vender
// Cross-module morphism: decreases Stock (inventory) and increases Caja
// (treasury). NOT conservation-bound — a sale is asymmetric: units leave
// the system, money enters. The kernel validates each entity against its
// own schema (Stock from inventory, Caja from treasury, Venta from sales).
//
// states.stock: the Stock record (inventory module).
// states.caja: the Caja record (treasury module).
// params: { cantidad:i64, precio_unitario:i64 (en centavos),
// timestamp:str, venta_id:str }
let cantidad = input.params.cantidad;
let precio = input.params.precio_unitario;
let venta_id = input.params.venta_id;
if cantidad <= 0 { throw "cantidad debe ser positiva" }
if precio <= 0 { throw "precio_unitario debe ser positivo" }
if type_of(venta_id) == "()" { throw "params.venta_id es obligatorio (idempotencia)" }
let stock = input.states.stock;
let caja = input.states.caja;
let total = cantidad * precio;
[
#{
op: "set",
path: #{ entity: "Stock", id: input.ids.stock, field: "cantidad" },
value: stock.cantidad - cantidad,
},
#{
op: "set",
path: #{ entity: "Caja", id: input.ids.caja, field: "saldo" },
value: caja.saldo + total,
},
#{
op: "create",
entity: "Venta",
id: venta_id,
data: #{
id: venta_id,
stock_id: input.ids.stock,
caja_id: input.ids.caja,
sku_id: stock.sku_id,
cantidad: cantidad,
precio_unitario: precio,
currency: caja.currency,
total: total,
timestamp: input.params.timestamp,
},
},
]
@@ -0,0 +1,21 @@
{
"module": "sales",
"schemas": [
"schema.k",
"../treasury/schema.k",
"../inventory/schema.k"
],
"morphisms": [
{
"name": "vender",
"inputs": [
{ "role": "stock", "entity": "Stock" },
{ "role": "caja", "entity": "Caja" }
],
"reads": ["stock.cantidad", "stock.sku_id", "caja.saldo", "caja.currency"],
"writes": ["stock.cantidad", "caja.saldo", "Venta"],
"depends_on": [],
"script": "morphisms/vender.rhai"
}
]
}
@@ -0,0 +1,16 @@
schema Venta:
id: str
stock_id: str
caja_id: str
sku_id: str
cantidad: int
precio_unitario: int
currency: str
total: int
timestamp: str
check:
cantidad > 0, "cantidad positiva"
precio_unitario > 0, "precio_unitario positivo"
len(currency) == 3, "currency ISO 4217"
total == cantidad * precio_unitario, "total debe ser cantidad * precio_unitario"