›
›
›
  1. docs
  2. ›
  3. byrcsc/laravel-customer-health
1.x
Browse documentationOpenClose

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Product events
  • Features and milestones
  • Onboarding
  • Health scores
  • Summaries and tenancy

Operations

  • Querying customer health
  • Queueing events
  • Recomputing scores
  • Retention and erasure
  • Production operations

Reference

  • Configuration
  • Public API
  • Events
  • Console commands
  • Database storage
  • Testing
  • Troubleshooting

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Product events
  • Features and milestones
  • Onboarding
  • Health scores
  • Summaries and tenancy

Operations

  • Querying customer health
  • Queueing events
  • Recomputing scores
  • Retention and erasure
  • Production operations

Reference

  • Configuration
  • Public API
  • Events
  • Console commands
  • Database storage
  • Testing
  • Troubleshooting

byrcsc/laravel-customer-health · 1.x

Troubleshooting.

Match customer health configuration, tracking, queue, score, and tenancy failures to their causes.

Start with the exception class, then check the configured declaration and the connection on which the package is operating.

Product event is not registered

UnregisteredEventException means the event class passed to track() is absent from customer-health.events.

Add the exact class and rebuild cached configuration:

'events' => [
    App\CustomerHealth\Events\WorkflowCreated::class,
],
php artisan config:cache

The same exception can occur when a checklist contains an event that is not registered.

Event declaration is invalid

InvalidEventDefinitionException is thrown when a registered value does not extend ProductEvent or two registered classes resolve to the same name.

Give every event a unique stable name:

public static string $name = 'workflow_created';

Subject or actor is rejected

InvalidTrackableException means the subject or actor is not an Eloquent model, has not been persisted, has an unsupported key, or has an empty morph type.

The subject must implement Trackable. The optional actor must implement Authenticatable. Save both models before tracking.

Properties cannot be queued

InvalidEventPropertiesException names the path containing an object or other non-JSON value:

Product event property [properties.context.model] must contain only JSON primitives and arrays.

Convert models, dates, and enums to IDs, strings, integers, booleans, null, or nested arrays before constructing the event.

Checklist cannot resolve

InvalidChecklistDefinitionException can mean:

  • no checklist is registered and a default was requested;
  • the requested name or class is not registered;
  • a checklist is empty or repeats a step;
  • a registered value does not extend Checklist; or
  • a step is not a milestone event.

Check customer-health.checklists, then confirm every step also appears in customer-health.events with $milestone = true.

Score cannot resolve

InvalidScoreDefinitionException covers missing or duplicate scores, invalid signals, non-positive or non-finite weights, and invalid state thresholds.

Every score needs at least one Signal. Every weight must be finite and above zero. States need unique integer thresholds from 0 through 100, including one threshold at zero.

If a signal returns below 0 or above 100, computation throws InvalidSignalValueException and stores no history or summary.

Queued event is never stored

Confirm all of these conditions:

  1. A worker consumes customer-health.queue_connection and customer-health.queue_name.
  2. Cached configuration contains queue => true as a boolean.
  3. The job is not in Laravel's failed-jobs store.
  4. The worker has restarted after configuration changes.
  5. Tenant context and the intended default connection are active on the worker.

When connection is null, the worker writes to its active default database, not a connection captured at dispatch time.

Inactive or stalled queries miss a customer

The package can discover only identities present in raw events or milestones. A customer with no package history cannot appear.

inactive(14) and stalledInOnboarding(14) use a strict older-than comparison. An event exactly 14 days old is not yet included.

Stalled onboarding also requires at least one completed step and at least one incomplete step in a registered checklist.

Summary is missing or on the wrong connection

Check connection, summary_connection, and tenant_resolver. Then confirm the summaries migration ran on the resolved summary connection.

Recompute affected subjects to upsert current summaries:

php artisan customer-health:recompute

In a database-per-tenant application, run the command inside each tenant context.

Tenant resolver is invalid

InvalidTenantResolverException means the configured value is not an existing invokable class or its return is not an integer, non-empty string, or null.

Implement TenantResolver and return the current tenant's stable key. Do not return a model object.

Score computation waits or times out

Computations for the same subject and score serialize on MySQL and PostgreSQL. MySQL waits up to 10 seconds and then throws ScoreComputationLockException.

Reduce overlapping computation, use the recompute command with withoutOverlapping(), or retry the failed job after the competing transaction finishes.

Recompute warns about retention

The warning means retention_days is shorter than a registered WindowedSignal. The computation still runs, but deleted raw events cannot contribute.

Increase retention, shorten the signal window, or accept that the score covers only retained history. Recomputing cannot recover pruned rows.

Purge command cannot resolve a subject

The command loads the subject model before deleting. Confirm the morph alias or model class, model key, application model connection, and Trackable implementation.

For a landlord summary, pass --tenant when the current resolver does not return the tenant ID stored on the target row.

Get help

For a reproducible package defect, open an issue with the exception, relevant configuration, database driver, and a minimal test. Remove customer properties, tenant identifiers, and other sensitive data first.

For usage questions, start a repository discussion.

What to read next

  • Configuration for every default and declaration list.
  • Console commands for option validation and exit codes.
  • Production operations for worker, scheduler, and freshness checks.
PreviousTesting
View source

On this page

  1. Product event is not registered
  2. Event declaration is invalid
  3. Subject or actor is rejected
  4. Properties cannot be queued
  5. Checklist cannot resolve
  6. Score cannot resolve
  7. Queued event is never stored
  8. Inactive or stalled queries miss a customer
  9. Summary is missing or on the wrong connection
  10. Tenant resolver is invalid
  11. Score computation waits or times out
  12. Recompute warns about retention
  13. Purge command cannot resolve a subject
  14. Get help
  15. What to read next