Introduction
Every business runs on rules. When a discount exceeds 20%, it needs manager approval. End dates must come after start dates. Priority customers get different pricing. Sales totals need to update when quantities change. Today, these rules live in people's heads, scattered across spreadsheets, or buried in email threads. Someone manually checks each entry, calculates every total, and catches errors after they've already caused problems. Teams waste hours on repetitive calculations and still miss critical validations. Different people apply rules differently, and when that key person is out sick, the whole process breaks down.
The Logic Builder transforms these scattered rules into living, breathing intelligence within your data. No more manual checking if order totals match line items. No more catching date conflicts after schedules are published. No more wondering if the right approver saw that high-value purchase. Your business rules become guardrails that guide every interaction, calculations that update instantly, and approval flows that route themselves. It's about encoding your expertise into the system itself, ensuring consistency across every team member, and building a business that enforces its own best practices automatically.
What is the Logic Builder?
The Logic Builder is a visual interface for creating business logic without code. Through drag-and-drop blocks and intuitive formulas, you define how your data validates, calculates, and flows through your organization.
Build validation rules that prevent errors before they happen, create calculated fields that update automatically, design dynamic forms that adapt based on user input, and establish approval workflows that route themselves. All without writing a single line of code.
Getting Started
Accessing the Logic Builder
The Logic Builder lives within your Dataset configuration, ready to add intelligence to any field. Navigate to your Board and ensure you're in Build Mode—look for the toggle in your left sidebar. Once enabled, click on any column header to reveal configuration options. Depending on the column type and your needs, you'll see options like "Set Validation Logic," "Calculate Value," or "Options Filter Logic."
Each option opens the Logic Builder with a context-appropriate interface. Validation rules present condition builders. Calculated values show formula editors. The builder adapts to your intent, providing the right tools for the task at hand.

Quick Start: Your First Validation Rule in 5 Minutes
Let's build a simple validation rule that ensures project end dates always come after start dates.
Step 1: Enter Build Mode
Navigate to your Board and toggle on Build Mode in the left sidebar.

Step 2: Select Your Field
Click on the "End Date" column header to open configuration options.

Step 3: Add Validation Logic
Click "Set Validation Logic" to open the Logic Builder.

Step 4: Write Your Formula
CurrentValue >= @StartDate

Step 5: Save and Test
Click Save. Try entering an end date before the start date—you'll see an instant validation warning!
💡 Pro Tip: When validation fails, users see a warning signal. (see screenshot below)

