Data validations

Data validation allows you to define rules for your fields, including acceptable value ranges.

Validation Properties

If validate field is set in schema, validation rules will be applied to the field value. The data type of the field is an array of maps, with expr and action defined. The action will be evaluated when the expr returns true.

PropertyTypeScripting LanguageDescription
exprstringCELAn expression in CEL Script
scriptstringJavaScriptThe JavaScript code to evaluate for validation
actionstring-allow or deny
error_messagestring-A string of error message to be returned when the validation fails

Notes:

  • The validation rules are evaluated in descending order
  • expr cannot access the fields provided through sourceId association

If Validate field is set in schema, validation rules will be applied to the field value. The data type of the field is an array of maps, with Expr and Action defined. The Action will be evaluated when the Expr returns true.

PropertyTypeScripting LanguageDescription
ExprstringCEL / JavaScriptAn expression in CEL Script or JavaScript
Actionstring-tailordb.#Permit.Allow or tailordb.#Permit.Deny
ErrorMessagestring-A string of error message to be returned when the validation fails

Notes:

  • The validation rules are evaluated in descending order
  • Expr cannot access the fields provided through SourceId association

Examples

<span><span style="color: var(--shiki-color-text)">reportNumber  </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  type          </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;integer&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  validate      </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// reportNumber value must be less than 100 or over 103</span></span>
<span><span style="color: var(--shiki-color-text)">    {</span></span>
<span><span style="color: var(--shiki-color-text)">      script        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;((value, data) =&gt; { return value &gt;=100 &amp;&amp; value &lt;=103})(_value, _data)&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">      action        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;deny&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">      error_message </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;reportNumber value must be less than 100 or over 103&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">description </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  type        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;string&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  description </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;Description of the product.&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  validate    </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [{</span></span>
<span><span style="color: var(--shiki-color-text)">    script        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;((value, data) =&gt; { return !(value.length &lt; 40)})(_value, _data)&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    action        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;deny&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    error_message </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;Description length should be less than 40 characters.&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">itemStatus </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  type     </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;string&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  validate </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [{</span></span>
<span><span style="color: var(--shiki-color-text)">    script        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;((value, data) =&gt; { return Object.keys(user).length === 0 })(_value, _data)&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    action        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;deny&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    error_message </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-string-expression)">&quot;You must be logged in to create an item&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">reportNumber</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Type</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.#TypeInt</span></span>
<span><span style="color: var(--shiki-color-text)">  Validate</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> [</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// reportNumber value must be less than 100 or over 103</span></span>
<span><span style="color: var(--shiki-color-text)">    {</span></span>
<span><span style="color: var(--shiki-color-text)">      Script</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">common</span><span style="color: var(--shiki-color-text)">.#Script </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        Expr</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">          ((value, data) =&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">            return value </span><span style="color: var(--shiki-token-keyword)">&gt;=</span><span style="color: var(--shiki-token-constant)">100</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">&amp;&amp;</span><span style="color: var(--shiki-color-text)"> value </span><span style="color: var(--shiki-token-keyword)">&lt;=</span><span style="color: var(--shiki-token-constant)">103</span></span>
<span><span style="color: var(--shiki-color-text)">          })(_value</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> _data)</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-string-expression)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      }</span></span>
<span><span style="color: var(--shiki-color-text)">      Action: </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">#Permit</span><span style="color: var(--shiki-color-text)">.Deny</span></span>
<span><span style="color: var(--shiki-color-text)">      ErrorMessage: </span><span style="color: var(--shiki-token-string-expression)">&quot;reportNumber value must be less than 100 or over 103&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">description</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Type</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.#TypeString</span></span>
<span><span style="color: var(--shiki-color-text)">  Description</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;Description of the product.&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Validate</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> [{</span></span>
<span><span style="color: var(--shiki-color-text)">    Script</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">common</span><span style="color: var(--shiki-color-text)">.#Script </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      Expr</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">        ((value, data) =&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">          </span><span style="color: var(--shiki-token-function)">return</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">value</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">length</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">&lt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">40</span><span style="color: var(--shiki-color-text)">)</span></span>
<span><span style="color: var(--shiki-color-text)">        })(_value</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> _data)</span></span>
<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-string-expression)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">    Action: </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">#Permit</span><span style="color: var(--shiki-color-text)">.Deny</span></span>
<span><span style="color: var(--shiki-color-text)">    ErrorMessage: </span><span style="color: var(--shiki-token-string-expression)">&quot;Description length should be less than 40 characters.&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">itemStatus</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Type</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.#TypeString</span></span>
<span><span style="color: var(--shiki-color-text)">  Validate</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> [{</span></span>
<span><span style="color: var(--shiki-color-text)">    Script</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">common</span><span style="color: var(--shiki-color-text)">.#Script </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      Expr</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">        ((value, data) =&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">          return </span><span style="color: var(--shiki-token-constant)">Object</span><span style="color: var(--shiki-token-function)">.keys</span><span style="color: var(--shiki-color-text)">(user).</span><span style="color: var(--shiki-token-constant)">length</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">===</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">0</span></span>
<span><span style="color: var(--shiki-color-text)">        })(_value</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> _data)</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-string-expression)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      }</span></span>
<span><span style="color: var(--shiki-color-text)">    Action:       </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">#Permit</span><span style="color: var(--shiki-color-text)">.Deny</span></span>
<span><span style="color: var(--shiki-color-text)">    ErrorMessage: </span><span style="color: var(--shiki-token-string-expression)">&quot;You must be logged in to create an item&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Example demonstrating how to use user attributes

