Article Type: Configuration / How-To
Audience: Developers, App Admins, Advanced Users
Module: Script Editor / Developer Tools
Applies to Versions: 2025.1+
Estimated Time: 30-45 minutes
The Fuuz Script Editor (formerly Transformation Explorer) is a comprehensive development environment for testing, validating, and executing JSONata and JavaScript functions within the Fuuz Industrial Operations Platform. This tool enables developers and authorized users to create reusable, version-controlled transformation scripts that can be deployed across data flows, screens, and integrations throughout your enterprise applications.
Saved scripts are version-controlled application components requiring deployment like data flows and screens, providing full audit trails and traceability for regulatory compliance. Scripts can execute in Local mode (browser) or Server mode (Fuuz server) with access to custom Fuuz functions. The Script Editor provides comprehensive validation for input/output payloads and schemas, plus an interactive workspace with resizable panels for efficient development.
Navigate to the Script Editor to begin developing and testing transformation scripts.
Configure validation and execution settings for your development environment.
Develop and test your JSONata or JavaScript transformation logic interactively.
user_id, facility, current_timestampSave your script as a version-controlled, deployable application component.
After saving, define schemas to validate data structure and provide documentation.
Deploy the saved script to target environments following your organization's deployment procedures.
Reference saved scripts anywhere JSONata transforms are used throughout Fuuz.
Saved scripts can be used in:
| Setting | Description | Default |
|---|---|---|
| Validate Input Payload | Validates input payload conforms to input schema. Errors sent to console. | Enabled |
| Validate Input Schema | Validates input schema is valid JSON schema format. Errors piped to console. | Enabled |
| Validate Output Payload | Validates script output matches output schema. Mismatches generate console errors. | Enabled |
| Validate Output Schema | Validates output schema is valid JSON schema format. Invalid schemas generate errors. | Enabled |
| Mode | Description | Use Cases |
|---|---|---|
| Local Mode | Executes scripts in browser environment | Rapid testing, client-side transforms, limited data |
| Server Mode | Executes scripts on Fuuz server | Production testing, large datasets, custom Fuuz functions |
| Panel | Purpose | Hotkey |
|---|---|---|
| Context Panel | Edit context variables ($context.user_id, $context.facility, etc.) | Alt+1 |
| Script Panel | Main code editor for JSONata or JavaScript | Alt+2 |
| Payload Panel | Input JSON data for script processing | N/A |
| Output Panel | Script execution results and errors | Alt+4 |
| Console Panel | Validation messages and execution logs | N/A |
All panels are resizable—click and drag panel borders to adjust size. Use View menu or hotkeys to toggle panel visibility.
The following examples demonstrate common use cases for the Script Editor, showing both JSONata and JavaScript implementations for industrial operations scenarios. Complete example files are attached to this article for download and testing.
Use Case: Summarize inventory snapshot data by status and product, generating management reports with aggregated quantities, lot counts, location information, and alerts for low stock or quality holds.
Attached Files:
Payload_Example_ProductLotSummaryScript.txt - Sample inventory snapshot dataContext_Example_ProductLotSummaryScript.txt - Context variables with product catalog and configurationJsonataTransform_Example_ProductLotSummaryScript.txt - Complete JSONata transformationInput Payload (excerpt):
{
"timestamp": "2025-01-01T14:30:00Z",
"facility": "Plant-North",
"inventory_snapshot": [
{
"product_id": "SHAFT-304-16",
"product_name": "Steel Shaft 304SS 16mm",
"lot_number": "LOT-2024-1201",
"quantity": 2500,
"unit": "EA",
"status": "Available",
"location": "WH-A-12",
"received_date": "2024-12-01"
},
{
"product_id": "BEARING-6205",
"product_name": "Deep Groove Ball Bearing 6205",
"lot_number": "LOT-2024-1210",
"quantity": 5000,
"unit": "EA",
"status": "Available",
"location": "WH-B-05",
"received_date": "2024-12-10"
}
// ... 7 more inventory records (see attached file)
]
}Context Variables (excerpt):
{
"user_id": "scott.smith",
"role": "operations_manager",
"facility": "Plant-North",
"shift": "A",
"current_timestamp": "2025-01-01T14:30:00Z",
"production_day": "2025-01-01",
"fiscal_period": "2025-Q1",
"product_catalog": {
"SHAFT-304-16": {
"category": "Machined Parts",
"reorder_point": 2000,
"safety_stock": 500
}
// ... product catalog for all products
},
"status_config": {
"Available": {
"priority": 1,
"color": "green",
"pickable": true
}
// ... configuration for all statuses
},
"settings": {
"include_shipped": false,
"show_alerts": true,
"group_by_category": true
}
}JSONata Script (excerpt):
{
"report_metadata": {
"generated_at": $context.current_timestamp,
"generated_by": $context.user_id,
"user_role": $context.role,
"facility": $context.facility,
"shift": $context.shift,
"production_day": $context.production_day,
"fiscal_period": $context.fiscal_period
},
"status_summary": inventory_snapshot[
$context.settings.include_shipped ? true : status != "Shipped"
]{
status: {
"status": status,
"priority": $lookup($context.status_config, status).priority,
"color": $lookup($context.status_config, status).color,
"is_pickable": $lookup($context.status_config, status).pickable,
"total_quantity": $sum(quantity),
"lot_count": $count(lot_number),
"unique_products": $count($distinct(product_id)),
"products": $sort($distinct(product_id)),
"locations": $sort($distinct(location))
}
},
"product_summary": inventory_snapshot{
product_id: {
"product_id": product_id,
"product_name": $$.product_name,
"category": $lookup($context.product_catalog, product_id).category,
"reorder_point": $lookup($context.product_catalog, product_id).reorder_point,
"total_quantity": $sum(quantity),
"available_quantity": $sum(quantity[status = "Available"]),
"below_reorder": $sum(quantity[status = "Available"]) <
$lookup($context.product_catalog, product_id).reorder_point,
"status_breakdown": ${
status: {
"status": status,
"quantity": $sum(quantity),
"lot_count": $count(lot_number),
"lots": lot_number
}
}
}
}
// ... alerts and category_rollup sections (see attached file)
}Key Features Demonstrated:
Use Case: Calculate Overall Equipment Effectiveness (OEE) at multiple levels (shift, day, week, work order) by combining production history and work unit state data. Provides comprehensive equipment performance metrics with downtime analysis and reduced output tracking.
Attached Files:
Payload_Example_OEECalculationsJavascript.txt - Production records and work unit historyContext_Example_OEECalculationsJavascript.txt - Product specifications, work orders, and work unit configurationJavascriptFunction_Example_OEECalculationsJavascript.txt - Complete JavaScript calculation functionInput Payload Structure:
{
"production_records": [
// 56 production records across 3 work units, 7 work orders
{
"id": 1,
"workUnit": "WC-100",
"workOrder": "WO-2024-001",
"product": "PROD-A",
"quantity": 45,
"dateTime": "2024-12-30T06:15:00Z",
"quality": "good",
"serialNumbers": ["SN-A-001", "SN-A-002"],
"lotNumber": "LOT-A-1230"
}
// ... 55 more production records
],
"workUnit_history": [
// 65 work unit state records tracking running, disabled, blocked, starved states
{
"id": 1,
"workUnit": "WC-100",
"dateTime": "2024-12-30T06:00:00Z",
"mode": "production",
"state": "running",
"durationMinutes": 60
}
// ... 64 more state records
]
}Context Variables Structure:
{
"products": {
"PROD-A": {
"name": "Aluminum Housing Assembly",
"ideal_cycle_time_seconds": 72,
"expected_hourly_rate": 50,
"setup_time_minutes": 60
}
// ... 5 more products
},
"work_orders": {
"WO-2024-001": {
"product": "PROD-A",
"order_quantity": 500,
"start_date": "2024-12-30T06:00:00Z",
"end_date": "2024-12-30T14:00:00Z",
"workUnit": "WC-100"
}
// ... 6 more work orders
},
"shifts": {
"Shift-1": {
"name": "Day Shift",
"start_hour": 6,
"end_hour": 14,
"duration_minutes": 480
}
// ... 2 more shifts
},
"workUnits": {
"WC-100": {
"name": "CNC Machining Center 1",
"department": "Machining"
}
// ... 2 more work units
}
}JavaScript Script Structure (key functions):
// Helper functions for shift/date/week calculation
function getShift(dateTime) {
const date = new Date(dateTime);
const hour = date.getUTCHours();
if (hour >= 6 && hour < 14) return 'Shift-1';
if (hour >= 14 && hour < 22) return 'Shift-2';
return 'Shift-3';
}
// Initialize aggregation structures
const workUnitStats = {};
const shiftStats = {};
const dayStats = {};
const weekStats = {};
const workOrderStats = {};
// Process production records - aggregate by work unit, shift, day, week
$.production_records.forEach(record => {
const shift = getShift(record.dateTime);
const date = getDate(record.dateTime);
const week = `Week-${getWeek(record.dateTime)}`;
// Aggregate good and scrap quantities at each level
// ... (see attached file for complete aggregation logic)
});
// Process work unit history for availability
$.workUnit_history.forEach(record => {
// Track running time, downtime events, reduced output
if (record.mode === 'disabled') {
downtimeEvents.push({
workUnit: record.workUnit,
durationMinutes: record.durationMinutes,
reason: 'Machine Disabled'
});
}
// ... (see attached file for complete tracking logic)
});
// Calculate OEE: Availability × Performance × Quality
function calculateOEEMetrics(stats, isWorkOrder = false) {
availability = stats.runTime / stats.plannedProductionTime;
performance = totalIdealTime / stats.runTime;
quality = stats.good / stats.total;
oee = availability * performance * quality;
return {
...stats,
availability: (availability * 100).toFixed(2),
performance: (performance * 100).toFixed(2),
quality: (quality * 100).toFixed(2),
oee: (oee * 100).toFixed(2)
};
}
// Return comprehensive multi-level OEE analysis
return {
summary: {
reportPeriod: "2024-12-30 to 2025-01-03",
totalWorkUnits: Object.keys(workUnitStats).length,
totalWorkOrders: Object.keys(workOrderStats).length,
totalGoodParts: /* calculated */,
totalScrapParts: /* calculated */
},
oee: {
byShift: shiftOEE, // OEE for each shift
byDay: dayOEE, // OEE for each day
byWeek: weekOEE, // OEE for each week
byWorkOrder: workOrderOEE // OEE for each work order
},
downtime: {
summary: downtimeSummary, // Aggregated by shift/day/week
events: downtimeEvents // Individual downtime events
},
reducedOutput: {
summary: reducedOutputSummary, // Blocked/starved analysis
events: reducedOutputEvents // Individual events
},
insights: {
topPerformingShifts: topPerformers,
shiftsNeedingAttention: areasOfConcern,
totalDowntimeMinutes: /* calculated */,
avgOEE: /* calculated */
}
};
When to Use JSONata:
When to Use JavaScript:
Success Criteria:
Testing Checklist:
| Issue | Cause | Resolution |
|---|---|---|
| Script Editor not visible in menu | Insufficient access rights | Contact administrator to provision Developer, App Admin, or RBAC policies |
| Payload cleared after saving | Expected behavior | Save payload to text file before saving script. Reload when resuming work |
| Works in editor, fails in data flow | Different execution context | Use Server mode in editor. Match context variables to flow environment |
| Schema validation errors | Schema syntax error | Enable "Validate Input Schema" to check syntax. Review JSON schema docs |
| Can't see schema panels | Only appear after saving | Save script first using File → Save |
| Undefined/null errors | Missing context or payload fields | Add null checks. Use JSONata null-safe operators (?, ?:) |
| Script changes not reflected | Not deployed to environment | Deploy updated script version to target environment |
| Custom Fuuz functions unavailable | Running in Local mode | Switch to Server mode in Editor → Settings |
| Poor performance with large data | Running in Local mode | Switch to Server mode. Optimize script logic |
| Script not in selection lists | Not deployed to environment | Deploy script to current environment (Build, QA, or Production) |
| Version | Date | Editor | Description |
|---|---|---|---|
| 1.0 | 2025-01-01 | Craig Scott | Initial Release |