🎉 Congratulations! You've just created your first validation rule. This simple rule will save hours of manual checking and prevent timeline conflicts.
Set Validation Operations Reference Table
Input Nodes
Node Type | Description | Use Case | Configuration | Output |
Custom Input | Static/predefined values | Constants, config | Value: "API_KEY_123" | Static value |
Dynamic User Input | Runtime user data | Form inputs | Field: "email", Type: "string" | User-provided value |
Text Operations
Operation | Description | Example | Input | Output |
Formulate Text | Creates text strings based on templates or formulas | Combine variables with static text | Template: "Hello {name}", Variables: {name: "John"} | "Hello John" |
Concatenate | Joins multiple text strings into one | Join first and last name | "Hello", " ", "World" | "Hello World" |
Replace | Finds and replaces text within a string | Replace words in text | Text: "Hello World", Find: "World", Replace: "Universe" | "Hello Universe" |
Uppercase | Converts all characters to uppercase | Convert to capital letters | "hello" | "HELLO" |
Lowercase | Converts all characters to lowercase | Convert to small letters | "HELLO" | "hello" |
Substring | Extracts portion of text | Get first 5 characters | Text: "Hello World", Start: 0, Length: 5 | "Hello" |
Length | Returns character count | Count text length | "Hello" | 5 |
Split | Divides text into array | Split by comma | Text: "apple,banana,orange", Delimiter: "," | ["apple", "banana", "orange"] |
Join | Combines array into string | Join with comma | Array: ["apple", "banana"], Delimiter: "," | "apple,banana" |
Starts With | Checks if text begins with specific characters | Check prefix | Text: "Hello World", Prefix: "Hello" | true |
Ends With | Checks if text ends with specific characters | Check suffix | Text: "Hello World", Suffix: "World" | true |
Index Of | Finds position of substring | Find word position | Text: "Hello World", Search: "World" | 6 |
Pad Start | Adds characters to beginning | Add leading zeros | Text: "5", Length: 3, Pad: "0" | "005" |
Pad End | Adds characters to end | Add trailing zeros | Text: "5", Length: 3, Pad: "0" | "500" |
Repeat | Duplicates text multiple times | Repeat text | Text: "Ha", Count: 3 | "HaHaHa" |
Arithmetic Operations
Operation | Description | Example | Input | Output |
Add | Addition of numbers | Sum values | 5, 3 | 8 |
Subtract | Subtraction of numbers | Find difference | 10, 4 | 6 |
Multiply | Multiplication of numbers | Calculate product | 6, 7 | 42 |
Divide | Division of numbers | Calculate quotient | 20, 4 | 5 |
Modulo | Remainder after division | Find remainder | 10, 3 | 1 |
Round | Round to nearest integer | Round decimal | 3.7 | 4 |
Floor | Round down to integer | Floor value | 3.9 | 3 |
Ceil | Round up to integer | Ceiling value | 3.1 | 4 |
Absolute | Get positive value | Remove negative | -5 | 5 |
Square | Calculate square | Square number | 4 | 16 |
Minimum | Find smallest value | Get minimum | 5, 3, 9 | 3 |
Maximum | Find largest value | Get maximum | 5, 3, 9 | 9 |
Random | Generate random 0-1 | Random decimal | None | 0.7392... |
Random Between | Random in range | Random integer | Min: 1, Max: 10 | 7 |
Advanced Math
Operation | Description | Example | Input | Output |
Power | Raise to power | Calculate exponent | Base: 2, Exponent: 3 | 8 |
Square Root | Calculate square root | Find root | 16 | 4 |
Exponential | Calculate e^x | Natural exponent | 1 | 2.71828... |
Natural Log | Natural logarithm (ln) | Log base e | e (2.71828...) | 1 |
Log10 | Base-10 logarithm | Log base 10 | 100 | 2 |
Log2 | Base-2 logarithm | Log base 2 | 8 | 3 |
Factorial | Calculate factorial | n! | 5 | 120 |
GCD | Greatest Common Divisor | Find GCD | 12, 18 | 6 |
LCM | Least Common Multiple | Find LCM | 4, 6 | 12 |
Array Operations
Operation | Description | Example | Input | Output |
Includes in Array | Check if value exists | Find element | Array: [1,2,3], Value: 2 | true |
Nth Element | Get element at position | Access by index | Array: [10,20,30], Index: 1 | 20 |
First Element | Get first element | Get start | [1,2,3] | 1 |
Last Element | Get last element | Get end | [1,2,3] | 3 |
Slice Array | Extract portion | Get subarray | Array: [1,2,3,4,5], Start: 1, End: 3 | [2,3] |
Reverse Array | Reverse order | Flip array | [1,2,3] | [3,2,1] |
Unique Values | Remove duplicates | Get distinct | [1,2,2,3] | [1,2,3] |
Flatten Array | Convert nested to flat | Flatten nested | [[1,2],[3,4]] | [1,2,3,4] |
Remove Empty | Filter out empty values | Clean array | [1,null,3,"",5] | [1,3,5] |
Count Elements | Total element count | Array length | [1,2,3] | 3 |
Sum of Array | Sum all numbers | Total sum | [1,2,3] | 6 |
Average | Calculate mean | Find average | [2,4,6] | 4 |
Min in Array | Find smallest | Get minimum | [5,2,8] | 2 |
Max in Array | Find largest | Get maximum | [5,2,8] | 8 |
Statistics
Operation | Description | Example | Input | Output |
Median | Find middle value | Get median | [1,3,5] | 3 |
Mode | Most frequent value | Find mode | [1,2,2,3] | 2 |
Std Deviation | Measure of variation | Calculate SD | [2,4,6,8] | 2.58... |
Variance | Average squared differences | Calculate variance | [2,4,6,8] | 6.67 |
Count Non-Empty | Count valid values | Count filled | [1,null,3,"",5] | 3 |
Percentile | Value below % of data | 75th percentile | Array: [1,2,3,4,5], Percentile: 75 | 4 |
Quartile | Divide into quarters | Find quartiles | [1,2,3,4,5,6,7,8] | Q1:2.5, Q2:4.5, Q3:6.5 |
Rank | Assign rank order | Rank values | [5,2,8,2] | [3,1,4,1] |
Correlation | Measure relationship | Find correlation | X: [1,2,3], Y: [2,4,6] | 1.0 |
Forecast | Predict future values | Project trend | Historical: [10,15,20], Periods: 2 | [25,30] |
Trend | Identify direction | Find trend | [10,15,20,25] | "increasing" |
Growth Rate | Calculate % change | Find growth | Start: 100, End: 150 | 50% |
Date/Time Operations
Operation | Description | Example | Input | Output |
Date Add | Add time to date | Add days | Date: "2024-01-01", Add: 7, Unit: "days" | "2024-01-08" |
Date Subtract | Subtract time/find difference | Subtract days | Date: "2024-01-08", Subtract: 7, Unit: "days" | "2024-01-01" |
Date Format | Change date format | Format date | Date: "2024-01-01", Format: "MMM DD, YYYY" | "Jan 01, 2024" |
Current DateTime | Get current timestamp | Get now | None | "2024-01-15T10:30:00Z" |
Time Subtract | Difference between times | Time elapsed | Start: "10:00", End: "14:30" | "4:30" |
Convert Date | Transform date formats | Convert format | Date: "01/15/2024", To: "ISO" | "2024-01-15" |
Fetch Operations
Operation | Description | Example | Input | Output |
Fetch | Make HTTP requests to external APIs | Get user data | URL: "https://api.example.com/users/123", Method: "GET" | JSON response data |
Logic Operations
Operation | Description | Example | Input | Output |
Condition | Evaluate if-then-else logic | Check user age | If: age >= 18, Then: "Adult", Else: "Minor" | "Adult" or "Minor" |
Branch | Split flow into multiple paths | Route by user type | Input: userType, Branches: ["admin", "user", "guest"] | Routes to matching path |
AI Operations
Operation | Description | Example | Input | Output |
AI Generator | Generate content using AI | Create personalized text | Prompt: "Write a welcome email for {name}", Variables: {name: "John"} | "Dear John, Welcome to our platform..." |
Advanced
Operation | Description | Example | Input | Output |
Code Block | Execute custom JavaScript code | Custom logic implementation | Code: | 20 |
Cast | Convert data types | Type conversion | Value: "123", To: "number" | 123 |
Comparison Operations
Operation | Description | Example | Input | Output |
Contains | Check substring presence | Find text | Text: "Hello World", Search: "World" | true |
Equals | Check exact match | Compare values | Value1: 5, Value2: 5 | true |
Not Equals | Check if different | Not equal | Value1: 5, Value2: 3 | true |
Greater Than | Check if larger | Compare size | Value1: 10, Value2: 5 | true |
Less Than | Check if smaller | Compare size | Value1: 3, Value2: 7 | true |
Greater or Equal | Check if >= | Compare with equal | Value1: 5, Value2: 5 | true |
Less or Equal | Check if <= | Compare with equal | Value1: 3, Value2: 5 | true |
Is Present in List | Check list membership | In list | Value: "apple", List: ["apple","banana"] | true |
Is Empty | Check if null/empty | Check empty | "" | true |
Is Not Empty | Check if has content | Check filled | "Hello" | true |
Length In | Length matches values | Length check | Text: "Hello", Lengths: [5,10] | true |
Length >= | Length at least | Min length | Text: "Hello", Min: 3 | true |
Length <= | Length at most | Max length | Text: "Hi", Max: 5 | true |
Joiners
Operation | Description | Example | Input | Output |
AND | All conditions true | Logical AND | Condition1: true, Condition2: true | true |
OR | Any condition true | Logical OR | Condition1: false, Condition2: true | true |
Encoding/Decoding Operations
Operation | Description | Example | Input | Output |
Base64 Encode | Convert to Base64 | Encode text | "Hello" | "SGVsbG8=" |
Base64 Decode | Convert from Base64 | Decode text | "SGVsbG8=" | "Hello" |
URL Encode | Encode for URLs | URL safe | "hello world" | "hello%20world" |
URL Decode | Decode from URLs | URL decode | "hello%20world" | "hello world" |
HTML Encode | Convert HTML entities | HTML safe | "<div>" | "<div>" |
HTML Decode | Decode HTML entities | HTML decode | "<div>" | "<div>" |
Encode (Generic) | Custom encoding | Custom encode | Text: "data", Algorithm: "custom" | Encoded output |
Decode (Generic) | Custom decoding | Custom decode | Encoded: "data", Algorithm: "custom" | Decoded output |
Hash & Crypto
Operation | Description | Example | Input | Output |
MD5 Hash | Generate MD5 hash | Hash text | "password" | "5f4dcc3b5aa765d61d8327deb882cf99" |
SHA1 Hash | Generate SHA1 hash | Hash text | "password" | "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" |
SHA256 Hash | Generate SHA256 hash | Hash text | "password" | "5e884898da28047151d0e56f8dc62927..." |
Hash (Config) | Configurable hash | Custom hash | Text: "data", Algorithm: "SHA512" | Hash output |
Encrypt | Encrypt data | Secure data | Data: "secret", Key: "key123" | Encrypted string |
Decrypt | Decrypt data | Decode data | Encrypted: "xyz", Key: "key123" | "secret" |
Utility Operations
Operation | Description | Example | Input | Output |
Sleep/Delay | Pause execution | Wait 1 second | Duration: 1000ms | Pauses flow |
Throttle | Limit execution rate | Max 1 per second | Interval: 1000ms | Rate limited execution |
Delay | Pause execution for specified time | Delay 2 seconds | Time: 2000ms | Execution paused |
Debounce | Delay until idle | Wait for pause | Wait: 500ms | Delayed execution |
Memoize/Cache | Store for reuse | Cache result | Key: "calc1", Value: Result | Cached value |
Security Operation | Apply security checks | Validate input | Input: User data | Validated/Sanitized |
Utility Operation | General purpose | Custom logic | Various inputs | Custom output |
UUID Generator | Generate unique ID | Create UUID | None | "550e8400-e29b-41d4-a716-446655440000" |
Logic Builder Types
1. Validation Rules
Validation rules are your data quality guardians. Every typo, every impossible date, every out-of-range value that enters your system creates a ripple effect—reports show wrong numbers, automations fail, teams make decisions on bad data. That invoice with a negative amount. The project end date before it started. The order quantity exceeding your entire inventory. Validation rules catch these errors at the source, preventing bad data from ever entering your system and eliminating hours of cleanup work.
Building Validation Logic
When you click "Set Validation Logic" on a field, the Logic Builder presents a formula editor where you'll define your rule. You can set validation for different scenarios:
Set Ongoing Validation Logic applies rules to data updates and modifications after the record exists. This ensures data integrity is maintained throughout the record's lifecycle.
Set Insert Validation Logic validates data only when new records are first created. Use this for rules that should apply during creation but may be relaxed for updates.