<span><span style="color: var(--shiki-color-text)">itemCode </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  type     </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;string&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  validate </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [{</span></span>
<span><span style="color: var(--shiki-color-text)">    script        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;((value, data) =&gt; { return !user.attributes.includes(\&quot;{ADMIN_ID}\&quot;) })(_value, _data)&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    action        </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;deny&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    error_message </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-string-expression)">&quot;To create an item, you must be the Admin&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">itemCode</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Type</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.#TypeString</span></span>
<span><span style="color: var(--shiki-color-text)">  Validate</span><span style="color: var(--shiki-token-punctuation)">:</span><span style="color: var(--shiki-color-text)"> [</span></span>
<span><span style="color: var(--shiki-color-text)">    {</span></span>
<span><span style="color: var(--shiki-color-text)">      Script</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">common</span><span style="color: var(--shiki-color-text)">.#Script </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        Expr</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">          ((value, data) =&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">            return </span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-token-constant)">user</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">attributes</span><span style="color: var(--shiki-token-function)">.includes</span><span style="color: var(--shiki-color-text)">(\</span><span style="color: var(--shiki-token-string-expression)">&quot;{ADMIN_ID}\&quot;)</span></span>
<span><span style="color: var(--shiki-color-text)">          })(_value</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> _data)</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-string-expression)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      }</span></span>
<span><span style="color: var(--shiki-color-text)">      Action:       </span><span style="color: var(--shiki-token-constant)">tailordb</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">#Permit</span><span style="color: var(--shiki-color-text)">.Deny</span></span>
<span><span style="color: var(--shiki-color-text)">      ErrorMessage: </span><span style="color: var(--shiki-token-string-expression)">&quot;To create an item, you must be the Admin&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Accessible variables in expressions

You can use _value to refer to the current field value and _data to refer to the entire record.

VariableDescription
_valueThis accesses its own field value.
_data.{other_field_name}Other fields can be accessed using the field name. ex. foo == 2 accesses foo field
_data.{array_name}[{index}]This accesses the array value. ex. arr[0] accesses the first value of arr
_data.{associative_array_name}.{key_name}This accesses associative array value. ex. dict.nestedValue accesses the dict associative array's nestedValue key value
userThis accesses the user context. ex. user.id accesses the logged in user id and user.attributes acessess user's attributes which is an array of UUIDs that are configured in the AttributesFields in the Auth service

Embedded functions in expressions

FunctionDescription
today()returns today's date in String, with format YYYY-MM-DD. ex. today() => "2024-07-02"
currentHHMM()returns the current time in String, with format HH:MM. ex. "21:37"
timeHH(int)returns the hours in int from the provided time. ex. timeHH("1213") => 12
timeMM(int)returns the minutes in int from the provided time. ex. timeMM("1213") => 13
startWith(string, string)returns the Boolean value which is the result of string prefix match. ex. startWith("hello world", "hello") => true
endWith(string, string)returns the Boolean value which is the result of string suffix match. ex. endWith("hello world", "world") => true
length(string)returns the int which is the length of the string. ex. length("12345") => 5