particle-academy / fancy-heuristics
Human + agent interaction analytics and Fancy UI pixel verification for Laravel hosts. Ingests collector events, aggregates heatmaps, and re-polls sites to verify the embedded badge stays visible.
Package info
github.com/Particle-Academy/fancy-heuristics
pkg:composer/particle-academy/fancy-heuristics
Requires
- php: ^8.2
- illuminate/console: ^11.0|^12.0|^13.0
- illuminate/contracts: ^11.0|^12.0|^13.0
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/events: ^11.0|^12.0|^13.0
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/routing: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- illuminate/validation: ^11.0|^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.26
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
README
particle-academy/fancy-heuristics is the PHP/Laravel ingestion + storage +
query backend for human + agent interaction analytics and Fancy UI pixel
verification. It is the server half of the Fancy Pixel / Fancy Heuristics
trio (paired with the @particle-academy/fancy-pixel badge embed and the
@particle-academy/fancy-heuristics-js browser collector).
- Zero third-party runtime deps —
illuminate/*only. - Namespace
FancyHeuristics\, facadeHeuristics, configconfig/heuristics.php.
Install
composer require particle-academy/fancy-heuristics php artisan vendor:publish --tag=heuristics-config # optional php artisan vendor:publish --tag=heuristics-migrations # optional (auto-loaded otherwise) php artisan migrate
The wire contract
Browser/agent clients flush JSON via navigator.sendBeacon:
POST /heuristics/collect { siteKey, sessionId, events: [ Event, ... ] }
POST /heuristics/pixel { siteKey, style, mode, visible, path, ts }
Event = {
kind: "pageview"|"click"|"scroll"|"pointer"|"dwell",
actor: "human"|"agent",
path, ts,
x?, y?, vw?, vh?, scrollPct?, dwellMs?, targetId?, label?, meta?
}
Cross-origin clients: these endpoints are posted from browsers on other origins. Exempt the route prefix from CSRF (
VerifyCsrfToken::$except) or keep them on the statelessapimiddleware group (the default). CORS headers are the host's responsibility.
Facade
use FancyHeuristics\Facades\Heuristics; Heuristics::record($event); // persist one event Heuristics::collect($payload); // persist a { siteKey, events } batch Heuristics::ping($ping); // persist a pixel liveness beacon Heuristics::heatmap($siteKey, $path); // normalised grid of pointer/click hits Heuristics::events($siteKey, [...]); // raw events, filtered Heuristics::sessionStats($siteKey); // sessions + counts by actor & kind
Pixel verification
heuristics_sites registers each site to re-poll. The verifier fetches the URL
server-side and runs the shared detection — the stable data-fancy-badge
marker or the literal "Powered by Fancy UI" wordmark (the exact same two
signals the showcase's ScanShowcaseSubmission scanner uses, kept in one place
in HeuristicsPixelDetector). It updates visible / pixel_status /
last_verified_at and fires PixelVerificationPassed / PixelVerificationFailed
for the host to toggle a listing.
Run twice daily:
// bootstrap/app.php use Illuminate\Console\Scheduling\Schedule; ->withSchedule(function (Schedule $schedule) { $schedule->command('heuristics:verify-pixels') ->cron(config('heuristics.verify.cron')); // default 03:00 & 15:00 })
php artisan heuristics:verify-pixels # all sites php artisan heuristics:verify-pixels --site=KEY # one site
Tests
composer install vendor/bin/pest