ℹ️ What is this system? — click to learn

The WIP Manufacturing Blockchain is a traceability system that records every production event — inventory movements, work-in-progress operations, and production order confirmations — as immutable blocks in a cryptographic chain.

Each time you receive material, transfer stock, start an operation, or complete production, a new block is mined using SHA-256 hashing. No record can ever be modified or deleted without breaking the chain — making this system suitable for compliance-critical environments (pharmaceutical, aerospace, automotive, medical devices).

Blocks in Chain
Total number of mined blockchain blocks since system start.
Active WIP
Items currently being processed on the shop floor.
Chain Valid
Green = all hashes are intact. Red = data tampering detected.
Inventory Movements
Total receipts, transfers, issues, and adjustments recorded.
Loading stats…
📈 Inventory Movements (Latest 20)
🔄 Orders by Status
📦 Stock by Location
Loading…
⚡ Recent Transactions
Loading…
ℹ️ How do Production Orders work?

A Production Order is the authorization to manufacture a specific product. It defines what to produce, how many units, and at what priority.

Each order goes through stages: Created → In Progress → Completed. Every status change is recorded as an immutable transaction on the blockchain.

ERP Ref
Optional optional link to an external ERP order number (e.g. OR-1000123) for future ERP integration.
Cost Center
The manufacturing cost center charged for this order (e.g. CC-ELECT-01).
Priority
LOW / NORMAL / HIGH / URGENT — used for visual identification on the shop floor.
Operations
Work steps within the order (e.g. SMT Assembly, AOI Inspection). Each is individually tracked.
➕ New Production Order
📋 All Orders
Loading…
ℹ️ Understanding WIP Tracking

WIP (Work-In-Progress) refers to material that has left the warehouse and is currently being transformed into a finished product. The WIP Board shows the real-time location and status of every in-process batch.

When you start an operation on a production order, a WIP item is automatically created. As the batch moves between work centers, each movement is recorded on the blockchain with timestamp, origin, destination, and the operator's name.

IN_PROGRESS
Operation currently running at this work center.
COMPLETED
Operation finished. Yield and scrap quantities confirmed.
Move WIP
Transfer a batch to another work center. Each move is a blockchain event.
Complete Operation
Close the operation. Record yield (good units) and scrap (defective units).
📍 Move WIP Item
Transfer a WIP batch to a different work center. A blockchain event is recorded with from/to/operator.
✅ Complete Operation
Close an operation by recording the yield (good units produced) and scrap quantity.
🔧 Active WIP Items
Loading…
ℹ️ Inventory Management on the Blockchain

Every inventory movement — from supplier receipt to production floor consumption — is recorded as a blockchain transaction. This creates an unbreakable audit trail that proves the origin, quantity, and handling of every material.

Goods Receipt
Register incoming material from a supplier. Adds stock to the specified warehouse location.
Transfer
Move stock between locations (e.g. warehouse → production line). Validates sufficient stock before recording.
Issue to Order
Consume material from a production order. Reduces stock at the source location.
Adjustment
Physical count correction. Sets the absolute quantity. All adjustments are permanently recorded.
📥 Record Inventory Movement
Mvt 101 — Receive material from supplier into a warehouse location.
📊 Current Stock Levels
Loading…
📦 All Inventory Items
Loading…
📥 Post Goods Receipt — Mvt 101
📊 Recent Goods Receipts
Loading…
🏭 Post Transfer — Mvt 311
📦 Current Production Stock Levels
Loading…
📤 Post Goods Issue — Mvt 261
⚡ Bulk Issue — All BOM Components
Load the BOM for the order's product and issue all components at once.
📋 Open Production Orders
Loading…
🔍 Select Production Order
⚙️ Operation Control
Start, pause, or end a manufacturing operation directly. Each action creates an immutable blockchain record.
📜 Confirmation History
Loading…
📦 Post Production GR — Mvt 101
📋 Deliverable Orders
Orders with confirmed operations, ready for goods receipt.
Loading…
🔬 Record Inspection Result
📜 Inspection History
Loading…
➕ Create Work Center
⚙️ All Work Centers
Loading…
➕ Create Routing
Operations Sequence
Add operations in sequence. Op number format: 0010, 0020, 0030 … (multiples of 10). Each operation maps to one work center.
📋 All Routings
Loading…
ℹ️ What is the Audit Trail?

The Audit Trail is the complete, chronological log of every event recorded in the blockchain. Unlike traditional databases, this log cannot be modified or deleted — any attempt would break the SHA-256 hash chain, which is immediately detectable.

