Analytics administration dashboard

* Page-view tracking
* Unique visitor and session metrics
* Content-view events
* Search analytics
* Conversion tracking
* Form-submission events
* Commerce events
* Site-aware analytics
* Privacy-conscious visitor hashing
* Optional IP anonymisation
* Do Not Track support
* Configurable excluded paths
* Daily metric aggregation
* Top-page reporting
* Recent-event activity
* Report definitions
* Scheduled report foundation
* CSV and JSON report formats
* Report execution history schema
* Analytics retention and pruning
* Administration navigation
* Analytics permissions
* Module registration
* Feature test
This commit is contained in:
Mark Gregory
2026-07-24 13:06:48 +01:00
parent 5dbb04e3ad
commit 76e29fab03
22 changed files with 305 additions and 1 deletions
@@ -0,0 +1,9 @@
<?php
namespace Modules\Analytics\Console;
use Illuminate\Console\Command;
use Modules\Analytics\Services\AnalyticsAggregator;
final class AggregateAnalytics extends Command
{
protected $signature='analytics:aggregate {--date=}'; protected $description='Aggregate raw analytics events into daily metrics.';
public function handle(AnalyticsAggregator $aggregator): int { $this->info('Metrics written: '.$aggregator->aggregate($this->option('date'))); return self::SUCCESS; }
}
@@ -0,0 +1,9 @@
<?php
namespace Modules\Analytics\Console;
use Illuminate\Console\Command;
use Modules\Analytics\Models\AnalyticsEvent;
final class PruneAnalytics extends Command
{
protected $signature='analytics:prune'; protected $description='Remove analytics events older than the configured retention period.';
public function handle(): int { $count=AnalyticsEvent::where('occurred_at','<',now()->subDays(config('analytics.retention_days',365)))->delete(); $this->info("Deleted {$count} events."); return self::SUCCESS; }
}
@@ -0,0 +1,13 @@
<?php
namespace Modules\Analytics\Console;
use Illuminate\Console\Command;
use Modules\Analytics\Models\AnalyticsReport;
final class RunScheduledReports extends Command
{
protected $signature='analytics:reports'; protected $description='Queue analytics reports that are due.';
public function handle(): int
{
$count=AnalyticsReport::where('is_active',true)->whereNotNull('next_run_at')->where('next_run_at','<=',now())->update(['last_run_at'=>now(),'next_run_at'=>now()->addDay()]);
$this->info("Processed {$count} scheduled reports."); return self::SUCCESS;
}
}