Solution Engineer Technical Guide

Build on Fuuz like you built it

Understanding the stack under Fuuz — MongoDB, GraphQL APIs, the Data Flow Engine, Fuuz JSONata bindings, and a deploy-anywhere infrastructure — isn't background knowledge. It's how you write better screens, faster flows, cleaner integrations, and diagnose problems in minutes instead of hours.

MongoDB‍ ‍GraphQL APIs‍ ‍Fuuz JSONata ‍ ‍Deploy-Anywhere InfrastructureWebSockets

THE STACK

What's Running Under
Everything You Build

Every screen, data flow, integration, and data model you create in Fuuz runs on this stack. Knowing how each layer works and how they talk to each other changes how you build and how fast you debug.

Client Layer Screen Designer · Mobile · External Apps · IoT Devices

Data Flow Engine Low-code / Pro-code workflow engine · Web, Backend & Gateway flows

Transformation Layer Fuuz JSONata Bindings · JavaScript · $state · $components · $metadata

GraphQL APIs Multiple typed APIs · Schema-validated · Real-time via separate WebSocket service

MongoDB Document Store · JSON-native · Multi-tenant · Indexed collections

Deploy-Anywhere Infrastructure Auto-scale · CDN · IAM · High availability · Managed operations

The Builder's Insight

When something isn't working, the stack gives you a clear isolation strategy. Data wrong? Check the document shape via a GraphQL query. Query returning unexpected results? Check predicates and filters. Transform producing bad output? Check the JSONata or JS expression in the transform console. Screen not rendering? Inspect the element binding. Each layer has a distinct responsibility and a distinct debugging approach.

Real-time: WebSockets, Not GraphQL Subscriptions

Real-time updates in Fuuz — live screen refresh, push events, shop floor alerts — are delivered via a dedicated WebSocket subscription service, separate from the GraphQL APIs. The end result is the same (live data without polling), but it is a distinct service, not a GraphQL subscription.

MongoDB is your data layer

Documents, not rows. Schema lives in the Fuuz data model designer. Document structure determines how simple or complex your queries, flows, and bindings will be.

GraphQL APIs are your data contract

Multiple typed APIs serve different parts of the platform. Filtering and aggregation happen here via predicates and _aggregate queries — not in JSONata transforms.

Data Flow Engine is your workflow layer

The low-code / pro-code engine that orchestrates logic — API calls, transforms, conditionals, error handling, integrations. Sits above GraphQL in the stack.

Fuuz JSONata is your expression language

Fuuz extends standard JSONata with platform-specific bindings: $components, $metadata, $state, join functions, and more. Standard JSONata is just the foundation.

BSON document reads / writes



GraphQL queries / mutations



typed queries / mutations / predicates

managed infrastructure

WebSocket events (real-time)

JSONata / JavaScript transforms


MONGODB

Think in Documents, Not Tables

The biggest conceptual shift for engineers from SQL-backed environments. MongoDB stores JSON documents, not rows. How you design documents affects query performance, screen binding complexity, and flow logic.

Concept SQL World MongoDB / Fuuz
Data unit Row in a table JSON document in a collection
Relationships Foreign keys + JOINs Nested sub-documents or ID references
Schema changes ALTER TABLE + migration + risk Add field in schema designer → live instantly, zero downtime
Optional data Nullable column on every row Field simply absent if not applicable
Variable shapes EAV tables or wide nullable rows Each document carries its own field set
Filtering / aggregation SQL WHERE / GROUP BY GraphQL predicates and _aggregate queries at the API layer
Record ID Primary key (varies) Always id in Fuuz GraphQL — no underscore prefix
SQL — Relational Traditional MES/ERP
-- Reconstructing ONE work order -- requires 4 tables + 3 JOINs SELECT wo.id, wo.number, wo.status, p.name, p.revision, op.seq, op.description FROM work_orders wo JOIN parts p ON p.id = wo.part_id JOIN wo_operations op ON op.wo_id = wo.id WHERE wo.id = 'WO-1042'; -- Add "customer_po" field? -- ALTER TABLE + migration + deployment window
MongoDB — Document (Fuuz) Fuuz Platform
// ONE document — full object in one read { "id": "WO-1042", // "id" not "_id" "number": "WO-1042", "status": "In Progress", "part": { "id": "part-ref-id", "name": "Bracket Assy", "revision": "C" }, "operations": [...], "customer_po": "PO-8812" // new field // schema designer → live. Zero downtime. }

