›
›
›
  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

Events.

Laravel events expose recorded activity, milestones, onboarding progress, and health-state transitions.

Listen to these events when package writes should trigger application work. All six event classes are final, readonly, and dispatched synchronously.

Event catalog

EventPublic propertiesWhen it fires
ProductEventRecordedProductEventRecord $recordAfter each raw product-event write
MilestoneReachedMilestone $milestoneAfter a milestone is inserted for the first time
OnboardingStepCompletedMilestone $milestone, string $checklist, string $stepAfter a checklist step milestone is first inserted
OnboardingCompletedMilestone $milestone, string $checklistAfter the checklist completion milestone is inserted
HealthScoreComputedHealthScoreRecord $record, ScoreResult $resultAfter every committed score computation
HealthStateChangedHealthScoreRecord $record, ?string $from, string $toAfter a committed computation changes state

OnboardingStepCompleted::$step is the milestone ProductEvent class name. OnboardingCompleted::$milestone is the generated onboarding:<checklist-name> milestone.

Listen for recorded activity

namespace App\Listeners;

use ByRcsc\LaravelCustomerHealth\Events\ProductEventRecorded;

final class RecordProductAudit
{
    public function handle(ProductEventRecorded $event): void
    {
        $event->record->name;
        $event->record->subject_type;
        $event->record->subject_id;
        $event->record->properties;
        $event->record->occurred_at;
    }
}

This event fires for every raw event, including repeated milestone events.

Listen for first adoption

namespace App\Listeners;

use ByRcsc\LaravelCustomerHealth\Events\MilestoneReached;

final class NotifyCustomerSuccess
{
    public function handle(MilestoneReached $event): void
    {
        if ($event->milestone->name !== 'workflow_created') {
            return;
        }

        // React to the first workflow created by this subject.
    }
}

The milestone table's unique index prevents duplicate first-occurrence events when concurrent calls track the same milestone.

Listen for onboarding progress

use ByRcsc\LaravelCustomerHealth\Events\OnboardingCompleted;
use ByRcsc\LaravelCustomerHealth\Events\OnboardingStepCompleted;

final class RecordOnboardingProgress
{
    public function handle(
        OnboardingStepCompleted|OnboardingCompleted $event,
    ): void {
        $event->checklist;
        $event->milestone->subject_type;
        $event->milestone->subject_id;
    }
}

These events are registered through the connection's afterCommit callback. They do not fire when the surrounding database transaction rolls back.

Listen for score state changes

namespace App\Listeners;

use ByRcsc\LaravelCustomerHealth\Events\HealthStateChanged;

final class OpenCustomerSuccessTask
{
    public function handle(HealthStateChanged $event): void
    {
        if ($event->to !== 'at_risk') {
            return;
        }

        $identity = [
            'type' => $event->record->subject_type,
            'id' => $event->record->subject_id,
        ];

        // Create or update an idempotent task for this identity.
    }
}

The first computation fires HealthStateChanged with $from === null. A later computation in the same state fires only HealthScoreComputed.

Both score events are registered after the score history and summary transaction commits.

Transaction and listener behavior

ProductEventRecorded and MilestoneReached dispatch after the package's event write transaction returns. If the caller has opened an outer transaction, these two events can run before that outer transaction commits.

Onboarding and score events use database afterCommit callbacks. They wait for the outer transaction to commit.

All listeners run synchronously unless the listener implements Laravel's ShouldQueue. A listener exception can fail the request or queued product-event job that dispatched it.

Queued job retries can create repeated ProductEventRecorded events and raw rows. Make listeners repeatable when queued tracking is enabled.

Events not dispatched

Pruning and purging do not dispatch package lifecycle events. Direct writes to the readable package models also bypass the event flow.

What to read next

  • Product events for raw and milestone write behavior.
  • Onboarding for step and completion identity.
  • Testing to fake and assert package events.
PreviousPublic APINextConsole commands
View source

On this page

  1. Event catalog
  2. Listen for recorded activity
  3. Listen for first adoption
  4. Listen for onboarding progress
  5. Listen for score state changes
  6. Transaction and listener behavior
  7. Events not dispatched
  8. What to read next