26.3 26.2 26.1 26.0 25.3 25.2 25.1 25.0
26.3 26.2 26.1 26.0 25.3 25.2 25.1 25.0

Scripts and Custom Logic

A maintainable service can be changed with low risk. In the Designer, maintainability depends on the process model and data structures being easy to follow, custom code staying disciplined and small, and the people who didn't build the service being able to safely support or extend it later.

This page covers practical best practices for using Action Script or JavaScript.

Keep Scripts and Custom Logic Disciplined

Designer supports technical implementation concepts such as Action Script Language, JavaScript specifics, libraries, and pro-code development. These capabilities are powerful, but they should be used carefully.

  • Always model business decisions graphically using gateways — never hide a business flow decision inside Action Script.

  • Use script logic only when modeling or standard configuration is not the clearer option.

  • Keep script blocks small, readable, and purpose-specific.

  • Split a large script into separate sub-logics (e.g. order header vs. order items) rather than one long block.

  • Avoid spreading similar script fragments across many services. Consider creating a library instead.

  • Document non-obvious script behavior, assumptions, and dependency expectations, e.g. in comments.

Be careful with custom code: Robustness decreases when critical business behavior is hidden in scattered, undocumented scripts that only one developer understands.

Use custom code when standard modeling, mappings, or built-in capabilities are not the clearest or most maintainable solution. Keep it focused and reusable.

Examples

Prefer

Operation: Order.validate() : Boolean

SQL
// An order is only valid when it has at least one line item and every item carries a strictly positive price and quantity.

set result = self.items.exists()
             and self.items.count() > 0
             and (select each from self.items
                  where element.price > 0.0 and element.quantity > 0).count()
                 = self.items.count();

Operation: Order.calculateSubtotal() : Float

// Sums (price * quantity) across every line item.

local lineTotals = apply element.price * element.quantity
                         to self.items;

set result = reduce lineTotals using element + nextElement
                               if single use element;

Order.calculateDiscount(subtotal : Float, premiumThreshold : Float, standardThreshold : Float) : Float

// Premium customers get 10% off orders over 500; everyone else gets 5% off orders over 1000.

set result = if self.customerType = "PREMIUM"
                then (if subtotal > premiumThreshold 
                      then subtotal * 0.1 else 0.0)
                else (if subtotal > standardThreshold
                      then subtotal * 0.05 else 0.0);

Operation: Order.summarize(taxRate : Float, premiumThreshold : Float, standardThreshold : Float) : OrderSummary

// Composes subtotal, discount and tax into the result the caller sends back to the client.

create result;
set result.orderId = self.orderId;

local subtotal = self.calculateSubtotal();
local discount = self.calculateDiscount(subtotal, premiumThreshold, standardThreshold);

set result.subtotal = subtotal;
set result.discount = discount;
set result.tax      = (subtotal - discount) * taxRate;
set result.total    =  subtotal - discount  + result.tax;

Avoid

Operation: Order.summarize() : OrderSummary

create r;
set r.id = o.orderId;
local lt = apply element.price * element.quantity to o.items;
set r.st = reduce lt using element + nextElement if single use element;
set r.d = if o.customerType = "PREMIUM" then (if r.st > 500.0 then r.st * 0.1 else 0.0) else (if r.st > 1000.0 then r.st * 0.05 else 0.0);
set r.t = (r.st - r.d) * 0.08;
set r.tot = r.st - r.d + r.t;
set r.v = true if o.items.exists();
set r.v = false if not(o.items.exists());

Problems:

This is one monolithic operation doing validation + subtotal + discount + tax + total, so none of these pieces can be reused or tested independently. Abug in one concern (e.g. the discount tiers) can't be isolated without reading the entire script top to bottom.

Line(s)

Remark

1 - 3

Variable naming.

r and o tell the reader nothing. Name the variables after what they contain, like result, order, lineTotal, subtotal.

4

set r.st = reduce lt using ... ;

This assumes o.items is existing and not empty. This will throw if it's genuinely empty.

5, 6

set r.d = if o.customerType = "PREMIUM" then (...) else (...);

The entire discount rule is crammed onto one unreadable line with nested statements. 500.0, 1000.0, 0.1, 0.05 are magic numbers with no names and no setting() — nobody reading this knows why those thresholds exist or can tune them without a redeploy.

8, 9

set r.v = true if ...;
set r.v = false if not(...);

This could just be set r.v = o.items.exists();, a single unconditional assignment.

This "is this order even valid" check happens last, after subtotal/discount/tax were already computed off. Validation needs to happen first (ideally in the diagram, gating whether this operation runs at all), not as an afterthought at the bottom.

📗
📘