On Embedding: Conceptually Sound, Practically Evolving

The embed-vs-reference pattern is the right mental model for document databases. In Fuuz, full embedded type support is actively in development. Apply the principles in your data model design now — as platform support deepens, models designed with this thinking will be well-positioned. Discuss with your team lead which patterns are best supported in your current release.

The #1 Mistake from SQL Backgrounds

Over-normalizing the data model. Creating a separate Fuuz model for every sub-entity because "that's how you do it in SQL." Before splitting, ask: will this data ever be queried independently, or does it always travel with its parent? If it always travels with its parent — it's a candidate for embedding. Fewer models often means simpler queries, cleaner flows, and easier screen bindings.

GRAPHQL APIs

GraphQL: Where
Filtering and Fetching Live

Fuuz exposes multiple GraphQL APIs. This is where you declare what data you want, apply filters and predicates, and run aggregations. Filtering and grouping happen here at the API layer — not in JSONata transforms.

Fuuz GraphQL Conventions — Know These Before You Build

Connection pattern: All results are wrapped in edges { node { ... } }. Your data lives on node.

Sorting: Use orderBy: [{ field: "fieldName", direction: "asc" }] — not sort.

Aggregation: Place the group field and _aggregate { id { count } } together inside edges.node — there is no separate groupBy argument.

Record ID: Always id — not _id.

Filtering: Use where variables — never fetch everything and filter in JSONata.

Mutations write data

Creates, updates, and deletes all go through GraphQL mutations. Always return id in the mutation selection set to confirm the write and enable chained operations.

Declare exactly what you need

Shape the query to match exactly what the screen or flow needs. No over-fetching a 40-field record to display 3 fields on a table row.

Filter via predicates

GraphQL predicates are your WHERE clause. Filter by field values, date ranges, and relationships at the API layer before data ever reaches your screen or flow.

Traverse relationships in one call

Walk from Work Center → Work Orders → Operations in a single query. One roundtrip returns the full graph — no chained REST-style calls.

Aggregate at the query layer

Use _aggregate queries for counts, sums, and grouping. Runs server-side — far more efficient than fetching all records and counting in JSONata.