This makes the system suitable for compliance requirements such as GMP 21 CFR Part 11 (pharma), AS9100 (aerospace), IATF 16949 (automotive), and ISO 13485 (medical devices).

Each transaction shows its Block Index (which block it belongs to) and Block Hash (the cryptographic fingerprint of that block).

Filter by type:
📜 Transactions
Loading…
ℹ️ Understanding SHA-256 Blockchain

Each block contains a batch of transactions and is secured by a SHA-256 hash calculated from its content plus the previous block's hash — forming an unbreakable chain.

Proof-of-Work (difficulty=2): every hash starts with 00… — achieved by trying different nonce values until the condition is met. Forging any record would require re-mining every block that follows it.

🔐 Hash
SHA-256 fingerprint of this block. Starts with "00" (Proof-of-Work).
🔗 Prev Hash
Points to the previous block. Breaking this link invalidates the whole chain.
🔢 Nonce
The number iterated until the hash met the difficulty requirement.
✅ Chain Valid
Every block's hash is correct AND every prev-hash link is intact.
Loading…
View:
Loading chain…
ℹ️ ERP Integration Overview

The ERP Bridge exports blockchain records as ERP export (Intermediate Document) structures — the standard format used by ERP for data exchange. These can be imported into ERP PP (Production Planning) and ERP MM (Materials Management).

LOIPRO01
Production Order export format (LOIPRO01). Used to create/confirm production orders in ERP PP via CO01/CO11N transactions.
MBGMCR02
Goods Movement export format (MBGMCR02). Used to post inventory movements in ERP MM via MIGO transaction (movement types 101, 261, 311).
Blockchain Hash in IDOC
The blockchain hash is embedded in the IDOC so the ERP system can cross-reference the exact blockchain block that originated the document.
Next Steps
For ERP system integration: configure ERP integration endpoints as appropriate for your system.
🏭 ERP PP Production Order IDOC — LOIPRO01
Click "Export IDOC" to generate ERP structure.
📦 ERP MM Goods Movement IDOC — MBGMCR02
Click "Export IDOC" to generate ERP structure.
📋 All Orders (for IDOC export)
Loading…
➕ New Material
📋 Registered Materials
Loading…
➕ Create / Update BOM
Components
📋 Registered BOMs
Loading…
💥 BOM Explosion
📋 Material List
Loading…

🏭 System Overview

WIP Manufacturing Blockchain is a shop-floor traceability system that records every production event — inventory movements, work-order operations, goods receipts, and confirmations — as immutable blocks in a SHA-256 cryptographic chain.

Each block is mined with Proof-of-Work (difficulty = 2 leading zeros). Once written, no record can be modified without breaking every subsequent hash, making tampering instantly detectable. The system is designed for compliance-critical industries: pharmaceutical, aerospace, automotive (IATF 16949), medical devices (ISO 13485), and food & beverage (FSMA / HACCP).

Tech Stack

Backend: Node.js + Express.js — RESTful API server
Blockchain core: Custom SHA-256 chain (blockchain.js) with PoW mining
Optional anchor: ethers.js v6 for Ethereum Sepolia testnet anchoring
Persistence: JSON files in data/ directory, saved after every block
Auth: HTTP Basic Auth + SHA-256 password hashing, roles: admin / operator
Frontend: Vanilla HTML/CSS/JS + Chart.js 4.4
Containerization: Docker + docker-compose with named volume

Key Files

server.js            — Express API + route handlers + seed data
blockchain.js        — SHA-256 chain, PoW mining, transaction types
blockchain-ethereum.js — Optional Sepolia anchoring (ethers v6)
user-manager.js      — Multi-user auth, password hashing
material-master.js   — Material, BOM, stock calculation
persistence.js       — JSON state save/load
public/index.html    — Single-page UI
data/
  blockchain-state.json  — Persisted chain
  users.json             — Hashed user credentials
  material-master.json   — Materials & BOMs

🔐 Authentication & User Roles

Roles

RoleCapabilitiesRestricted from
adminAll operations + user management + chain inspection + ERP export
operatorAll production movements (GI, GR, Transfer, Scrap, Backflush, WO ops)Chain view, ERP export, admin user management, Help page

Manage Users (API)

GET    /api/admin/users               — List all users (admin)
POST   /api/admin/users               — Create user: {username, password, role, name}
DELETE /api/admin/users/:username     — Remove user (cannot remove primary admin)
PUT    /api/admin/users/:u/password   — Change password: {newPassword}

Docker Credentials

Set in .env (or docker-compose.yml environment block):

