feat(post-audit): batch A+B quick-wins + audit-side residuals
Bundles the user-prioritised follow-ups from the post-audit punch-list.
Batch A — pipeline + EOI safety:
- §1.1 timeline buildAuditDescription renders diff fields ("leadCategory → hot_lead").
- §4.13 EOI rejection cascade: notification to assigned rep + audit row + rose banner.
- §4.10b finish doc-detail: SigningProgress reuse, linked-entity names (server-resolved),
per-event icons + tooltips + show-more in activity panel.
- §7.2 stage guidance card replaces empty Payments slot pre-reservation.
- §4.15 deal-pulse trigger audit (docs/deal-pulse-trigger-audit.md).
Batch B — UX consistency + docs:
- §1.4 quick log-contact button on interest header.
- §2.1 contact-log compose: Dialog → Sheet.
- §7.1 docs/deal-pulse explainer page; /docs/ in PUBLIC_PATHS.
- DocumentStatus now includes 'rejected' + 'declined' across constants, labels, tone maps.
Audit-side residuals:
- M-NEW-1 /me/ports skips port-context requirement.
- M-AU03 audit log CSV export endpoint + UI button.
- M-IN03 dead receipt-scanner.ts deleted; live path already per-port.
- M-P01 pg_trgm GIN indexes (migration 0071).
- §10.1 webhook tests verified passing (was stale).
Deferred per user direction:
- §11.3 email copy refactor (needs old-CRM reference).
- M-EM03 IMAP bounce-to-interest linking.
Tests: 1374/1374. tsc + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
145
src/app/docs/deal-pulse/page.tsx
Normal file
145
src/app/docs/deal-pulse/page.tsx
Normal file
@@ -0,0 +1,145 @@
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Deal Pulse & Heat — Port Nimara CRM',
|
||||
description:
|
||||
'How the deal pulse chip + heat score work: signals, calibration, and what to do when a deal goes cold.',
|
||||
};
|
||||
|
||||
/**
|
||||
* §7.1 — public explainer page for the Deal Pulse + Heat scoring model.
|
||||
* Linked from the popover in `deal-pulse-chip.tsx` ("Full guide"). Kept
|
||||
* intentionally text-heavy + jargon-free so a new sales rep can read
|
||||
* once and internalize the model without bouncing back to the kanban.
|
||||
*
|
||||
* Public route (no auth) so external docs links and email signatures
|
||||
* resolve cleanly. The route lives outside (dashboard) for that reason
|
||||
* — middleware lets `/docs/...` through.
|
||||
*/
|
||||
export default function DealPulseDocsPage() {
|
||||
return (
|
||||
<div className="mx-auto max-w-3xl px-6 py-10 text-sm leading-relaxed text-foreground">
|
||||
<header className="mb-8 space-y-2 border-b pb-6">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
Port Nimara CRM · Sales playbook
|
||||
</p>
|
||||
<h1 className="text-2xl font-semibold">Deal Pulse & Heat</h1>
|
||||
<p className="text-muted-foreground">
|
||||
What the chip on every interest card actually means, how it's scored, and how to act
|
||||
on it.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<section className="space-y-4">
|
||||
<h2 className="text-lg font-semibold">The chip in one sentence</h2>
|
||||
<p>
|
||||
The colored chip on each interest is a fast read of{' '}
|
||||
<strong>how hot the deal is right now</strong> based on what's been happening on it
|
||||
lately — not a prediction, not an AI score, just a mechanical rollup of recent activity.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="mt-8 space-y-4">
|
||||
<h2 className="text-lg font-semibold">Levels</h2>
|
||||
<dl className="space-y-3">
|
||||
<div className="rounded-md border bg-rose-50 p-3">
|
||||
<dt className="font-semibold text-rose-900">Hot</dt>
|
||||
<dd className="text-rose-900/90">
|
||||
Recent inbound contact, multiple touches in the last week, or a milestone (EOI sent,
|
||||
deposit received) inside the last 7 days. Default-sort lists put these at the top.
|
||||
</dd>
|
||||
</div>
|
||||
<div className="rounded-md border bg-amber-50 p-3">
|
||||
<dt className="font-semibold text-amber-900">Warm</dt>
|
||||
<dd className="text-amber-900/90">
|
||||
Activity in the last 14–30 days. The deal isn't neglected but the cadence has
|
||||
slowed — usually means a follow-up reminder is the right next action.
|
||||
</dd>
|
||||
</div>
|
||||
<div className="rounded-md border bg-slate-100 p-3">
|
||||
<dt className="font-semibold text-slate-700">Cold</dt>
|
||||
<dd className="text-slate-700/90">
|
||||
No movement in 30+ days. Time to either re-engage with intent or close the deal as
|
||||
lost so the kanban stays honest.
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section className="mt-8 space-y-4">
|
||||
<h2 className="text-lg font-semibold">What feeds the score</h2>
|
||||
<ul className="list-disc space-y-2 pl-5">
|
||||
<li>
|
||||
<strong>Recency of last contact log entry.</strong> Inbound (client replied) counts more
|
||||
than outbound (rep reached out).
|
||||
</li>
|
||||
<li>
|
||||
<strong>Furthest pipeline stage reached.</strong> A deal at EOI scores higher than one
|
||||
at Enquiry, all else equal.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Count of related interests on the same client.</strong> Volume signals intent.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Count of EOIs sent.</strong> Multiple EOIs = multiple berths under serious
|
||||
consideration.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Time at current stage.</strong> Stagnation drags the score down even if other
|
||||
signals look good — a deal stuck at Reservation for six weeks should not read hot.
|
||||
</li>
|
||||
</ul>
|
||||
<p className="text-muted-foreground">
|
||||
The exact weights live in <code className="text-xs">system_settings</code> under
|
||||
<code className="text-xs"> heat_weight_*</code> keys and can be tuned per-port from the
|
||||
admin Settings page.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="mt-8 space-y-4">
|
||||
<h2 className="text-lg font-semibold">What to do with each level</h2>
|
||||
<ul className="list-disc space-y-2 pl-5">
|
||||
<li>
|
||||
<strong>Hot:</strong> Don't lose the momentum. Send the next document or schedule
|
||||
the in-person visit while they're engaged.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Warm:</strong> Log a follow-up contact attempt; set a reminder if you're
|
||||
waiting on them.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Cold:</strong> Either "Reopen with a fresh hook" (price drop, new
|
||||
inventory, event invite) or close the deal so the pipeline reflects reality.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section className="mt-8 space-y-4">
|
||||
<h2 className="text-lg font-semibold">FAQ</h2>
|
||||
<details className="rounded-md border p-3">
|
||||
<summary className="cursor-pointer font-medium">Does this use AI?</summary>
|
||||
<p className="mt-2 text-muted-foreground">
|
||||
No. It's a deterministic SQL rollup of contact logs, milestones, and stage
|
||||
transitions. The same inputs always produce the same chip color.
|
||||
</p>
|
||||
</details>
|
||||
<details className="rounded-md border p-3">
|
||||
<summary className="cursor-pointer font-medium">
|
||||
Can I override the chip on a specific deal?
|
||||
</summary>
|
||||
<p className="mt-2 text-muted-foreground">
|
||||
Not directly — the chip is a read-only summary. To change it, change the inputs: log a
|
||||
contact, advance a stage, or close the deal.
|
||||
</p>
|
||||
</details>
|
||||
<details className="rounded-md border p-3">
|
||||
<summary className="cursor-pointer font-medium">How often does it refresh?</summary>
|
||||
<p className="mt-2 text-muted-foreground">
|
||||
On every interest write. The kanban + list pages query a live materialized rollup, so
|
||||
you should see the chip move within a few seconds of any update.
|
||||
</p>
|
||||
</details>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user