Task Templates

Conditions

← Back to Task Templates

A condition is a boolean check the system evaluates against the live reservation, guest, property, teammate, or message-thread state. Conditions appear in two places:

  1. Trigger conditionsshould this template fire at all for this reservation?
  2. Auto-resolve conditionsshould this scheduled task actually run when its time comes?

Shape

{
  "property": "reservation.nukiAccessCode",
  "operator": "is_not_null",
  "value": null,
  "notifyOnNotMet": true
}
  • property — the entity.field to read (uses the same namespacing as placeholders).
  • operator — one of equals, notEquals, in, notIn, is_null, is_not_null, greaterThan, lessThan, contains, startsWith.
  • value — comparison value (literal or another placeholder reference).
  • notifyOnNotMet — only meaningful for auto-resolve conditions; when true, the operator gets a WhatsApp ping at fire time if the condition fails.

Multiple conditions are AND-combined.

Common conditions

Pre-fire (Send Check-in)

reservation.nukiAccessCode is_not_null

"Don't send the check-in message until the PIN has been generated."

Pre-fire (Pre-checkout reminder)

messageThread.hasUnansweredGuestMessage equals false

"Don't send the pre-checkout reminder if the guest has an open question — answer them first."

Pre-fire (Thank-you message)

reservation.guestMood notIn ['angry', 'disputed']

"Only send a warm thank-you if the guest isn't visibly upset."

Pre-fire (Generate access code)

reservation.status notIn ['cancelled', 'no_show']

"Don't provision a PIN for a cancelled reservation."

Sequenced auto-resolve

task.dependencies.allDone equals true

"Wait until all dependent tasks complete first."

When a condition is met / not met

At evaluation time:

  1. The runtime walks the property path the same way placeholders do.
  2. Compares against value using operator.
  3. Returns true / false.

If false:

  • Trigger conditions → the template doesn't fire for this reservation; no task is created.
  • Auto-resolve conditions → the task stays in scheduled status; if notifyOnNotMet: true, the operator is notified.

In both cases, the failure is logged to app_errors with enough context to debug.

Adding a new property to the catalogue

Developer task: add the field to platformCapabilities.ts. The editor's condition picker reads from that file at startup. Operators don't need to do anything — once the developer ships the change, the new property appears in the condition picker on next reload.

A note on data quality

A condition that reads from data the system never populates is just a permanently-false gate. Common examples:

  • reservation.guestMood — only populated after the LLM mood-analyser has run on at least one inbound guest message. New reservations with no inbound messages have guestMood = NULL.
  • reservation.guestCommunicationType — same as guestMood.
  • reservation.earlyCheckinTime — only set if the guest or operator explicitly requested early check-in; otherwise NULL.

Use is_not_null / is_null operators when you're not sure the field is always populated, and consider a fallback chain in placeholders.


  • #214 — condition status surfaced on task cards.
  • #260reservation.nukiAccessCode is_not_null condition reads from canonical guest row (JOIN disambiguation).
  • #180 — silent-skip → failed; conditions are now the authoritative truth.
Source: the FlatsBratislava operator manual.