Approvals

Tiered approval for large opportunities — what triggers it, who approves at each tier, and what happens on approve/reject.

Approvals

HotCRM ships with one built-in approval: the Opportunity Approval flow. It enforces a tiered "extra pairs of eyes" rule on large deals so no rep can commit a big-ticket opportunity without the right level of sign-off.

Since ObjectStack 7.4 this is modeled as a flow with approval nodes (ADR-0019), not a standalone approval-process object. The flow chains the approval steps, locks the record while a step is pending, and mirrors the live decision onto the opportunity's approval_status field. Auto-launch requires the triggers capability (see Administration › Automation).

What triggers an approval

The flow runs automatically when an opportunity is saved and its amount reaches a threshold — no manual "submit" step:

  • Amount $100K or moreSales Manager review.
  • Amount > $500KSales Manager review and Sales Director sign-off.

Under $100K, no approval is needed — the rep can progress the deal directly. The manager line is inclusive: a deal at exactly $100,000 does route for approval. The entry guard (approval_status = not_required) means the flow's own status writes don't re-trigger it.

The tiered process

TierApproverApplies whenWhy
1. Sales ManagerThe sales_manager roleAmount $100K or moreFirst line of defense — sanity-check the deal
2. Sales DirectorThe sales_director roleAmount > $500KFinal sign-off — protect company margin on the largest deals

A > $500K deal goes Manager → (decision gate) → Director. A $100K–$500K deal needs only the Manager. Rejection at either tier ends the run as rejected and notifies the owner.

What submitters see

When a rep saves an opportunity whose amount reaches the threshold, the flow submits it automatically:

  1. The opportunity is locked — the approval node holds the record until the step resolves.
  2. approval_status flips to pending (shown as In Approval).
  3. The first approver gets an in-app notification and email.

There's no separate "Submit for Approval" click — reaching the amount threshold on save is the trigger.

What approvers see

Each approver receives:

  • An email with the opportunity summary, amount, account, stage, and the submitter's comment.
  • An in-app task in their Approval Inbox.
  • A one-click Approve / Reject with a comment box.

Approvers can also delegate during PTO (configured in their profile).

First-response behavior

The process uses first-response behavior — the first approver to respond at each step (in case of delegates or multiple eligible approvers) decides the outcome. No "wait for all" voting.

What happens on each outcome

✅ Approved (all required tiers)

  1. The opportunity is unlocked.
  2. approval_status is stamped approved and approved_date is set to today.
  3. The owner is notified ("Deal approved").

❌ Rejected (at any tier)

  • The run ends immediately as rejected — a reject at the Manager tier never reaches the Director.
  • approval_status is stamped rejected and the owner is notified to revise and resubmit.
  • The rejection is captured in the approval request's history.

Record locking

Each approval node sets lockRecord: true, so while a step is pending the opportunity is locked by the approval engine — edits are blocked until the step resolves. The lock is released automatically on the final approve/reject.

The approval audit trail

Every action is recorded on the approval request (sys_approval_request) created by the flow:

DateTierActorActionComment
2024-03-12 09:14systemSubmittedAuto-submitted (amount $620K > $500K)
2024-03-12 11:30ManagerSam LeeApproved"OK given strategic logo"
2024-03-12 14:02DirectorPat WongApproved"Approved — book it"

This history is permanent and surfaces in deal-review reports.

Where to find pending approvals

In the HotCRM app there is one approvals entry, and it sits under My Work — an approval waiting on you is your work, so it lives beside your tasks, deals and cases rather than in a group of its own. My Work is open when the app loads, so you do not have to click a group open to see it.

  • Inbox — opens the platform's approval centre, the screen where the approvals waiting on you are actually approved or rejected. Inbox is the label on the sidebar item; Approval Requests is not a navigation entry anywhere in this app. The name is not invented — it is what the approvals plugin calls the object (Approval Request / Approval Requests) — but this page had it standing where a sidebar item should be.

That item pins no view of its own. It used to land on the sys_approval_request object's list, which is read-only — you could read a request there but not act on it — so it now opens the approval centre instead, the surface that carries the Approve / Reject buttons. The object name is still on the entry, as the guard that hides the whole item on an install without the approvals plugin, but it is no longer where the item lands.

The approval centre has three tabs of its own:

TabWhat it shows
My PendingRequests waiting on your decision, with a count badge
Submitted by meRequests you raised, in any state
AllEvery request you are allowed to see

Inside whichever tab you are on, a separate Status filter narrows further: All statuses, Pending, Approved, Rejected, Recalled or Returned for revision.

The object's own list views are a different screen

The approvals plugin also ships four built-in list views on the sys_approval_request object. They are real and still shipped — they are simply not what clicking Inbox opens, and no sidebar item in this app opens them:

Built-in view on the objectWhat it shows
My PendingRequests still pending where you are one of the approvers
I SubmittedEverything you submitted, in any state
CompletedRequests that ended — approved, rejected or recalled
AllEvery request, most recently updated first

Read those as a second screen, not as the tabs above. Two names sit on both sides unchanged, and one pair differs by a single word:

Built-in view on the objectApproval centre tab
My PendingMy Pending — same words, different screen
I SubmittedSubmitted by me
Completedno tab — use the Status filter instead
AllAll — same words, different screen

The three names this page used to list — Pending My Approval, Submitted by Me and Recently Approved — exist nowhere: neither src/ nor the installed approvals plugin carries any of them, under any spelling. My Pending, I Submitted and Completed are the views they were describing. One caveat arrived with the re-point: the approval centre's Submitted by me tab differs from the phantom Submitted by Me only in capitalisation. That tab is a real screen in the centre — it is not, and never was, a view of the object.

Action History is not in the group either, and no sidebar item anywhere in this app carries that name. The audit trail is real data — the approvals plugin stores every action as sys_approval_action, ships Recent / By Actor / All views for it, and each action points back at its request through a request_id lookup. What is missing is only the way in: no navigation entry in this app opens that object.

Tips for sales reps

  • Mind the thresholds — an amount of $100K or more (and especially over $500K) will auto-launch approval the moment you save. A deal priced at exactly $100,000 is on the approval side of the line. Plan for the review window before promising a close date.
  • Get the deal right before saving at or above the threshold — the record locks while a tier is pending; you can't tweak it mid-review.
  • Watch for the rejection notification — a reject ends the run; revise and save again to re-submit.

Tips for managers

  • Respond within 24 hours — sales velocity matters; a stuck approval kills deal momentum.
  • Use the comment field even on approvals — "Approved; please attach signed NDA before booking".
  • Reject with specifics"Need exec sponsor letter from customer" is far more useful than "Not yet".

Tips for admins

  • The thresholds ($100K / $500K), the tiers (manager → director), and lockRecord are all defined in the Opportunity Approval flow — edit the approval nodes and the decision gate to change them.
  • Add more approvals by dropping approval nodes into any flow (contract approval, expense approval, etc.) — see Administration › Automation.
  • The flow lives alongside other automation in the codebase (src/flows/opportunity-approval.flow.ts).
  • Delegated approvers are set in user profile preferences. See Administration › Profiles.

On this page