Volver a plantillas

Inventario

operations

Controle productos, niveles de stock y movimientos entre ubicaciones.

Colecciones

Products

Product catalog

Campos del esquema

name:stringsku:stringcategory:stringunit_cost:numberunit_price:numbermin_stock:numberactive:boolean

Stock Movements

Inbound and outbound stock changes

Campos del esquema

type:stringquantity:numberreason:stringreference:stringtimestamp:string

Locations

Warehouses and storage locations

Campos del esquema

name:stringaddress:stringtype:stringcapacity:number

Relaciones

stock_movements
for_product
productsMovement for product
stock_movements
at_location
locationsMovement at location
products
stored_at
locationsProduct stored at location

Consultas de ejemplo

Consulte los datos de esta plantilla usando el endpoint SQL.

Current stock levels

Calculate net stock per product by summing inbound and outbound movements.

WITH
  movements AS (
    SELECT
      target_id as product_id,
      source_id as movement_id
    FROM relationships FINAL
    WHERE workspace_id = {workspace_id:String}
      AND rel_type = 'for_product'
      AND deleted = false
  ),
  quantities AS (
    SELECT
      m.product_id,
      sum(CASE
        WHEN r.data.type.:String IN ('inbound', 'adjustment') THEN CAST(r.data.quantity, 'Float64')
        WHEN r.data.type.:String = 'outbound' THEN -CAST(r.data.quantity, 'Float64')
        ELSE 0
      END) as net_stock
    FROM movements m
    JOIN records r FINAL ON r.id = m.movement_id
      AND r.workspace_id = {workspace_id:String}
      AND r.deleted = false
    GROUP BY m.product_id
  )
SELECT
  p.data.name.:String as product,
  p.data.sku.:String as sku,
  coalesce(q.net_stock, 0) as stock,
  CAST(p.data.min_stock, 'Float64') as min_stock
FROM records p FINAL
LEFT JOIN quantities q ON q.product_id = p.id
WHERE p.workspace_id = {workspace_id:String}
  AND p.collection = 'products'
  AND p.deleted = false
ORDER BY stock ASC

Movement history

List recent stock movements with type and quantity.

SELECT
  data.type.:String as movement_type,
  CAST(data.quantity, 'Float64') as quantity,
  data.reason.:String as reason,
  data.reference.:String as reference,
  data.timestamp.:String as timestamp
FROM records FINAL
WHERE workspace_id = {workspace_id:String}
  AND collection = 'stock_movements'
  AND deleted = false
ORDER BY data.timestamp.:String DESC

Inventory value by category

Total inventory value grouped by product category using unit cost.

SELECT
  data.category.:String as category,
  count() as product_count,
  sum(CAST(data.unit_cost, 'Float64')) as total_cost,
  sum(CAST(data.unit_price, 'Float64')) as total_price
FROM records FINAL
WHERE workspace_id = {workspace_id:String}
  AND collection = 'products'
  AND deleted = false
  AND data.active.:Bool = true
GROUP BY category
ORDER BY total_price DESC

Inicio rápido

Cree las colecciones usando el Rekor CLI:

rekor collections upsert products --workspace my-inventory --schema @products.json

Esquema completo (JSON)

Copie la definición completa de la plantilla:

{
  "collections": [
    {
      "id": "products",
      "name": "Products",
      "description": "Product catalog",
      "icon": "box",
      "color": "#8b5cf6",
      "json_schema": {
        "type": "object",
        "required": [
          "name",
          "sku"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "sku": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "unit_cost": {
            "type": "number",
            "minimum": 0
          },
          "unit_price": {
            "type": "number",
            "minimum": 0
          },
          "min_stock": {
            "type": "number",
            "minimum": 0
          },
          "active": {
            "type": "boolean",
            "default": true
          }
        }
      }
    },
    {
      "id": "stock_movements",
      "name": "Stock Movements",
      "description": "Inbound and outbound stock changes",
      "icon": "arrow-right-left",
      "color": "#22c55e",
      "json_schema": {
        "type": "object",
        "required": [
          "type",
          "quantity"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "inbound",
              "outbound",
              "adjustment",
              "transfer"
            ]
          },
          "quantity": {
            "type": "number"
          },
          "reason": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    {
      "id": "locations",
      "name": "Locations",
      "description": "Warehouses and storage locations",
      "icon": "map-pin",
      "color": "#f59e0b",
      "json_schema": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "warehouse",
              "store",
              "dropship"
            ]
          },
          "capacity": {
            "type": "number"
          }
        }
      }
    }
  ],
  "relationships": [
    {
      "type": "for_product",
      "source": "stock_movements",
      "target": "products",
      "description": "Movement for product"
    },
    {
      "type": "at_location",
      "source": "stock_movements",
      "target": "locations",
      "description": "Movement at location"
    },
    {
      "type": "stored_at",
      "source": "products",
      "target": "locations",
      "description": "Product stored at location"
    }
  ]
}