[TERMINAL · SKILLS]
> mounting /skills...
> indexing skill manifests...
> linking agents: claude · codex · gemini · cursor
> ready.
[░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
Use Cases/Build a Warehouse Inventory System

Build a Warehouse Inventory System

Build a warehouse management system with real-time stock tracking, bin location management, pick/pack/ship workflows, low-stock alerts, and multi-warehouse synchronization.

Development#typescript#tsconfig#type-checking#type-safety#javascript-migration
Works with:claude-codeopenai-codexgemini-clicursor

Skills stack · 5 skills

Avg quality 96/100·All SAFE
>

typescript

v1.0.0

Sets up and repairs TypeScript projects: picks tsconfig.json settings for a Node.js service, an npm library or a bundled web app, runs type-checking in CI, and replaces `any` and unsafe casts with types the compiler can verify. Use when someone asks to "set up TypeScript", "fix this tsconfig", "fix a TypeScript error", "upgrade to TypeScript 6 or 7", "migrate JavaScript to TypeScript", "publish types for a package", "run .ts files in Node" or "make this type-safe". Covers the changed defaults in TypeScript 6.0 and 7.0, module and moduleResolution, strict mode, project references, declaration output, narrowing, satisfies and common compiler errors.

93/100 quality
7.30× impact
SAFE· stale score
View skill
>

redis

v1.1.0

Redis is an in-memory data store used as a cache, session store, message broker and counter service. Use when adding a cache layer, storing sessions, rate limiting an API, running pub/sub or Streams with consumer groups, taking a distributed lock, building a leaderboard, or configuring Redis for production (persistence, maxmemory, eviction).

93/100 quality
1.79× impact
SAFE· stale score
View skill
>

postgresql

v1.1.0

Assists with designing schemas, writing performant queries, managing indexes, and operating PostgreSQL databases. Use when working with JSONB, full-text search, window functions, CTEs, row-level security, replication, or performance tuning. Trigger words: postgresql, postgres, sql, database, jsonb, rls, window functions, cte.

100/100 quality
5.15× impact
SAFE· stale score
View skill
>

hono

v1.1.0

Hono is a small web framework built on Web Standards (Request/Response) that runs unchanged on Cloudflare Workers, Deno, Bun, Node.js, AWS Lambda and Vercel. Use it when the user asks to build a Hono API, add Zod validation, JWT auth, CORS or middleware, use the type-safe RPC client (hc), render JSX, stream responses, or deploy one codebase to several runtimes.

100/100 quality
6.20× impact
SAFE· stale score
View skill
>

zod

v1.1.0

Zod is a TypeScript-first schema library that validates data at runtime and infers static types from the same schema. Use when validating API request bodies, form input, environment variables or config files, parsing untrusted JSON, or migrating from Zod 3 to Zod 4. Covers z.object, safeParse, z.infer, coercion, discriminated unions, refinements, JSON Schema output and the v4 API changes.

93/100 quality
3.87× impact
SAFE· stale score
View skill
$

The Problem

Carmen manages operations at a 30-person e-commerce company with 2 warehouses and 8,000 SKUs. Inventory is tracked in spreadsheets synced twice daily. Yesterday they oversold 200 units of a popular item — stock showed 300 but only 100 were actually available (the rest were allocated to pending orders). Returns sit in a pile for days because nobody updates stock counts. They lose $25K/month from overselling, dead stock, and misplaced items. They need real-time inventory with stock reservations, bin locations, and automated reorder alerts.

Step 1: Build the Inventory Engine

typescript
// src/warehouse/inventory.ts — Real-time inventory with reservations, bin locations, and multi-warehouse
import { pool } from "../db";
import { Redis } from "ioredis";

const redis = new Redis(process.env.REDIS_URL!);

interface InventoryItem {
  sku: string;
  name: string;
  warehouseId: string;
  binLocation: string;         // e.g., "A-03-12" (aisle-rack-shelf)
  quantityOnHand: number;
  quantityReserved: number;    // allocated to pending orders
  quantityAvailable: number;   // onHand - reserved
  quantityInbound: number;     // purchase orders in transit
  reorderPoint: number;
  reorderQuantity: number;
  lastCountedAt: string;
  updatedAt: string;
}

type MovementType = "receive" | "ship" | "transfer" | "adjust" | "return" | "damage" | "cycle_count";

interface StockMovement {
  id: string;
  sku: string;
  warehouseId: string;
  type: MovementType;
  quantity: number;            // positive = in, negative = out
  referenceId: string;         // order ID, PO number, etc.
  binFrom: string | null;
  binTo: string | null;
  userId: string;
  notes: string;
  createdAt: string;
}

// Reserve stock for an order (atomic operation)
export async function reserveStock(
  items: Array<{ sku: string; quantity: number }>,
  orderId: string,
  warehouseId?: string
): Promise<{ success: boolean; errors: string[]; reservations: Array<{ sku: string; warehouseId: string; quantity: number }> }> {
  const errors: string[] = [];
  const reservations: Array<{ sku: string; warehouseId: string; quantity: number }> = [];

  const client = await pool.connect();
  try {
    await client.query("BEGIN");

    for (const item of items) {
      // Lock the row for update
      const { rows } = await client.query(
        `SELECT warehouse_id, quantity_on_hand, quantity_reserved, bin_location
         FROM inventory WHERE sku = $1 ${warehouseId ? "AND warehouse_id = $2" : ""}
         ORDER BY (quantity_on_hand - quantity_reserved) DESC
         FOR UPDATE`,
        warehouseId ? [item.sku, warehouseId] : [item.sku]
      );

      let remaining = item.quantity;
      for (const row of rows) {
        const available = row.quantity_on_hand - row.quantity_reserved;
        if (available <= 0) continue;

        const toReserve = Math.min(remaining, available);
        await client.query(
          `UPDATE inventory SET quantity_reserved = quantity_reserved + $3, updated_at = NOW()
           WHERE sku = $1 AND warehouse_id = $2`,
          [item.sku, row.warehouse_id, toReserve]
        );

        reservations.push({ sku: item.sku, warehouseId: row.warehouse_id, quantity: toReserve });
        remaining -= toReserve;
        if (remaining <= 0) break;
      }

      if (remaining > 0) {
        errors.push(`Insufficient stock for ${item.sku}: need ${item.quantity}, can reserve ${item.quantity - remaining}`);
      }
    }

    if (errors.length > 0) {
      await client.query("ROLLBACK");
      return { success: false, errors, reservations: [] };
    }

    // Store reservation for release if order is cancelled
    await client.query(
      `INSERT INTO stock_reservations (order_id, items, created_at) VALUES ($1, $2, NOW())`,
      [orderId, JSON.stringify(reservations)]
    );

    await client.query("COMMIT");

    // Update Redis cache
    for (const res of reservations) {
      await updateCachedStock(res.sku, res.warehouseId);
    }

    // Check reorder points
    for (const item of items) {
      await checkReorderPoint(item.sku);
    }

    return { success: true, errors: [], reservations };
  } catch (err) {
    await client.query("ROLLBACK");
    throw err;
  } finally {
    client.release();
  }
}

// Release reservation (order cancelled)
export async function releaseReservation(orderId: string): Promise<void> {
  const { rows: [reservation] } = await pool.query(
    "SELECT items FROM stock_reservations WHERE order_id = $1", [orderId]
  );
  if (!reservation) return;

  const items: Array<{ sku: string; warehouseId: string; quantity: number }> = JSON.parse(reservation.items);
  for (const item of items) {
    await pool.query(
      `UPDATE inventory SET quantity_reserved = GREATEST(quantity_reserved - $3, 0), updated_at = NOW()
       WHERE sku = $1 AND warehouse_id = $2`,
      [item.sku, item.warehouseId, item.quantity]
    );
    await updateCachedStock(item.sku, item.warehouseId);
  }

  await pool.query("DELETE FROM stock_reservations WHERE order_id = $1", [orderId]);
}

// Receive stock (from purchase order or return)
export async function receiveStock(
  sku: string,
  warehouseId: string,
  quantity: number,
  binLocation: string,
  referenceId: string,
  type: "receive" | "return" = "receive",
  userId: string
): Promise<void> {
  await pool.query(
    `INSERT INTO inventory (sku, warehouse_id, bin_location, quantity_on_hand, quantity_reserved, reorder_point, reorder_quantity, updated_at)
     VALUES ($1, $2, $3, $4, 0, 10, 50, NOW())
     ON CONFLICT (sku, warehouse_id)
     DO UPDATE SET quantity_on_hand = inventory.quantity_on_hand + $4, bin_location = $3, updated_at = NOW()`,
    [sku, warehouseId, binLocation, quantity]
  );

  await recordMovement(sku, warehouseId, type, quantity, referenceId, null, binLocation, userId, "");
  await updateCachedStock(sku, warehouseId);

  // Update inbound quantity if receiving a PO
  if (type === "receive") {
    await pool.query(
      `UPDATE inventory SET quantity_inbound = GREATEST(quantity_inbound - $3, 0) WHERE sku = $1 AND warehouse_id = $2`,
      [sku, warehouseId, quantity]
    );
  }
}

// Ship stock (fulfill order)
export async function shipStock(
  items: Array<{ sku: string; warehouseId: string; quantity: number }>,
  orderId: string,
  userId: string
): Promise<void> {
  for (const item of items) {
    await pool.query(
      `UPDATE inventory SET
         quantity_on_hand = quantity_on_hand - $3,
         quantity_reserved = GREATEST(quantity_reserved - $3, 0),
         updated_at = NOW()
       WHERE sku = $1 AND warehouse_id = $2`,
      [item.sku, item.warehouseId, item.quantity]
    );

    await recordMovement(item.sku, item.warehouseId, "ship", -item.quantity, orderId, null, null, userId, "");
    await updateCachedStock(item.sku, item.warehouseId);
  }

  await pool.query("DELETE FROM stock_reservations WHERE order_id = $1", [orderId]);
}

// Transfer between warehouses
export async function transferStock(
  sku: string,
  fromWarehouse: string,
  toWarehouse: string,
  quantity: number,
  userId: string
): Promise<void> {
  const client = await pool.connect();
  try {
    await client.query("BEGIN");

    // Deduct from source
    await client.query(
      `UPDATE inventory SET quantity_on_hand = quantity_on_hand - $3, updated_at = NOW()
       WHERE sku = $1 AND warehouse_id = $2 AND quantity_on_hand - quantity_reserved >= $3`,
      [sku, fromWarehouse, quantity]
    );

    // Add to destination
    await client.query(
      `INSERT INTO inventory (sku, warehouse_id, quantity_on_hand, updated_at)
       VALUES ($1, $2, $3, NOW())
       ON CONFLICT (sku, warehouse_id)
       DO UPDATE SET quantity_on_hand = inventory.quantity_on_hand + $3, updated_at = NOW()`,
      [sku, toWarehouse, quantity]
    );

    await client.query("COMMIT");
  } catch (err) {
    await client.query("ROLLBACK");
    throw err;
  } finally {
    client.release();
  }

  await recordMovement(sku, fromWarehouse, "transfer", -quantity, `transfer-to-${toWarehouse}`, null, null, userId, "");
  await recordMovement(sku, toWarehouse, "transfer", quantity, `transfer-from-${fromWarehouse}`, null, null, userId, "");
}

// Get real-time stock across all warehouses
export async function getStockLevel(sku: string): Promise<{
  total: { onHand: number; reserved: number; available: number; inbound: number };
  warehouses: Array<{ warehouseId: string; onHand: number; reserved: number; available: number; binLocation: string }>;
}> {
  // Try cache first
  const cached = await redis.get(`stock:${sku}`);
  if (cached) return JSON.parse(cached);

  const { rows } = await pool.query(
    `SELECT warehouse_id, quantity_on_hand, quantity_reserved, quantity_inbound, bin_location
     FROM inventory WHERE sku = $1`, [sku]
  );

  const warehouses = rows.map((r: any) => ({
    warehouseId: r.warehouse_id,
    onHand: r.quantity_on_hand,
    reserved: r.quantity_reserved,
    available: r.quantity_on_hand - r.quantity_reserved,
    binLocation: r.bin_location || "",
  }));

  const total = {
    onHand: warehouses.reduce((s, w) => s + w.onHand, 0),
    reserved: warehouses.reduce((s, w) => s + w.reserved, 0),
    available: warehouses.reduce((s, w) => s + w.available, 0),
    inbound: rows.reduce((s: number, r: any) => s + (r.quantity_inbound || 0), 0),
  };

  const result = { total, warehouses };
  await redis.setex(`stock:${sku}`, 30, JSON.stringify(result)); // 30s cache
  return result;
}

async function checkReorderPoint(sku: string): Promise<void> {
  const { rows } = await pool.query(
    `SELECT warehouse_id, quantity_on_hand, quantity_reserved, reorder_point, reorder_quantity
     FROM inventory WHERE sku = $1`, [sku]
  );

  for (const row of rows) {
    const available = row.quantity_on_hand - row.quantity_reserved;
    if (available <= row.reorder_point) {
      const alertKey = `stock:alert:${sku}:${row.warehouse_id}`;
      const alerted = await redis.get(alertKey);
      if (!alerted) {
        await redis.setex(alertKey, 86400, "1");
        await redis.rpush("notification:queue", JSON.stringify({
          type: "low_stock", sku, warehouseId: row.warehouse_id,
          available, reorderPoint: row.reorder_point, suggestedOrder: row.reorder_quantity,
        }));
      }
    }
  }
}

async function updateCachedStock(sku: string, warehouseId: string): Promise<void> {
  await redis.del(`stock:${sku}`);
}

async function recordMovement(
  sku: string, warehouseId: string, type: MovementType, quantity: number,
  referenceId: string, binFrom: string | null, binTo: string | null,
  userId: string, notes: string
): Promise<void> {
  await pool.query(
    `INSERT INTO stock_movements (sku, warehouse_id, type, quantity, reference_id, bin_from, bin_to, user_id, notes, created_at)
     VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, NOW())`,
    [sku, warehouseId, type, quantity, referenceId, binFrom, binTo, userId, notes]
  );
}

Results

  • Overselling eliminated — atomic stock reservations with row-level locking; 200-unit oversell incidents dropped to zero
  • Returns processed same day — receiveStock with type "return" updates inventory instantly; returned items are available for sale within minutes
  • $25K/month losses recovered — real-time tracking + reservations + reorder alerts; no more dead stock or phantom inventory
  • Multi-warehouse fulfillment — orders automatically pull from the warehouse with most available stock; inter-warehouse transfers tracked with full audit trail
  • Bin location mapping — warehouse staff find items in seconds (aisle A, rack 3, shelf 12); pick time reduced 40%

Related use cases