›
byrcsc/laravel-customer-health · 1.x
Run queue workers, score recomputation, pruning, and health-state monitoring in production.
Use this checklist before customer health data drives alerts, customer success workflows, or application access decisions.
Time-window signals change even when no new event arrives. Schedule score recomputation instead of treating a stored score as permanently current:
use Illuminate\Support\Facades\Schedule;
Schedule::command('customer-health:recompute')
->hourly()
->withoutOverlapping();Run the scheduler once per minute through the deployment platform. In a database-per-tenant application, execute recomputation inside each tenant context.
Monitor non-zero exits. The command continues after a subject failure, so some scores may update while others remain stale.
When queued tracking is enabled, no product event is written until a worker handles the job.
Monitor:
RecordProductEvent jobs;A job retry can append the same raw activity again. Milestone inserts remain unique.
Run Laravel's model pruning command after setting retention_days:
php artisan model:prune \
--model='ByRcsc\LaravelCustomerHealth\Models\ProductEventRecord'Keep retention at least as long as every raw-event reporting and score window. Pruning is irreversible from package storage.
Current summary rows include computed_at. Alert or exclude rows older than
the expected recomputation cadence:
$stale = CustomerHealth::summaries()
->where('computed_at', '<', now()->subHours(2))
->get();An old summary can indicate a failed recomputation, an unresolvable subject, a missing tenant run, or an unavailable database connection.
Listen for HealthStateChanged when state transitions should trigger work.
The event fires after a score transaction commits and includes the previous
nullable state plus the new state.
The package serializes computations for the same subject and score on MySQL
and PostgreSQL. MySQL waits up to 10 seconds for its named lock, then throws
ScoreComputationLockException.
SQLite does not acquire an application lock. Avoid running overlapping computations for the same identity on SQLite when transition order matters.
withoutOverlapping() reduces scheduler overlap, but controllers or jobs can
still call compute() concurrently. Catch and retry lock timeouts through the
application's normal job retry policy.
When summaries use a landlord connection, include both the tenant history tables and landlord summary table in backup and restore plans.
After restoring or truncating summaries, run recomputation to recreate current rows. Score history alone is not read automatically to rebuild a summary.