ADMIN_USER=admin
ADMIN_PASSWORD=YourSecurePassword2026

The admin user is always re-seeded from these env vars on startup. Operator accounts are stored in data/users.json.

📦 Movement Type Codes

All movements follow SAP-aligned movement type numbering. Each posting creates one blockchain transaction and one document number (e.g. 261a00001).

CodeTypeDirectionAPI endpointUse case
101Goods Receipt from WO⬆ +StockPOST /api/goods-receiptFinished goods from production order into FG store
102Reversal of GR (101)⬇ -StockPOST /api/reversalCancel an erroneous goods receipt
261Goods Issue to WO⬇ -StockPOST /api/goods-issueIssue raw materials from warehouse to production order
262Reversal of GI (261)⬆ +StockPOST /api/reversalReturn over-issued materials back to stock
311Transfer between SLocs↔ NeutralPOST /api/transferMove material from warehouse to production line (or vice-versa)
312Reversal of Transfer (311)↔ NeutralPOST /api/reversalUndo a storage location transfer
543Backflush (automatic GI)⬇ -StockPOST /api/backflushAuto-deduct BOM components on operation confirmation
552Reversal of Backflush⬆ +StockPOST /api/reversalCancel a backflush posting
551Scrap Posting⬇ -StockPOST /api/scrapWrite off defective or obsolete material
122Return to Vendor⬇ -Stock(planned)Return received material back to supplier
201GI for Cost Center⬇ -Stock(planned)Consume material for maintenance / overhead

Reversal API

POST /api/reversal
Body: { "originalDocNumber": "261a00001", "operator": "admin", "text": "Reason for reversal" }

🏗️ Work Order (WO) Lifecycle

Work Orders follow SAP PP status flow. Each transition is recorded on the blockchain.

StatusMeaningAPINext allowed
CRTDCreated — not yet authorizedPOST /api/work-orderREL
RELReleased — authorized for productionPOST /api/work-order/:id/releaseDLV, TECO
DLVDelivered — GR posted, output confirmedauto on GRTECO
TECOTechnically Complete — all ops confirmedPOST /api/work-order/:id/tecoCLSD
CLSDClosed — settled, no more postingsPOST /api/work-order/:id/close

Create Work Order (SAP-style)

POST /api/work-order
Body: {
  "material": "CTRL-BOARD-V21",
  "plant": "1000",
  "quantity": 50,
  "scheduledStart": "2026-04-01",
  "scheduledEnd": "2026-04-03",
  "costCenter": "CC-PCB-01",
  "workcenter": "WC-SMT-01",
  "createdBy": "admin"
}

Goods Issue to WO

POST /api/goods-issue
Body: {
  "woNumber": "WO-001",
  "material": "MAT-001",
  "quantity": 50,
  "sloc": "WH-STORES",
  "text": "GI for production run"
}

Goods Receipt from WO

POST /api/goods-receipt
Body: {
  "woNumber": "WO-001",
  "material": "CTRL-BOARD-V21",
  "qtyReceived": 48,
  "qtyScrap": 2,
  "slocTo": "FG-STORE",
  "operator": "admin"
}

⛓️ Blockchain Architecture

Block Structure

{
  index:        number,         // sequential block number
  timestamp:    ISO string,     // UTC time of mining
  transactions: TX[],           // array of transaction objects
  previousHash: string,         // SHA-256 of previous block
  hash:         string,         // SHA-256 of this block content
  nonce:        number          // PoW solution (hash starts with "00...")
}

Proof-of-Work

Each block must have a hash starting with 00 (difficulty = 2). The nonce is incremented until this condition is met. This makes retroactive tampering computationally expensive.

Chain Validation

GET /api/chain          — Returns all blocks + validity (admin only)
GET /api/stats          — Returns chainValid boolean (public)

How it validates: For each block, it recomputes the hash from its content and confirms it matches the stored hash. It also confirms each block's previousHash matches the actual hash of the preceding block.

Ethereum Anchoring (optional)

Set ETHEREUM_ENABLED=true and ETHEREUM_PRIVATE_KEY in .env to anchor block hashes to the Sepolia testnet. Each anchor is a signed transaction storing the SHA-256 root hash in transaction data.

ETHEREUM_ENABLED=true
ETHEREUM_PRIVATE_KEY=0xYourPrivateKey
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YourProjectId

Persistence

The chain is saved to data/blockchain-state.json after every new block. On Docker, this maps to the named volume wip_data — data survives container restarts.

docker volume inspect wip_blockchain_wip_data

🔌 API Quick Reference

Authentication

