Automated CRM Audit

Status: Production. Read-only.

Purpose

Assesses a HubSpot portal across seven operational domains and produces severity-classified findings, each carrying the count behind it and the population it was measured against. It reads the portal through the API and writes nothing back.

Cadence

The Audit is one full run, including the duplicate-detection pass, which is the expensive one, delivered as a detailed PDF report. Audit+, a tier of the Audit, adds automated weekly Audit runs, client portal access, full Audit History, run comparisons and ad hoc Audits. Each run is stored as a snapshot, so a number is compared against the same number a week earlier rather than recalculated and hoped about.

Audit modules

Seven modules, each producing independent findings:

PortalUsersCRM structureData qualityWorkflowsMarketingReporting

How duplicates are counted

Two passes. An exact pass over normalised values, and a near-match pass comparing names that requires the email domains to corroborate the match. The near-match pass is approximate by design and deterministic in practice: the same records produce the same pairs on every run. When the comparison budget is reached it reports the scan as truncated rather than quietly returning a smaller number.

What it will not claim

Where a figure cannot be measured in a period, the audit records why instead of emitting a zero. A duplicate count older than the rest of the report is labelled as such. A metric whose calculation has changed is presented as a fresh baseline rather than trended across the change.

Required HubSpot scopes

The scopes on the private app the audit runs with, as HubSpot reports them (16), used only to read. Three of them (automation, forms, sales-email-read) also permit changes; Mixbound never uses them to change anything. No create, update, delete, merge, property change or workflow enrolment.

✓ automation✓ automation.sequences.read✓ cms.domains.read✓ communication_preferences.read✓ crm.lists.read✓ crm.objects.companies.read✓ crm.objects.contacts.read✓ crm.objects.deals.read✓ crm.objects.owners.read✓ crm.objects.users.read✓ crm.schemas.companies.read✓ crm.schemas.contacts.read✓ crm.schemas.deals.read✓ forms✓ oauth✓ sales-email-read

Determinism

No part of the audit calls a language model. The service dependency set is better-sqlite3, express, googleapis and mysql2. The same portal state produces the same findings.

Technology

Node.js 20HubSpot API v3/v4Read-only callsSQLite snapshots