Release Notes — Week of 2026-06-06
Spanning Mon 2026-06-01 → Sat 2026-06-06. 60 commits across ~14 areas. This release adds a complete workflow debugger and retry-from-step, gives Dashboards their own RBAC module with role-based sharing, reworks the booking flow (host picker + team fallback + submit actions), tiered approval rules, transfer-on-deactivate for users, plus a long list of fixes.
Four tenant migrations ship with this release. Run them on prod with:
npx ts-node apps/api/src/scripts/run-tenant-migrations.ts
| Migration | Adds |
|---|---|
| 077 | Task expiry marker + form recipient routing + account doc visibility rollup |
| 078 | users.exclude_from_lead_assignment flag |
| 079 | Workflow run debug columns (filter_evaluation, payload_in, config_snapshot, retried_from_step_id) |
| 080 | Dashboards RBAC module + role-sharing tables |
Workflows / Automation
The deepest changes this week. The Workflow Builder doc was rewritten end-to-end with the full filter and action reference.
Debugging & retry
- Filter evaluation tree on every run — see exactly which condition matched and which value was used.
payloadIn+configSnapshotcaptured per step so you can replay with the same state.- "Retry from here" retries a single step onwards using its captured payload; "Retry run" replays the whole run.
- New run status
completed_with_errors— individual step failures no longer abort the run. Downstream steps still execute and the run is flagged for review.
New triggers
- Scheduled (cron) triggers — set a cron + timezone + entity scan filter; the sweeper fires the workflow once per matched row on every tick. Includes a [Validate Cron] endpoint, [Preview matches], [Run now], and three starter templates (Dormant Lead 20d, Dormant Account 90d, Stale Opp 30d).
task_expired— fires from the hourly task-expiry cron when a task's due date passes.
New actions
router— switch with N labelled paths; first match wins, with a default lane.create_account,create_contact,convert_lead— close the loop on lead-to-CRM automations from forms / imports.
Action upgrades
assign_owner—skipIfOwnerSetguard, multi-team pool (teamIds[]),all_activepool mode, retain previous owner as a read-only record team member, leads pool drops users flaggedexclude_from_lead_assignment.create_task— newstage_ownerassignee mode (resolves viarecord_stage_assignments→ stage config → record owner); Google Calendar mirror; resolved-context error message on FK failures.update_field— supports custom fields (JSONB), type-aware values, hardened SQL allowlist per module.send_email— expandedtooptions:account_email,primary_contact_email,assigned_user_email,manager_email,trigger_user_email; sender provider override; rich-text body editor; template picker from the new Email Templates module.send_notification— newtomodes:manager,team,multiple_users,role,all_admins.add_to_email_list— multi-provider support (lists tagged with their provider in the picker).- Trigger filter values — lookup-backed dropdowns; boolean custom fields render Yes/No.
Audit + change detection
previousValuesnow propagated from every entity service (leads / contacts / accounts / opportunities / tasks / projects), and the runner normalises camel + snake key forms.changed_to,changed_from, andany_changenow reliably work everywhere.- Bug fix:
lead_stage_changedwasn't firing when the stage was changed from the lead journey bar — fixed.
UX fixes
- AddActionMenu portalled out of the canvas transform so it doesn't clip.
- Branch lanes full-width, action chips inside Yes / No lanes are now readable.
Dashboards
Dashboards now own their RBAC and sharing model — independent of Reports.
- New RBAC module:
dashboardswithview,create,edit,delete,share_role,share_public. Migration 080 mirrors existing role permissions so behaviour stays the same until you tune it. - Role-based sharing — share a dashboard with one or more roles; each user gets a clone-on-first-view so they can tweak filters without affecting other members of the role.
- Auto-seed — default dashboards are seeded for new users on create, on invite-accept, and lazily on first read.
- ShareDashboardModal — two tabs (Roles / Public Link), each independently RBAC-gated.
- Scope picker — was decorative; now actually filters, intersected with the user's record-access scope.
- Per-widget date range — replaces the old hardcoded
created_at. Each widget picks its own date column. - New builder controls —
refreshInterval,reportType(table widgets),trendField,trendGranularity,rankBy,colorScheme,sliderStep,projectionMeasure,baseSeriesLabel,projectedSeriesLabel. Imports are now lossless. - Tab context menu — Set as default, Tab settings (date range / scope defaults + options).
Users / RBAC
- Transfer owned records on deactivate / delete — atomic transaction that re-assigns leads, opportunities, contacts, accounts, tasks, projects, subscriptions, and booking forms before the user is removed. See Users Management.
exclude_from_lead_assignmentflag on the user record — workflowassign_owner(any pool mode) drops these users from the lead pool. Useful for managers / finance who sit on team rosters but should never be routed leads.- Self-access — users can view and edit their own profile and availability without
users:view. - Record-level scope for
project_time_entries(edit / delete) — see Record Access. - Stage Owner runtime resolution — runtime stage-owner lookup now powers a new
stage_ownerassignee on workflowcreate_task. See Stage Ownership.
Bookings / Forms
- Host picker in booking forms with team fallback — when no specific members are chosen, the booking is offered to every active member of the team.
- Submit actions now run on booking — the lead / contact / account is created via the same submit-action chain forms use, with the lead/contact owner defaulting to the booking host (a workflow
assign_ownercan still override). - Pick-a-slot vs auto-book mode + team round-robin.
- Booking forms route to
/book/everywhere; team members auto-select. - Actions tab now exposed on
meeting_bookingforms. - E.164 phone validation with intl country picker.
- Lookup field type for system-managed lists (industries, countries, etc.).
- New submit action:
add_to_email_list, plus sender control onsend_emailsubmit actions. - Forms tab on Opportunities + Leads detail pages.
- "Filled by" submission badges so you can see at a glance which user / portal submitted each form.
- Drafts and inactive forms are no longer hidden from entity pages.
See Form Builder, Scheduling Overview.
Leads / Lead Scoring / SLA
- Rule-based duplicate detection v2 with manager notification when a duplicate is detected during create / import.
- Multi-select for
in/not_inoperators on dropdown fields. older_thanoperator forces a days input (no more free-form date string).- Standard-field dropdowns now load industries and sources from the live config.
- Scoring decay fix — older signals correctly weighted down.
- SLA cursor fix — the working-hours iterator was getting stuck at the same time-of-day; resolved.
See Lead Settings, Lead Scoring & SLA.
Opportunities / Stages
- Stage name / colour / probability are now editable inline with an atomic auto-rebalance of dependent probabilities.
- Won and Lost terminal stages are editable and accept field-config.
- Stage change accepts
stageFieldsalias, stripscustom.prefix on persist, parses JSONB-as-string in the validator, and resolvescustom.*keys correctly. - Documents tab SQL fix.
See Opportunity Settings.
Approvals
- Tiered approval rules with min / max discount range — different approvers for 5–10%, 10–25%, 25%+ discounts.
- Generic match conditions per trigger event — same condition group syntax as workflows.
- Dynamic attribute picker on conditions — the field list is pulled from the entity schema instead of a hardcoded list.
See Approval Rules.
Email / Templates / Marketing
- Email Templates admin module + template picker on notification and workflow
send_emailconfigs + rich-text body editor. - Multi-provider email-marketing lists — lists are tagged with their provider (MailerLite / Mailchimp) in the picker so admins can pick the right list when both are connected.
- Custom SMTP test-email button — verify SMTP from the integration page without leaving the UI.
- Sender-account from-address now visible in the picker.
send_notificationwas writing to a non-existent column; fixed.
See Notification Templates, Email Marketing, Email Setup.
Targets / Gamification
- KAM metrics wired into target compute + scoped triggers.
- Duration dropdown instead of raw period count — pick "1 month", "1 quarter", etc.
- Persistent role-scope templates with auto-expand on user lifecycle events (joiners / leavers / role changes).
- Performance dashboard backend + EOD recap cron.
See Targets Setup, Gamification & Badges.
Customer Success
- Account tiers (Strategic / Enterprise / Growth / SMB, configurable).
- QBR cadence config per tier.
- Tunable churn signals with per-signal weights and thresholds.
- Customer-success workflow templates for tier-based re-engagement.
See Customer Success Settings, Customer 360.
Lead Import
- Opt-in workflow triggers per import job — a checkbox on the import wizard decides whether imported rows fire
lead_createdworkflows. Default: off, so a 5,000-row import doesn't fan out into 5,000 workflow runs by accident.
See Importing Leads.
Projects
- Custom fields end-to-end on projects.
- Calendar tasks (CRM tasks linked to project tasks) shown on the project calendar.
- Server-side time-entry edit / delete with new
project_time_entriesRBAC module. getTemplatesrows now camelCased so theisActivefilter works.
Field Validation / Form Builder
- All four module registries (leads / opps / accounts / contacts) corrected.
- Custom fields are now loaded into validation rules.
- Field-validation persist now sends the full DTO with a better fallback message.
- Drag-reorder for custom fields within a tab.
Infrastructure
- Tenants table schema fix.
workboxprecache limit bumped to 10 MiB (the bundle had outgrown 5 MiB).- Missing
Sendicon import on the Custom SMTP test-email button — fixed. - Account documents rollup now respects visibility flags from the source modules.
- Form recipient tracking persisted on submissions.