All endpoints require HTTP Basic Auth: Authorization: Basic base64(user:password)

curl -u admin:PASSWORD http://localhost:3000/api/stats

Core Endpoints

MethodPathAuthDescription
GET/api/statsPublicSystem stats + chain validity
GET/api/chainAdminFull blockchain ledger
GET/api/auth/meUserCurrent user info
GET/api/ordersUserAll production orders
POST/api/ordersUserCreate production order
GET/api/work-ordersUserSAP-style WO list
POST/api/work-orderUserCreate SAP WO
POST/api/goods-issueUserMvt 261 — GI to WO
POST/api/goods-receiptUserMvt 101 — GR from WO
POST/api/transferUserMvt 311 — SLoc transfer
POST/api/scrapUserMvt 551 — Scrap posting
POST/api/backflushUserMvt 543 — Backflush
POST/api/reversalUserReverse any document
GET/api/inventoryUserAll inventory items + stock
GET/api/materialsUserMaterial master list
POST/api/materialsUserCreate material
GET/api/bom/:materialIdUserBOM with explosion
GET/api/reports/stockUserStock by SLoc
GET/api/reports/movementsUserMovement history
GET/api/audit-trailUserFull audit trail
GET/api/admin/usersAdminUser list
POST/api/admin/usersAdminCreate user

⚙️ Docker — Run & Operate

First Run

# 1. Copy environment file
cp .env.example .env

# 2. Edit credentials
nano .env   # set ADMIN_PASSWORD

# 3. Build & start
docker-compose up -d --build

# 4. Open browser
open http://localhost:3000

Common Commands

docker-compose up -d           # start in background
docker-compose down            # stop (data preserved in volume)
docker-compose down -v         # stop AND delete all data ⚠️
docker-compose logs -f         # follow logs
docker-compose restart         # restart without rebuild
docker-compose up -d --build   # rebuild image (after code change)

Environment Variables

PORT=3000                  # HTTP port (default 3000)
ADMIN_USER=admin           # Primary admin username
ADMIN_PASSWORD=secret      # Primary admin password
DATA_DIR=/app/data         # Data directory (inside container)
ETHEREUM_ENABLED=false     # Set true to enable Sepolia anchoring
ETHEREUM_PRIVATE_KEY=      # Wallet private key for anchoring
SEPOLIA_RPC_URL=           # Infura/Alchemy Sepolia endpoint
AUTH_ENABLED=true          # Set false to disable auth (dev only)

Data Backup

# Backup all data from Docker volume
docker cp $(docker-compose ps -q app):/app/data ./backup-$(date +%Y%m%d)

# Restore
docker cp ./backup-20260321/. $(docker-compose ps -q app):/app/data/

🔧 Troubleshooting

Chain shows invalid (red dot)

This means at least one block's hash does not match its content. Possible causes:

1. A file was edited manually in data/blockchain-state.json
2. The data volume was corrupted during a forced container kill
3. A previous version of the server wrote blocks in a different format

Resolution: If you are in development and want to reset: docker-compose down -v && docker-compose up -d --build. In production, restore from backup.

Server won't start — WWW-Authenticate error

Cause: an em-dash (—) or other non-ASCII character in the WWW-Authenticate header. HTTP headers only accept printable ASCII (0x20–0x7E).

Fix: check server.js for any Unicode in the res.set('WWW-Authenticate', ...) call. Replace with a hyphen.

Port already in use

lsof -i :3000             # Find process using port 3000
kill -9 <PID>             # Kill it
docker-compose up -d      # Restart

Data lost after restart

Ensure you are using the named volume in docker-compose.yml, not a bind mount to a temp directory:

volumes:
  - wip_data:/app/data    ✅ (named volume — persists)
  - ./data:/app/data      ✅ (bind mount to project dir — also persists)
  - /tmp/data:/app/data   ❌ (temp — cleared on reboot)

Login always fails

1. Check ADMIN_PASSWORD is set in .env or the compose file
2. Try: curl -u admin:YourPassword http://localhost:3000/api/auth/me
3. Check server logs: docker-compose logs
4. Reset admin: stop container, delete data/users.json, restart — admin is re-seeded from env vars

Ethereum anchoring fails silently

The Ethereum module uses a try/catch around every anchor call — failures do not crash the server. Check logs for [Ethereum] prefixed messages. Common causes: invalid private key, no Sepolia balance, RPC URL timeout.

Chart.js canvas keeps growing

Fixed in current version by storing chart instances in state.invChartInst and calling .destroy() before recreating. If you see this again, ensure the chart-container has a fixed height in CSS.