Actions
An action is what runs when a task completes (manually or via auto-resolve). Actions are autodiscovered from the tRPC mutation registry, so every public mutation that has .meta({ description: "..." }) is selectable in the editor.
Common actions
Communication
| Action | What it does |
|---|---|
whatsapp.sendTemplate |
Send an approved WhatsApp template to the guest's phone |
whatsapp.sendFreeText |
Send a free-text WhatsApp message (only inside the 24h window) |
whatsapp.sendInteractiveButtons |
Send a template with up-to-3 button replies |
report.sendReply |
AI-draft a reply to the most recent inbound guest message and send it |
report.sendOperatorNotification |
Send a WhatsApp notification to the operator (you) |
Smart lock
| Action | What it does |
|---|---|
nuki.generateCode |
Provision a Nuki PIN for the reservation, write to canonical guest row |
nuki.revokeCode |
Revoke a Nuki PIN |
nuki.regenerateCode |
Revoke + provision a new PIN (use only on guests ≥30 days past — see Access Codes Safety) |
Guidebook & docs
| Action | What it does |
|---|---|
guidebook.generate |
Produce the per-stay guidebook PDF and store it |
guidebook.send |
Send the guidebook URL to the guest |
invoice.generate |
Generate an invoice PDF |
invoice.email |
Email an invoice to the guest |
Operations
| Action | What it does |
|---|---|
cleaner.assign |
Assign a cleaner to the cleaning task for a reservation (post-#171, respects May-16 unassignment guard) |
task.complete |
Mark another task done (used when one task gates another) |
task.snooze |
Push the due time forward |
reservation.flag |
Tag a reservation for follow-up (e.g. disputed, vip) |
What params an action exposes
The action's tRPC mutation declares a Zod schema for its input. The editor reads the schema and renders a form field per param. After #149, only operator-meaningful params are surfaced — internal telemetry params (aiOriginalBody, aiGuestMessageBody) marked [internal] in .describe() are hidden.
If you find a leak (an internal-looking param showing in the form), file a bug; the ratchet test at server/tests/actionDiscoveryRatchet.test.ts should catch it in CI but won't catch newly-added fields until they're triaged.
Adding a new action
Developer task — see CLAUDE.md section tRPC Procedures. Quick summary: add a tRPC mutation with .meta({ description: "..." }) and operator-meaningful Zod params. It appears in the action picker on next backend restart.
Related issues
- #149 — operator-meaningful params surface; internal telemetry hidden.
- #171 —
cleaner.assignhonours May-16 unassignment fix. - #180 — every action that internally skips now returns
skipped: truewith a reason instead of silent success. - #185 —
Add FAQ entryaction fired withProperty not foundafter schema regression.