Reference other fields using the @ symbol—@FieldName pulls values from the same record. Use comparison operators (>, <, ==, !=) and logical operators (AND, OR, NOT) to build complex conditions.
A simple validation to ensure a task assignee is different from the task creator (preventing self-assignment):
CurrentValue != @CreatedBy

2. Calculated Values
Calculated fields bring spreadsheet-style intelligence directly into your database. Today, your team manually calculates totals, updates percentages, and adjusts prices—each calculation a chance for error, each update taking precious minutes. That commission spreadsheet maintained outside the system. Project percentages updated manually every Friday. Pricing formulas only Sarah knows. Calculated values automate these computations, ensuring every total is accurate, every percentage updates instantly, and formulas apply consistently regardless of who's working.
Calculation Triggers
Control when calculations execute by choosing the appropriate trigger:
On Row Creation runs once when a record is created. Perfect for setting initial values like default priorities or generating unique identifiers. The calculation locks in that initial value and doesn't change unless manually edited.
On Focus recalculates whenever a user clicks into the field. Ideal for values that might change based on other edits but don't need constant updates. A "Days Until Due" field might recalculate each time someone views it.
On Edit updates whenever dependent fields change. Your bread and butter for most calculations—totals that sum line items, markups that adjust with costs, scores that aggregate multiple factors. The calculation runs automatically, keeping values synchronized.
On Click waits for explicit user action. Place a calculate button in the field for expensive operations or when you want users to control timing. Useful for complex calculations that call external services or when you need to snapshot values at specific moments.
Always continuously recalculates in real-time as any dependent data changes. Best for critical metrics that must stay current, like inventory levels or live dashboard totals. Use sparingly as it can impact performance with complex calculations.
Never prevents automatic calculation entirely. The field can only be updated through manual entry or explicit actions. Useful for values you want to calculate once and preserve, or fields that serve as manual overrides to calculated values.
Formula Syntax
The Logic Builder speaks a language similar to spreadsheet formulas but with database awareness. Reference fields with @FieldName. Use standard operators (+, -, *, /) and parentheses for order of operations.
Format dates for display:
DATE_FORMAT(@DueDate, "YYYY-MM-DD HH:MM:ss") // Output: Jan 15, 2025 05:12:45

