2026.3
2026.3 strengthens Hantera's background processing and integration boundaries, adds first-class order charges and classifications, and expands the platform tooling available to app developers.
Platform & Core
Deliveries are now Fulfillments Breaking-ish
Delivery was an overloaded term that no longer described the model clearly. A Fulfillment can group multiple shipments and can also exist solely to carry fees, so it represents the broader commercial fulfillment of part of an order rather than one physical delivery. The model is therefore now named Fulfillment.
Nothing breaks:
- The graph root set
deliveries, thedelivery/deliveryId/deliveryNumber/deliveryStateedges and fields, registry paths (graph/delivery/...,enums/graph/delivery/...,actors/order/numbering/delivery) and ACL entries grantinggraph/delivery:*all keep resolving — as deprecated aliases. - Every legacy query through
deliveriesstill answers — it now carries aDEPRECATEDwarning, in bothstrictandwarnvalidation modes. New canonical queries emit no warnings. - The legacy commands (
createDelivery,setDeliveryAddress,releaseShippingToInvoicing, …) are kept and delegate to their fulfillment-named replacements (createFulfillment,setFulfillmentAddress,releaseFulfillmentToInvoicing, …) byte-identically. - Filtrera
Order.Deliverieskeeps compiling;Order.Fulfillmentsis added alongside.
Migration is gradual: move rules, components and integrations to the canonical names at your own pace. Aliases are removed in a later release, gated on deprecation telemetry.
Dual-id commands: createOrderLine, createStaticShippingDiscount, setShippingPrice, setShippingProduct, setShippingTax and splitOrderLine now take an optional fulfillmentId alongside the deprecated optional deliveryId. Supply exactly one of the pair (splitOrderLine: at most one — supply neither to keep the new line in the original line's fulfillment). Supplying both is an INVALID_COMMAND error.
Numbering: Fulfillment Series Prefix Requires Attention
The fulfillment numbering entity is renamed from delivery to fulfillment, and its default prefix changes from D to F:
- Tenants without explicit numbering configuration start a new fulfillment series at
F1000. Existing fulfillments keep theirD…numbers. - Tenants with configured
defaultPrefix/seedsare unaffected — the migration moves the registry row toactors/order/numbering/fulfillmentwith its value intact. - To keep the
Dprefix, setactors/order/numbering/fulfillment→{ "defaultPrefix": "D" }before upgrading.
This is the only item in this release that requires a tenant decision.
VS Code Extension
The extension's bundled language server resolves the new fulfillment names after reload — reload the window once the platform has been updated, so diagnostics and suggestions match.
Jobs, Scheduling & Workers
Worker Queues and Per-Definition Concurrency Feature
The job scheduler can now divide its worker capacity into named queues. This isolates time-critical work from slow or high-volume background processing: a saturated default queue no longer consumes workers reserved for a priority queue.
Job definitions and app manifests can set:
queue— the priority class that newly scheduled jobs enter.maxConcurrency— the maximum number of concurrent executions for that definition across the scheduler.
These settings solve different problems and compose cleanly. Queue workers provide operational isolation; maxConcurrency protects an external dependency or other non-parallel-safe job definition. Existing jobs remain compatible: an unset or unavailable queue routes to the configured default queue.
Declarative Job Schedules Feature
Job definitions can now declare recurring schedules directly with standard five-field cron expressions and optional time zones. The scheduler reconciles declared occurrences instead of relying on each completed run to schedule its successor.
This makes recurring work restart-safe and prevents duplicate chains: each occurrence has a durable identity, so multiple scheduler instances still materialize it only once. Schedules support forbid (the default) and allow concurrency policies, per-tenant overrides, suspension, occurrence previews, and signals for invalid or unhealthy schedules. Existing ad-hoc and self-scheduled jobs continue to work unchanged.
See Jobs and Job Definitions.
Cancel Pending Jobs from Reactors
The reactor runtime now includes deleteJob alongside scheduleJob:
deleteJob jobIdIt deletes a pending job when the caller has write access to its job definition. It returns an error record for a missing, unauthorized, running, or already-finished job, so components can handle cancellation explicitly rather than maintaining application-specific cancellation tokens.
Job Parameters in Graph
Any dynamic-fields column can now back a custom Graph field. This makes values such as job parameters available as typed, filterable Graph fields without adding a native column or duplicating data into another resource. See Graph custom fields.
Graph & Live Queries
More Reliable Live Queries Improvement
Live queries have received a substantial reliability pass. Result maintenance now handles custom dynamic fields, typed actors, newly matching rows, capped result sets, ordering, and concurrent updates more consistently. Portal reconnection and authentication flows also preserve existing live-query subscriptions rather than unnecessarily recreating them.
This is primarily a correctness and performance improvement: existing live-query definitions remain compatible, while operational lists and real-time portal views stay synchronized more reliably as data changes.
Dynamic Fields as Custom Graph Fields Feature
Custom Graph fields are no longer limited to one special dynamic-field source. Any dynamic-fields column can provide a custom field, allowing apps to expose typed, queryable values from their own resources — including job parameters — through normal Graph selection, filtering, sorting, and authorization.
Integrations, Ingresses & Observability
Egresses: a Typed Outbound Boundary Feature
Egresses are now the canonical way for rules, jobs, reactors, and ingresses to call external systems. An egress resource binds a typed component to a destination, credentials, idempotency policy, and caller ACL. Components invoke it with call; they do not construct arbitrary network destinations or receive credentials directly.
- Only callers granted
egresses/<key>:callcan invoke an egress. - Rules may make synchronous calls only to egresses marked
idempotent: true. - Egresses provide a single point for request logging, tracing, statistics, and optional response caching.
- The legacy reactor
httpmodule and its allowed-host configuration remain available for compatibility, but new outbound integrations should use egresses.
Trusted Client IP for HTTP Ingresses
HTTP ingresses can now receive the originating client IP through the canonical X-Hantera-Client-IP header. The platform resolves proxy headers once and overwrites this header before ingress handling, so clients cannot spoof the value.
Map it through the existing header-binding mechanism:
properties:
headers:
clientIp: X-Hantera-Client-IPThe component then receives clientIp as a normal parameter. See HTTP ingress parameter mapping.
Connections and AMQP Ingresses Feature
Connections are first-class, reusable resources for long-lived external broker sessions. A connection owns its endpoint, credentials, health, reconnect policy, and shared transport; ingresses and egresses reference it by id without exposing its credentials to components.
The initial AMQP 1.0 adapters support RabbitMQ 4.x, Azure Service Bus, and Azure Event Hubs:
- Queue ingresses provide at-least-once message processing with settlement, retry, dead-letter handling, response support, and collision protection.
- Stream ingresses provide partitioned consumption with durable, fenced checkpoints plus retry and quarantine behavior.
- Egresses can send through a connection with the
sendmacro, including trace-context propagation across the broker boundary.
Connection status and reconciliation failures are available through resource status and signals. A failed replacement preserves a working connection as the last-known-good transport where possible.
App Settings Can Configure App Resources
Settings bindings let an app setting overlay fields on connections and ingresses that the same app provides. The literal manifest value stays the default; a tenant-configured setting supplies the effective endpoint, address, or credential field used by the runtime.
Bindings are validated by h_ app pack, installation, and development mode. Secret-bound fields remain write-only and are masked on resource reads, while an update reconciles affected resources from the complete committed configuration.
Unified Monitoring Dashboard Feature
The new Monitoring area at /system/monitoring consolidates traces, operational statistics, and traffic-log settings:
- Trace a unit of work across ingress, jobs, egresses, actors, and sendings.
- Compare ingress and egress throughput, errors, and latency.
- Identify a slow external host independently from the egress that called it.
- Monitor worker queues using due depth, ready depth, throughput, worker saturation, and configured capacity.
- Configure ingress and egress capture levels and retention from one place.
The former standalone egress dashboard is retired in favor of this shared operational view.
Orders: Classifications & Fees
First-Class Tax and Commodity Classifications Feature
Order lines now carry vendor-neutral tax classifications, commodity classifications, and country of origin as first-class data. Product enrichment snapshots the current product classifications onto the order line, keeping an order's commercial data stable even if the catalogue changes later.
Classifications are available through commands, rule effects, Filtrera input shapes, and dedicated Graph nodes. The keyed, replace-all write model prevents duplicate classifications and lets tax providers resolve codes by system and jurisdiction rather than relying on vendor-specific dynamic-field conventions.
The same tax-classification model is available on fees and native shipping, so every taxable base uses a consistent integration surface.
Fees Are Native Order Charges Feature
Hantera now has first-class fees: additive, taxable, discountable charges such as handling, restocking, return shipping, and assembly fees. A fee belongs either to an order line or a fulfillment and is a distinct charge from both product value and native shipping.
Fees participate in totals, promotions, invoicing, payment capture, refunds, Graph queries, and rules. They can have their own tax, tax classifications, static discounts, and calculated discounts; order-wide discounts distribute across active fees as well as lines and shipping. Fee types are defined in the registry and can be provided by apps; for example, the Returns app lets administrators define return-related fee types. The core model remains vendor-neutral.
Filtrera & Developer Tooling
Calendar Module
Filtrera now includes the standard calendar module for calendar-aware date logic in components and rules. Import it with import 'calendar' when business logic needs calendar calculations instead of treating every interval as a fixed duration.
App Test Command Feature
The CLI now runs an app's API-level test suite:
h_ app test [path] [-s <session>] [--filter <pattern>] [--list]Tests live with the app under tests/**/*.test.mjs|js, execute with Node's built-in test runner, and exercise the app through its public ingresses, resources, actor APIs, and Graph queries. The command forwards the selected authenticated tenant session and exits non-zero when a suite fails, making it suitable for CI. App packages do not include the tests/ directory.
See the Hantera CLI reference.
Also in this release
OnOrderValidate-style rule hooks for all actors with a*Commandshook run after command application — see Rules.- The Fulfillment Graph node is the canonical replacement for
delivery, whose reference page documents the supported aliases. - Numerous bug fixes and performance improvements across the portal, Graph, scheduler, language server, and design system.