GraphQL — Query with Predicates Filter at the API Layer
# Filter HERE in the query — not in JSONata query GetOpenWOs( $where: WorkOrderWhereInput $orderBy: [WorkOrderOrderByInput!] $first: Int $after: String ) { workOrder( where: $where orderBy: $orderBy first: $first after: $after ) { pageInfo { startCursor endCursor hasNextPage hasPreviousPage } total edges { node { id // "id" — not "_id" in Fuuz number status scheduledStart part { name revision } } } } } # Variables example: # { "where": { "workCenterId": { "_eq": "wc-123" }, # "status": { "_eq": "Open" } }, # "orderBy": [{ "field": "scheduledStart", "direction": "asc" }] }
GraphQL — Mutation (Write) Flow / ERP Write-back
mutation UpdateWOStatus( $id: ID! $status: String! $completedAt: DateTime ) { updateWorkOrder( id: $id data: { status: $status completedAt: $completedAt } ) { id // always return id to confirm status completedAt } }

Schema-validated in real time

The GraphQL input in Fuuz autocompletes and validates against the schema as you type. Field name errors and type mismatches are caught immediately, before runtime.

GraphQL — Aggregate Query Count/Sum at API Layer
# Aggregate WOs grouped by status # Group field goes on the node; _aggregate goes inside node query WOStatusCounts( $where: WorkOrderWhereInput $orderBy: [WorkOrderOrderByInput!] ) { workOrder( where: $where orderBy: $orderBy ) { total edges { node { workOrderStatusId // ← field to group the aggregate on _aggregate { id { count } } } } } } # Variables: { "orderBy": [{ "field": "workOrderStatusId", # "direction": "desc" }] } # Result: each edge.node contains the group field + count
Anti-pattern — Don't Do This Common SQL-background Mistake
// ❌ WRONG: Fetch all, filter in JSONata query { workOrders { // no filter — returns all id status number } } // JSONata transform node: $[status = "Open"] // wrong layer // ✅ RIGHT: Filter in the query query { workOrders(where: { status: { _eq: "Open" } }) { id status number } }

API EXPLORER & QUERY BUILDER

Learn GraphQL the
Fuuz Way — No Memorization Required

The fastest way to learn Fuuz GraphQL isn't reading docs — it's using the built-in API Explorer and Query Builder. These no-code tools generate correct GraphQL for you in real time, with full field descriptions, type information, and variable guidance at every step.

Relationships — one click away

Any related model (campaign, batchType, qualityStatus) appears as an expandable node in the Query Builder. Click it to include related fields — no JOIN syntax required. The builder handles the nested structure automatically.

Where to Find It

Navigate to System → Business Intelligence → API Explorer in any Fuuz tenant. The API Explorer gives you a live GraphQL environment with the Query Builder tool accessible via the Tools menu at the top of the editor. Everything here runs against your actual tenant schema in real time.

Query Builder — Visual query construction

Open via Tools in the API Explorer. Pick the model you want to query, check the fields you want returned, and the Query Builder writes the GraphQL for you in real time. No syntax to memorize — just click.

Full field descriptions built in

Click the pencil icon next to any field to see its full description, data type, and any field-level arguments available — rounding options for floats, format options for durations, and more. The schema documents itself.

Live GraphQL code view

Click the </> GraphQL Code button in the Query Builder to see the exact query being written as you select fields. Copy it directly into a screen binding or flow node — already correctly structured.

Variable explorer

Click the $ button in the Query Builder to see all available variables for a query — $where, $orderBy, $first, $after — with their exact types. No guessing at variable names or shapes.

Baked-in field arguments reduce scripting

Different field types expose built-in transformation arguments. Duration fields offer text (ISO8601) or milliseconds format options. Float fields offer rounding direction (Up, Nearest, Down). These eliminate JSONata transforms for common formatting needs.

The Recommended Learning Path for GraphQL in Fuuz

Step 1: Open API Explorer → Tools → Query Builder.
Step 2: Select your model and check the fields you need.
Step 3: Click the pencil on any field to read its description and available arguments.
Step 4: Click $ to see available variables and their types.
Step 5: Click </> GraphQL Code to view the generated query.
Step 6: Copy the query into your screen binding or flow node and test it in the Explorer first.

Do this a dozen times across different models and you will have internalized Fuuz GraphQL faster than any documentation could teach it.

Field Arguments Reduce Scripting

Before reaching for a JSONata transform to format a value, check whether the field already has a built-in argument for it. Duration fields can return ISO8601 text or milliseconds. Float fields can round up, nearest, or down. These are configured directly in the Query Builder — click the pencil icon on the field to see what arguments are available for any given field type.

DATA FLOW ENGINE

The Low-code / Pro-code
Workflow Engine

The Fuuz Data Flow Engine sits above the GraphQL layer — it orchestrates logic, calls APIs, handles errors, and applies transforms. Think of it as your application's business logic layer, built visually with the option to drop into JavaScript for complex operations.

Web Flows

Triggered by user interactions on screens. Also serve as Remote Function Calls (RFC) — callable from any external system. Web Flows with screen context have full access to $components and all screen elements directly within the flow engine. They are also MCP tools, enabling agentic workflow integration.

Backend Flows

Server-side logic triggered by events, schedules, or API calls. Used for integration logic, data processing, ERP write-backs, and operations that should not run on the client.

Gateway Flows

Expose Fuuz logic to external systems as callable endpoints. Used when external systems need to push data in or trigger Fuuz operations programmatically.

Integration Without Rip-and-Replace

Integrating external systems with Fuuz gives you all the benefits of the platform — flows, GraphQL queries, MCP tools, and agentic workflows — without replacing existing systems. Interact with external data where it lives while orchestrating it through Fuuz

Data Flows are MCP Tools & Agentic Workflow Builders

Every Fuuz Data Flow is also an MCP (Model Context Protocol) tool. This means flows can be orchestrated by AI agents, and Integration nodes can be used to build deterministic agentic workflows for any business process or integration scenario — without any additional tooling or infrastructure.

Fuuz is the Only Enterprise Platform with Self-Documenting APIs

When you create or extend a data model in Fuuz, the GraphQL APIs are automatically generated and updated — no separate API development step required. Save any query or mutation from the Explorer and it immediately appears in your external API list. Create topics and webhooks for real-time event-driven integrations. Web Flows are RFC endpoints callable from any external system.

Pub/Sub, Topics & Webhooks

Fuuz supports Pub/Sub messaging — create your own topics and web hooks for real-time data exchange between systems. This enables event-driven integrations without polling, and powers live data exchange across Fuuz and external platforms.

Saved Queries & Mutations

Any GraphQL query or mutation can be saved directly from the API Explorer — instantly adding it to your external API list. This is how Fuuz generates self-documenting APIs automatically from your data models. Create your own APIs without writing any server code.

Stack Position: DFE is Above GraphQL

The Data Flow Engine sits above the GraphQL API layer. Flows call GraphQL APIs to read and write data, then use the Transformation Layer to process results. Understanding this ordering matters when tracing what triggered what during a debug session.

Debugging Flows: Use the Console and Flow Logs

When a flow isn't behaving as expected, your primary tools are the Flow Console and execution logs. Every transform node exposes its input and output in the console — inspect the actual data at each step without adding separate debug nodes. Check the console of the relevant transform section before assuming the problem is upstream.

FUUZ JSONATA BINDINGS

Not Just JSONata —
Fuuz JSONata

Standard JSONata is the foundation, but Fuuz extends it substantially with platform-specific bindings. These give you access to screen state, user identity, flow context, join operations, and more. When you're building in Fuuz, you're using Fuuz JSONata — significantly more powerful than the open-source baseline.

Two Execution Contexts — Know Which One You're In

Screen expressions run client-side. You have access to $components, $metadata, $card, data, and $$.

Data Flow expressions run server-side. You have access to $state, $state.context, and $state.claims. Exception: in Web Flows that run with screen context, you also have access to screen elements directly within the flow engine — $components and related screen bindings are available there.

Fuuz JSONata includes 200+ custom bindings built specifically for the platform, with more released regularly. Standard open-source JSONata is just the starting point.

$components- Interact with Screen Element

Expression What It Does
$components.Form1.fn.save() Save the form
$components.Form1.fn.setValue("field", val) Set a single field value programmatically
$components.Form1.formState.dirty true when unsaved changes exist
$components.Form1.formState.valid true when all validations pass
$components.Form1.data.fieldName Read a field value directly
$components.Table1.fn.search() Trigger table search / refresh
$components.Table1.selectedRows Array of all selected rows
$components.Table1.selectedRows[0].id First selected row's ID
$components.Screen.fn.setContextValue("k", v) Set a single screen context key
$components.Screen.fn.mergeContext({...}) Shallow-merge values into screen context
$components.Screen.context.myKey Read a screen context value

$metadata — URL, User, Tenant

Expression What It Does
$metadata.urlParameters.id URL path parameter (e.g. /record/:id)
$metadata.querystring.tab Query string parameter (?tab=details)
$metadata.user.id Logged-in user ID
$metadata.user.email Logged-in user email
$metadata.user.roles Array of user roles
$metadata.tenant.id Current tenant ID
$metadata.tenant.name Current tenant name
$metadata.settings.timezone User timezone
$metadata.settings.dateFormat User date format string

$state — Data Flow Context

Expression What It Does
$ Current node payload — shorthand for $state.payload
$state.payload Full current node input payload
$state.context Shared flow context (set via Set/Merge Context nodes)
$state.context.myKey Read a specific context value
$state.claims.userId Triggering user ID from auth
$state.claims.tenantId Tenant ID from auth claims
$state.claims.roles User roles from auth claims
$state.metadata.flowId Current flow ID
$state.lastError Error from last caught error node

data, $card & $$ — Element-level Bindings

Expression What It Does
data.fieldName Read a field value inside a Form element
data.active ? "Yes" : "No" Ternary on a boolean form field
$card.data.id Card record ID — use inside Cards elements (not data.id)
$card.data.status Card record field value
$$.newValue New value in an onChange handler
$$.oldValue Previous value in an onChange handler
$isNotNilOrEmpty($$.newValue) and $not($$.newValue = $$.oldValue) Guard: only fire when non-empty and actually changed

Fuuz Join Functions & Utility Bindings

Fuuz JSONata — Join Functions Beyond Standard JSONata
// $innerJoin — match records from both sides $innerJoin( workOrders, // left array parts, // right array "partId", // left join key "id" // right join key ) // $leftOuterJoin — keep all left, match right $leftOuterJoin( workOrders, scheduledShifts, "shiftId", "id" )
Fuuz JSONata — Utility Bindings Screen & Flow Context
// $query — run a GraphQL query inline $query({ "api": "system", "statement": "query { ... }", "variables": { "id": "123" } }) // $numeral — number formatting $numeral(12345).format("0,0") // "12,345" $numeral(0.75).format("0%") // "75%" $numeral(1234.5).format("$0,0.00") // "$1,234.50" $now // ISO 8601 timestamp $appConfig.someKey // tenant app config

Critical JSONata Syntax Gotchas

Gotcha Correct Usage
No ! operator Use $not(expr) instead of !expr
String concat is & "a" & " " & "b" — not +
Equality is = x = "val" — not == or ===
Membership check x in [1,2,3] — not .includes()
No null coalescing ?? $exists(val) ? val : "default"
Cards vs Form data Inside Cards: $card.data.x — not data.x
Context is $ $ = entire current input. Confirm shape in the console before writing transforms.

MENTAL MODEL

Coming from SQL?
Reframe These 5 Things

These are the specific mental model shifts that trip up experienced engineers when they first build on Fuuz. These are the closest useful parallels — not a 1:1 mapping, the platforms are genuinely different.

SQL / Relational Normalize everything. Every sub-entity gets its own table. Reconstruct the object at query time with JOINs. MongoDB / Fuuz Design for your access pattern. Data that always travels together belongs together. Think in objects first, storage second.
SQL / Relational Schema changes are risky: ALTER TABLE, migration scripts, deployment windows, potential table locks. MongoDB / Fuuz Add a field in the Fuuz schema designer — live instantly, zero downtime. Schema field changes are low-risk, fast tasks.
Embedded Documents (NoSQL) Full embedded document support is a common expectation from MongoDB backgrounds. Fuuz JSON Schema & JSON Objects Fuuz supports JSON schema and JSON objects within data models. Full embedded document support is on the roadmap. Enumerations are handled by creating joins between models — a clean, queryable pattern.
SQL / Legacy ERPs You need a database diagram and extensive documentation just to know where to start building a query. Fuuz Application Graph + Query Builder Go straight to the Query Builder — all relationships are exposed by clicking. Use the Application Graph to see every relationship between data models, screens, and flows in a single visual knowledge graph. Fuuz is the only platform on earth with this feature.
SQL WHERE / GROUP BY Filter and aggregate in the database query engine using SQL clauses. GraphQL predicates / edges.node._aggregate Filter via where variables. Group and aggregate using edges.node.fieldName + _aggregate { id { count } }. Sort using orderBy: [{ field, direction }]. JSONata reshapes — it does not filter.
SQL JOINs Combine data from multiple tables using INNER JOIN, LEFT JOIN, computed by the DB engine. Fuuz JSONata $innerJoin / $leftOuterJoin Fuuz provides join functions to combine result sets from multiple GraphQL queries in a flow transform.
On-prem / Hosted SQL Infrastructure is your team's problem. Backups, upgrades, scale events, DR planning — all on you. Deploy-Anywhere Infrastructure / Fuuz All infrastructure is managed. Focus entirely on application delivery. Application performance on large datasets is still your design responsibility.

APPLICATION GRAPH

The Knowledge Graph
No Other Platform Has

The Fuuz Application Designer includes an Application Graph — a live, visual knowledge graph of your entire application. It shows every relationship between data models, screens, and data flows in a single interactive view. This is not a static diagram — it reflects your actual deployed application in real time.

Fuuz is the Only Platform on Earth With This Feature

In traditional systems, understanding how data, screens, and logic relate to each other requires digging through documentation, database diagrams, and source code. In Fuuz, open the Application Designer and select Application Graph. Every data model, every screen, and every flow that interacts with that data is visible immediately — no documentation required. This is your starting point for any new engagement, troubleshooting session, or impact analysis.

Data models as nodes

Every Fuuz data model appears as a node in the graph. Relationships between models are shown as edges — the same relationships exposed in the Query Builder and GraphQL schema.

Screens and flows connected

The graph shows which screens and data flows interact with each data model — giving you instant visibility into the impact of any schema change before you make it.

No documentation required

Unlike SQL-backed systems where you need a database diagram and documentation just to begin, the Application Graph is your documentation. Start here on every new engagement.

For Engineers from Legacy Systems — This Should Be a Revelation

If you have spent years in point solutions or legacy ERP environments, you know how much time is lost just trying to understand the shape of the system before you can build anything. The Application Graph eliminates that entirely. Combine it with the Query Builder — which exposes all relationships by clicking — and you can go from zero context to writing correct GraphQL in minutes, not days.

BUILD PATTERNS

Patterns Every SE
Should Internalize

Recurring patterns across MES, WMS, CMMS, and integration builds. Apply them consistently and you will build faster, with fewer bugs, and more maintainable solutions.

PATTERN 01

Design the query before the model

Start with what the screen needs to display. Design your document shape to make that query simple. Model for the access pattern — not in the abstract.

PATTERN 05

Request only what the screen uses

A table row showing 3 fields should request only 3 fields. Over-fetching adds payload weight and makes bindings harder to read and maintain.

PATTERN 02

Filter in GraphQL, reshape in JSONata

Use where variables to filter and edges.node._aggregate to count/sum. Sort via orderBy: [{ field, direction }]. Use JSONata to reshape the already-filtered response only. Never flip these roles.

PATTERN 06

Know your JSONata context

Screen: $components, $metadata, data, $card. Flow: $state. Confusing these produces silent failures, not errors.

PATTERN 03

Always return id in mutations

After any GraphQL mutation, return id in the selection set. Confirms the write and gives you the ID for any chained operations in the same flow.

PATTERN 07

Map ERP writes to mutations early

When scoping ERP integrations (NetSuite, Plex, BC), identify target GraphQL mutations before writing any flow logic. The mutation schema defines exactly what Fuuz accepts.

PATTERN 04

Check the console before assuming upstream

Every transform section exposes input/output in the console. Inspect it there first before assuming the problem is in the GraphQL query

PATTERN 08

Scope field additions as low-risk

Adding a field to a model is a fast, zero-downtime task. Flow logic, behavioral changes, and performance tuning on large collections — that's where real effort lives.

The SE Build Loop

1. Confirm document shape (schema designer) → 2. Write GraphQL query with predicates → 3. Use JSONata to reshape result → 4. Bind to screen element or flow output → 5. Inspect each layer in the console/logs independently before declaring it working end-to-end.

TROUBLESHOOTING

Debug by Layer,
Not by Guessing

The stack gives you a clear isolation strategy. Each layer has a distinct failure signature. Start at the data layer and work up — every time.

Symptom Suspect Layer Where to Look
Screen shows no data GraphQL query / predicate Run the query standalone. Is the predicate returning records? Is the field name correct?
Wrong data on screen JSONata binding / wrong field Inspect the raw GraphQL response first. Correct there? If yes, check the JSONata expression in the transform console.
Screen loads slowly Dynamic expressions / missing indexes Most common causes: (1) dynamic transformed fields like visible bindings executing too frequently, (2) complex filters on large collections without an index.
Flow not triggering Trigger config / event mismatch Confirm the trigger event matches the action being performed. Check flow execution logs.
Flow erroring mid-run Specific node failure Open flow execution history to identify the failing node. Inspect the console of that transform to see what input it received.
GraphQL mutation fails Wrong field name / type mismatch Read the error — GraphQL errors are explicit. Fuuz uses id not _id. Autocomplete in the editor flags these as you type.
Integration writes missing Mutation not running / wrong tenant Confirm mutation ran in flow execution logs. Confirm correct tenant context. Check id returned in mutation response.
JSONata producing null Wrong context / wrong field path Are you in a screen or a flow? $state only works in flows. $components / $metadata only in screens. Inside Cards: use $card.data.x not data.x.

The Debug Hierarchy — Follow This Order Every Time

Step 1: Does the data exist? (Run a GraphQL query to confirm)
Step 2: Does the query return it correctly? (Run the exact binding query with your predicates standalone)
Step 3: Does the JSONata transform it correctly? (Inspect input/output in the transform console)
Step 4: Does the screen element bind correctly? (Check element property mapping)

Skipping steps leads to false diagnoses and wasted time. Layer by layer, every time.

SAAS + DEPLOY-ANYWHERE INFRASTRUCTURE

What Managed SaaS Means
for How You Build and Scope

Fuuz running as managed SaaS on a deploy-anywhere infrastructure changes what belongs in your delivery scope, what customers inherit automatically, and how to think about application-level performance and design.

Schema changes are instant

Field additions deploy without downtime. Iterate on your data model incrementally across sprints — no upgrade events or deployment windows needed.

Security is inherited

Encryption at rest and in transit, IAM, audit logging — all built into the platform infrastructure layer. Don't scope custom security plumbing. It's already there.

Infrastructure is never in your scope

No servers, no database setup, no backups, no failover planning. The platform manages all of it, regardless of where it’s deployed. Your entire scope is application delivery.

Platform vs. app release cadence

Core platform infrastructure updates continuously. However, Fuuz application feature releases follow a managed schedule. Confirm feature availability for your release version when scoping.

Platform scale vs. app performance

The platform scales automatically regardless of deployment target. But application performance on large datasets is your design responsibility — load-test against realistic data volumes before go-live.

Multi-site = configuration

Adding a new plant or region to an existing tenant is a configuration task. Multi-tenant architecture means global rollout doesn't create new infrastructure scope.

Don't Confuse Platform Scale with App Performance

Platform infrastructure scales automatically regardless of where Fuuz is deployed. But how your application handles large data sets is a design concern you own. Complex flow logic, unindexed queries on large collections, and overly dynamic screen bindings all affect performance under real-world data volumes. Load test against realistic data before handing off to customers.

~0

Minutes of downtime
to add a field to a model

1

GraphQL call to retrieve
a fully hydrated object graph

Platform scale headroom
— app perf is still your job