Monthly client reports

CRM → Client reports saves a named lead goal for a company or tag. A lead is a complete form delivered to a CRM record or a currently confirmed booking; choose a specific form or booking link when needed. Walkthroughs require a chosen booking link. Attribution: when a goal names a form or booking link, every lead through that page counts for the client, including a brand-new person the public booking/form route just created with no company or tag. Without a page, a lead counts only once its CRM contact is on the client company (or the contact/company carries the client tag); the public booking route never sets either, so pick the client's own link for booking goals. With a page selected, the submission or booking row itself is the lead: archiving or deleting its contact later does not remove it. Without a page, archived contacts are excluded because the relationship is the attribution. Counting uses the submission/booking creation time, even when an appointment takes place later. Partial forms, pending CRM deliveries, archived contacts and cancelled bookings are excluded. Attribution uses the action's earliest recorded first touch; missing tracking is unknown and does not remove the lead.

Months use the goal's IANA zone (default America/Vancouver), with inclusive start and exclusive end across DST. Current-month actual stops at the read time. Pace projects actual over elapsed local calendar days and stays empty ("Too early to project") until one full day has elapsed; future-month pace is empty. Closed-month pace equals actual. Tags use current membership, and company reports use current company relationships: this is a live report, not an immutable historic billing record.

The dashboard reuses CRM's inferred funnel: later open stages and won deals imply previous steps. It does not claim historical transition counts. Value stays in integer cents, separated by currency. Won/lost counts use close dates independently of the pipeline's created-in-month cohort.

CSV and the print page use the same aggregation as the screen. Print / Save PDF opens a branded page and uses the browser's PDF print function. The report has organization name and configured primary color. No external logo fetch is required.

Monthly schedules accept at most 25 current member UUIDs. The existing send-reports cron delivers legacy report subscriptions first, then attempts the previous calendar month once per goal (never a month that ended before the goal was created, judged in the goal zone), rechecks the creator's permission and each recipient's membership and CRM read permission, and records provider acceptance as queued. No external email address can be configured. Claims are made before sending; a process death can leave an ambiguous pending attempt, which is not retried automatically. A failed month is recorded and later months continue. Zone names match in any ASCII casing (utc, america/vancouver), as PostgreSQL and browsers match them, including goals saved before this rule; a goal whose stored zone Postgres does not recognise (an unknown name, a padded name, or one that differs by more than ASCII case) is skipped, left unclaimed and counted as invalid; any other per-goal failure is contained to that goal, and a failure of the whole client-report step never fails the cron response or the legacy subscriptions.

Archive (crm:archive, admins by default) removes a goal from the list, clears its schedule and frees its slot under the 100-goal limit; its reports stay readable by id. The print page carries its own Content-Security-Policy (default-src 'none', one hashed print script, no framing). Delivery receipts do not claim inbox delivery.

Flags: CRM_CLIENT_REPORTS_ENABLED=true by default; false kills new API routes and scheduled delivery. Set NEXT_PUBLIC_CRM_CLIENT_REPORTS_ENABLED=false when building the web to remove the new navigation. Existing saved reports retain their reviewed platform hold.

Limits: 100 goals/org, 10000 actions/report, three-second statement timeout. Large inputs fail with 422 rather than silently truncating.

We use essential cookies to keep you signed in. See our Privacy Policy for details.