Pipeline Management
How the sales pipeline works day-to-day — moving deals, automatic probability, forecasting and the kanban board.
Pipeline Management
The pipeline is the sum of all your open opportunities. HotCRM gives you a governed pipeline where stage progression, win probability and forecast values are all kept in sync automatically — reps focus on selling, not on data hygiene.
How probability is set
Win probability is set from the stage automatically, so every rep's forecast uses the same numbers:
| Stage | Default win probability |
|---|---|
| Prospecting | 10 % |
| Qualification | 25 % |
| Needs Analysis | 40 % |
| Proposal | 60 % |
| Negotiation | 80 % |
| Closed Won | 100 % |
| Closed Lost | 0 % |
You can override the probability manually on an individual deal if you have a special situation, but the override is reset the next time the stage changes. This prevents reps from inflating their forecast by hand.
Admins can adjust the percentages per stage — see Administration › Automation.
How expected revenue is calculated
Expected Revenue = Amount × Probability ÷ 100
This number is the heart of the weighted forecast. It's recalculated automatically every time the amount or probability changes (including the auto-updates from stage changes).
The weighted forecast is a list-view total, not a dashboard number. The Open Deals and All Opportunities views on Opportunities each carry an Expected Revenue column with a column sum (src/views/opportunity.view.ts), and that sum over the open pipeline is the weighted forecast.
No dashboard can give you the same figure. The Sales Performance dashboard (sales_dashboard) reads the opportunity_metrics dataset, and that dataset declares no measure over expected_revenue — every amount measure it exposes (Total Amount, Avg Deal Size, Won Revenue, Lost Revenue) reads the raw amount field. So its Total Pipeline tile is the unweighted open pipeline; the two numbers differ by the probability weighting, which is the whole point of the calculation above.
The pipeline kanban view
The kanban board is the Sales Pipeline view on Opportunities (pipeline_kanban), and the sidebar entry that opens it reads Pipeline. It shows the pipeline one column per stage, open deals only: the board carries its own filter — stage not_in [closed_won, closed_lost] in src/views/opportunity.view.ts — so only the five active stages, Prospecting, Qualification, Needs Analysis, Proposal and Negotiation, can ever hold a card. Closed business is not hidden, it is elsewhere: All Opportunities and the Sales Performance dashboard both include it. Whether the two closed stages are drawn as permanently empty columns or left off the board altogether is the console's rendering choice and not something this app declares — either way there is no closed deal on this board to find.
Each card carries the four fields the board binds (kanban.columns):
- Opportunity name
- Account
- Amount
- Close date
Owner is not on the card. owner_id sits in the view's top-level columns list, which is what the grid renderings read, but the card binding names those four fields and stops there. To see the owner next to a deal, use All Opportunities, which carries an Owner column, or the Deal Cards gallery, whose cards do show it.
To advance a deal, just drag the card to the next column. The stage rules are advice, not a gate. opportunity_stage_progression (src/objects/opportunity.object.ts) declares which moves are legal — Prospecting straight to Closed Won is not one of them — but the rule carries warning severity, so a move outside the table writes one line to the server log, "Invalid opportunity stage transition", and the save still goes through. Nothing in the board stops you. What the log buys you is that a bad import or a misbehaving integration can be found afterwards; see Administration › State Machines for what the table is and is not good for.
At the top of each column you'll see one number: the sum of Amount across that column's deals — the unweighted total for that stage. One is all a kanban column can carry, by design: a board declares a single summarizeField (src/views/opportunity.view.ts), and this board binds it to amount.
The board has no weighted total. As How expected revenue is calculated says above, the weighted forecast is a list-view total: the Expected Revenue column sum on Open Deals and All Opportunities.
Pipeline health signals
A few derived fields surface deal risk so you can act on them in your weekly review:
| Signal | What it tells you |
|---|---|
| Days in current stage > 30 | Deal is stagnant — push or close it. |
| Close date in the past AND stage still open | Forecast is wrong; reset the date or accept the loss. |
| Amount > $500K with no submitted approval | Discount approval is required before this can close. |
| Closed lost with no loss reason | The deal's story is gone — nothing can learn from it. |
The AI assistant surfaces at-risk deals when you ask "what's slipping?" or "how does my pipeline look?"
Pipeline reports worth bookmarking
Only the first of these is on the sidebar. There is no Reports group: the reports group is called Insights (src/apps/crm.app.ts), and it pins three reports — Pipeline Coverage, Lead Inflow and SLA Performance — alongside the CRM Overview dashboard and Forecasts. The other four below are opened from the reports screen. Names here are the labels the report library lists, which is not always the shorter name on the nav entry.
| Report | What it shows |
|---|---|
| Pipeline Coverage by Forecast × Quarter | Are we covering 3x the quota for the upcoming quarter? A matrix of open pipeline: forecast category down the rows, close quarter across the columns. The sidebar entry for it reads Pipeline Coverage. |
| Opportunity Funnel by Owner → Stage | Per-rep funnel health — spot leaky stages. |
| Opportunities by Stage | Bar chart of pipeline by stage. |
| Won Opportunities by Owner | Leaderboard for quarter-end recognition. |
| Customer Churn Signals | Open cases + low NPS on existing customers = churn risk. |
See Analytics › Reports for details.
Recommended pipeline cadence
| Cadence | What to do |
|---|---|
| Daily | Open the Pipeline board. Find stalled cards (in-stage > 14 days). Push or close. |
| Weekly | Run Pipeline Coverage. Ask the AI assistant: "what's at risk?" |
| Monthly | Run Opportunity Funnel by Owner → Stage. Coach reps with leaky stages 1:1. |
| Quarter-end | Run Won Opportunities by Owner for commissions. Archive lost deals with a loss reason. |
Forecasting roll-up
The Sales Manager / Director view of the forecast is built from:
- The Opportunity Metrics dataset (
opportunity_metrics) — measure Total Amount (sum of amount), dimension Stage - The Sales Performance dashboard (
sales_dashboard) — widgets for pipeline by stage, win rate, and open pipeline by owner - The Pipeline Coverage report (
pipeline_coverage_by_quarter, whose own label reads Pipeline Coverage by Forecast × Quarter) — a matrix of open pipeline: forecast category down the rows, close quarter across the columns
Together they answer: "do we have enough pipeline to make the quarter, and where are the risks?"
What that dashboard will not give you is a top deals ranking, and no renaming would fix it: a dashboard table binds to an analytics dataset and can only aggregate — it cannot list raw records (ADR-0021). The Top Open Opportunities table that once held that slot was replaced by Open Pipeline by Owner, a per-rep ranking, for exactly that reason; the Row 5 comment in src/dashboards/sales.dashboard.ts records the swap. For a deal-by-deal ranking, open an opportunity list view.
Tips for sales reps
- ✅ Move stage promptly — your forecast is wrong if your stage is wrong.
- ✅ Use Next Steps — your manager reads it every Monday standup.
- ❌ Don't slide the close date to hide slippage; use Closed Lost with a reason.
Tips for sales managers
- ✅ Run Opportunity Funnel by Owner → Stage monthly to catch reps with leaky funnels.
- ✅ Use Pipeline Coverage in QBRs to set the next quarter's targets.
- ✅ Coach reps to fill in Loss Reason and Loss Details on every closed-lost deal — it is the only competitive data the app keeps.
Tips for admins
- Add or remove stages? You need to update three places in the source, none of them a Setup screen: the
OPPORTUNITY_STAGE_OPTIONSpicklist thestagefield renders (src/objects/_picklists.ts), theSTAGE_PROBABILITYmap that sets probabilities inside theopportunity_lifecyclehook (src/objects/opportunity.hook.ts), and theopportunity_stage_progressionstate-machine validation rule that controls transitions (src/objects/opportunity.object.ts). See Customization › Extending Objects. - The $100K large deal notification threshold is not a Setup field either: it is the CEL start condition of the
opportunity_won_alertflow —record.amount >= 100000insrc/flows/opportunity-won-alert.flow.ts. Who gets the alert is that flow'snotifynode, whoserecipientslist is the single entry{record.owner_id}— the deal owner alone.