Chained Calculations
Calculated fields can reference other calculated fields, creating sophisticated derived data. A "Subtotal" field sums line items. A "Tax" field calculates from the subtotal. A "Total" field adds them together. Change any input, and the entire chain updates automatically.
⚠️ Warning: Circular references (A→B→C→A) will prevent your logic from saving. Always design calculation flows in one direction.
3. Options Filter Logic
Static forms frustrate users with irrelevant options. A purchase order form showing IT vendors when buying office supplies. A task assignment dropdown listing employees from other departments. These cluttered interfaces slow work and increase errors. Options Filter Logic transforms your drop downs and reference fields into intelligent selectors that adapt based on context, showing only the choices that make sense.
Department-Based Expense Categories
Filter expense categories based on selected department:
//Show only relevant expense types for each department
IF(@Department == "Sales",
SHOW_OPTIONS(["Travel", "Meals", "Hotels"]),
IF(@Department == "IT",
SHOW_OPTIONS(["Software", "Hardware", "Cloud Services"]),
SHOW_OPTIONS(["Office Supplies", "Other"]))) //All other departments
This basic example shows how selecting "Sales" in the Department field instantly updates the Expense Category dropdown to show only sales-related options, while selecting "IT" shows technology expenses. Clean, simple, and prevents incorrect categorization.
4. Approval Workflows
Approval workflows ensure critical decisions follow proper authorization chains. Right now, high-value purchases slip through without oversight, urgent requests sit in email inboxes, and no one knows if that $50,000 order got approved. Someone circumvents the process because they don't know the rules. Requests bounce between departments with unclear ownership. The Logic Builder's approval conditions automatically route requests to the right people, enforce your authorization policies, and ensure nothing falls through the cracks—turning chaos into a smooth, predictable flow.
Manager Approval with User Validation
Set approval condition to ensure only the designated manager who is logged in can approve the requests:

Best Practices
Design Principles
Start Simple, Iterate Complexity — Begin with basic rules that handle the common case. A validation checking dates might start as @EndDate > @StartDate
. As you discover edge cases, enhance it: account for timezone differences, business days only, or blackout periods. Each iteration makes your logic more robust without overwhelming initial implementation.
Make Logic Self-Documenting — Future maintainers (including yourself) need to understand your logic's intent. Use clear field names: @CustomerAcquisitionDate
beats @Date1
. Structure complex formulas with line breaks and indentation. Add comments in description fields explaining business reasoning, not just technical implementation.
Design for Change — Business rules evolve. Hard-coding values creates brittleness. Instead of IF(@Amount > 5000, "Requires Approval", "Auto-Approved")
, reference a configuration field: IF(@Amount > @ApprovalThreshold, "Requires Approval", "Auto-Approved")
. When thresholds change, update one field instead of hunting through dozens of formulas.
Testing Strategies
🧪 Test Data Best Practice: Create a dedicated "Test Workspace" with sample data covering all edge cases. Reset it monthly to maintain a clean testing environment.
Test Edge Cases — Your logic works for typical values, but what about extremes? Test with zero, negative numbers, very large values. Try empty fields, special characters in text, dates far in the past or future. If your formula divides by a field, what happens when it's zero?
Validate Cross-Field Dependencies — When fields depend on each other, test all combinations. If status determines which fields are required, check every status. If calculations chain together, verify the entire flow from input to final result. One broken link breaks the entire chain.
Use Test Records — Create dedicated test records to verify logic without affecting real data. Name them clearly: "TEST - Do Not Delete - Validation Testing". Build a suite covering your main scenarios. Run through them after major logic changes to ensure nothing broke.
Maintenance
Version Control Through Documentation — While the Logic Builder doesn't version formulas, you can track changes manually. Before modifying complex logic, copy the current formula to the field description with a date stamp. This creates an audit trail and recovery path if changes introduce issues.
Monitor Performance Impact — Complex calculations on large datasets can slow your system. If users report sluggish forms, review your logic. Consider moving expensive calculations from "On Edit" to "On Focus" or "On Click". Sometimes splitting one complex calculation into several simpler ones improves performance.
Regular Logic Audits — Schedule quarterly reviews of your logic rules. Business processes change, making some rules obsolete. New patterns emerge that could be automated. Logic that seemed clear six months ago might need documentation updates. These audits keep your system aligned with actual business needs.
Troubleshooting
Common Issues
"Circular Reference Detected"
This error appears when fields reference each other in a loop. Field A depends on Field B, which depends on Field C, which depends on Field A. The Logic Builder prevents saving such configurations.
Solution: Map out field dependencies on paper. Identify the cycle. Usually, one calculation should be "primary" with others deriving from it. Restructure your logic to flow in one direction.
Validation Always Fails
Your validation logic might be too restrictive or checking the wrong condition. Common culprits include comparing different data types (text vs number), timezone mismatches in date comparisons, or logic that can never evaluate to true.
Solution: Temporarily simplify your validation to isolate the issue. Start with true
(allows everything), then add conditions one by one until you find the problem. Check data types match on both sides of comparisons.
Calculations Show Wrong Results
Suspect order of operations issues, incorrect field references, or data type mismatches. The formula might be correct but operating on unexpected values.
Solution: Break complex calculations into steps. Create temporary calculated fields for each sub-calculation. This shows intermediate values, making it easier to spot where things go wrong. Check that referenced fields contain the expected data type and format.
Options Not Filtering
Dynamic filters might reference the wrong fields, use incorrect syntax, or have logic that never matches actual data.
Solution: Log the values being compared. Add a calculated field showing @Category + " | " + @Subcategory
to see actual values. Ensure your filter conditions match these exactly, including case sensitivity and spacing.
Performance Issues
Slow Form Loading
Too many "On Edit" calculations can make forms sluggish. Each keystroke triggers recalculation of dependent fields.
Solution: Audit your calculation triggers. Move non-critical calculations to "On Focus" or "On Click". Consider whether some calculated values could be computed during a nightly batch process instead of real-time.
Timeout Errors
Extremely complex logic or calculations over large datasets might exceed processing limits.
Solution: Simplify nested IF statements using lookup tables. Instead of 20 nested conditions for pricing tiers, create a Pricing Tiers dataset and use a reference field. Break monolithic calculations into smaller, focused pieces.
Next Steps
Explore related Proma features that enhance automation capabilities:
@Automation Engine - Orchestrates multi-step workflows using Logic Builder's validated and calculated data.
@Smart Columns - Add intelligent, automated fields to your datasets
@Interfaces - Build custom user interfaces that trigger and display automations
Have questions? Our team is ready to help at [email protected]