Phase 4 — Closing (Sales)
What this phase delivers: interested targets coming out of Connect are handed to Closing-Agents to book appointments, hold meetings, track no-shows, and close contracts — all in a drag-and-drop pipeline, with closing-agent commissions and a single controlling view across all four stages.
Like Phase 3, this is mostly build — the pipeline is tightly coupled to the rest of the system. The genuine integrations here are e-signature (SignRequest) and payment collection (GoCardless); scheduling is built in-house, and a full external CRM is only relevant if we decide not to build the pipeline.
1. What we build vs. what we integrate (this phase)
We build the drag-and-drop pipeline (a React + shadcn/ui Kanban in apps/web), appointments, notes, contract records, no-show tracking, closing-agent commissions, and the cross-team controlling overview. Business logic lives in NestJS services (apps/api), not in the React components.
We integrate two helpers that are cheaper to plug in than to build well:
- E-signature (SignRequest) for sending and signing the closing contract.
- Payment collection (GoCardless) for collecting payment after a contract closes.
A full CRM (Pipedrive/HubSpot) is the alternative to building the pipeline — presented below so the build-vs-buy choice is explicit. Each integration is its own NestJS module behind an interface (mockable, retry + backoff, 30s timeout, secrets redacted, cost recorded, mocked in CI); their webhooks are signature-verified before touching business logic.
2. Layer 1 — Sales pipeline: build vs. CRM
The core decision of the phase.
| Option | Pros | Cons |
|---|---|---|
| Build the pipeline (recommended) | Deep integration with the rest of the flow; the benchmark, call history, and email history all live in one place; a drag-drop Kanban is cheap to build well with React + shadcn/ui; no per-seat CRM cost | It's ours to build and maintain; slightly more up-front work than bolting on a CRM |
| Pipedrive | Fast to stand up; RESTful API, webhooks on deal changes; free API token per plan | A seam between our system and theirs; data sync to maintain; weaker cross-stage controlling; per-seat cost |
| HubSpot | Very capable; large ecosystem; strong API + workflows | Heavier and pricier; more than we need; same integration-seam and controlling drawbacks |
How each one works + docs
- Build the pipeline — Targets move through closing stages on a Kanban board inside our own app, directly linked to the
Targetrecord (so the benchmark, email history, and call log stay attached), with each move recorded as aPipelineEvent. No external sync. (This is build, not an integration.) - Pipedrive — RESTful API (v1) with OAuth 2.0 or an API token; you'd push deals, persons, and activities, and subscribe to webhooks on deal-created/updated to mirror stage changes back into our system. Docs: https://www.pipedrive.com/en/features/crm-api
- HubSpot — REST API with OAuth 2.0 / private apps over CRM objects (contacts, companies, deals, pipelines), plus webhooks and workflow actions. Docs: https://developers.hubspot.com/docs
Recommendation: build the pipeline. The whole value of this platform is one connected flow with one benchmark; bolting on an external CRM re-introduces exactly the data seams we've avoided everywhere else. Keep it behind our own model so we're not locked to a vendor.
3. Layer 2 — Appointment scheduling
For booking the sales meeting, syncing calendars, and catching reschedules/no-shows. This repo builds scheduling in-house (it is not in the v1 external-integration list); the hosted options below were researched as alternatives and could be slotted behind a scheduling interface later.
| Option | Pros | Cons |
|---|---|---|
| Build it (this repo) | Full control; appointment data stays in our own infrastructure (the safer GDPR posture); directly coupled to the target/deal record and no-show tracking | Calendar sync and availability logic are fiddly to build well |
| Calendly (alternative) | Mature; REST API v2 with webhooks on book/cancel/reschedule; built-in mark-as-no-show endpoint; calendar sync handled | Paid tiers for API/webhooks; hosted (data lives with them) |
| Cal.com (alternative) | Open-source; self-hostable (data stays with us); API for event types and bookings | More setup/maintenance if self-hosted |
How each one works + docs
- Build it — We manage availability, calendar sync (Google/Microsoft), and booking pages ourselves, storing appointments against the deal with reschedule and no-show flags. This is the v1 path.
- Calendly — REST API v2 (personal-access-token or OAuth 2.1); generates scheduling links and fires webhooks whenever an invitee books, cancels, or reschedules; a dedicated endpoint marks an invitee as a no-show. Docs: https://developer.calendly.com
- Cal.com — Open-source scheduling with a REST API over event types and bookings; can be self-hosted so appointment data stays inside our own infrastructure. Docs: https://cal.com
Recommendation: build scheduling in-house for v1 to keep appointment data in-region and tightly coupled to the deal; add Calendly or self-hosted Cal.com behind the interface later only if the manual calendar work proves too costly.
4. Layer 3 — Contracts (e-signature) & payments
For sending/signing the closing contract and collecting payment. This repo's choices are SignRequest (e-signature) and GoCardless (payment collection).
| Concern | Choice (this repo) | Pros | Cons |
|---|---|---|---|
| E-signature | SignRequest | eSignature REST API; webhooks for signature status; EU-based, eIDAS-recognised; attach signed result to the deal | Pay-as-you-go cost; another vendor to wire in |
| Payments | GoCardless | Bank-debit collection API; webhooks on payment status; strong SEPA / EU direct-debit coverage; per-transaction pricing | Collection is direct-debit-oriented rather than card; another vendor |
| Store records only (fallback) | build | Simplest; no vendor | No actual signing/collection workflow — only viable if contracts and payments are handled elsewhere |
How each one works + docs
- SignRequest — You create a signing request (the document plus its signers) via the REST API, send it for signature, and receive status updates through SignRequest webhooks (signature-verified before use); the signed document is attached to the deal. Sent on contract send. Docs: https://signrequest.com/api/v1/docs/
- GoCardless — After a contract closes, you create a mandate + payment via the REST API and receive webhooks on payment lifecycle events (created/confirmed/failed) to reconcile against the deal. Called after contract close. Docs: https://developer.gocardless.com
- Store records only — We just record contract metadata and files against the deal, with signing/payment handled outside the system (fallback if a vendor isn't provisioned).
Recommendation: wire in SignRequest for in-app signing and GoCardless for collection, both behind their own interfaces so records-only remains a clean fallback.
5. What we build — the pipeline
Plain-language description:
- Deals — one per closing opportunity, linked to the
Target(carrying its benchmark, email history, and call log). - Drag-and-drop Kanban — deals move through the 8 closing stages (below).
- Appointments — booked meetings with reschedule and no-show tracking.
- Notes — free-form context on each deal.
- Contracts — records (and SignRequest-signed documents) attached to sold deals, with GoCardless payment collection after close.
- Closing-agent commissions — calculated from sold deals.
- Warm call-back handoff — a distinct path to send a warm follow-up back to the Connect team, kept separate from cold-call shifts.
- Controlling overview — the cross-team view (outreach → connect → closing) aggregating all the KPIs into one dashboard.
Round-robin assignment
Appointments are round-robin assigned to Closing-Agents, and a Closing-Agent sees only their round-robin-assigned targets (least-privilege scoping).
The 8-stage closing pipeline
New target (validation pre-stage) → Appointment scheduled → Follow-up → First meeting → Follow-up meeting → Sold (end) → Not sold (end) → Unqualified (end).
6. How the closing flow works
- Phase 3 hands over targets marked appointment scheduled / interested, in benchmark order.
- A deal is created and enters the pipeline at the validation pre-stage; it is round-robin assigned to a Closing-Agent, and an appointment is booked.
- Reschedules and no-shows update the deal (via webhooks where a scheduling provider is used, otherwise from the in-house calendar).
- The Closing-Agent works the deal through the stages, adding notes.
- On Sold, a contract is sent via SignRequest, payment is collected via GoCardless, and the closing-agent's commission is calculated.
- Everything feeds the controlling overview, closing the loop from first discovery to signed, paid contract.
7. Legal & compliance notes for this phase
The full compliance layer is out of scope for v1 in this repo; treat these as design considerations for the legal opinion:
- E-signature validity — in the EU, electronic signatures are legally recognised under eIDAS; SignRequest handles that compliance layer for in-app signing.
- Payments — direct-debit collection via GoCardless carries SEPA mandate obligations; confirm the mandate flow with the legal opinion.
- GDPR retention — contracts, payment records, and customer records are personal data with their own retention obligations; erasure handling should extend to deals, contracts, and payments.
- Data residency — SignRequest and GoCardless are EU-based; in-house scheduling keeps appointment data in-region.
8. Decisions needed for Phase 4
- Pipeline: confirm we build it (recommended) vs. integrate Pipedrive/HubSpot.
- Scheduling: confirm build-in-house for v1 vs. adding Calendly / self-hosted Cal.com behind the interface.
- Contracts & payments: confirm SignRequest for signing and GoCardless for collection now, vs. records-only to start.
- Commission rules: how is Closing-Agent commission calculated (per sold deal, % of contract value)? ⚠️ Needs client sign-off.
- Controlling: which cross-team KPIs matter most for the single overview dashboard? ⚠️ Needs client sign-off.
- Data residency: any requirement beyond the EU-based defaults to keep appointment/contract/payment data in-region?
Appendix — Documentation links
| Integration | Docs |
|---|---|
| SignRequest (e-signature) | https://signrequest.com/api/v1/docs/ |
| GoCardless (payment collection) | https://developer.gocardless.com |
| Calendly (scheduling, alternative) | https://developer.calendly.com |
| Cal.com (scheduling, open-source alternative) | https://cal.com |
| Pipedrive (CRM alternative) | https://www.pipedrive.com/en/features/crm-api |
| HubSpot (CRM alternative) | https://developers.hubspot.com/docs |
Prices, plan gating, and features are approximate and change — confirm on each provider's site. Part of the project docs — Phase 4 of 5 (Phase 5 = controlling + optimisation).