Security Analytics - v1.0.0

Reports

ReportGenerator produces structured reports against the security_events and related tables. Six report types ship.

Shipped report types

Type Audience Contents
ExecutiveSummaryReport Leadership Headline metrics, period-over-period delta, incident count
IncidentReport Security team Per-incident detail with timeline + actions taken
ComplianceReport Audit / GRC Access logs, authentication trail, retention compliance
ThreatReport Security team Threat intel matches, top attackers, malicious IP/URL list
TrendReport Security team Time-series breakdown of event volume by type / severity
UserActivityReport IT / managers Per-user activity summary, anomaly history

Generating on demand

$report = security_analytics()->reports()->generate(
    type: 'executive_summary',
    from: now()->subMonth(),
    to: now(),
    format: 'pdf',   // pdf | csv | json
);

$report->disk;   // 'local'
$report->path;   // 'security-reports/executive-summary-2026-04-18-to-2026-05-18.pdf'
$report->url();  // pre-signed URL when the disk supports it

The format list and storage location are configurable in config('artisanpack.security-analytics.reports').

Scheduling reports

ScheduledReport rows drive recurring generation:

use ArtisanPackUI\SecurityAnalytics\Models\ScheduledReport;

ScheduledReport::create([
    'type'       => 'executive_summary',
    'frequency'  => 'weekly',    // daily | weekly | monthly
    'format'     => 'pdf',
    'recipients' => ['ciso@example.com', 'cto@example.com'],
    'enabled'    => true,
]);

The GenerateScheduledReport job runs on schedule ($schedule->command('security:generate-report') daily) and dispatches each due ScheduledReport. The generated file lands on the configured disk; recipients get an email with a download link.

CLI invocation

php artisan security:generate-report executive_summary --from=2026-04-01 --to=2026-04-30 --format=pdf

Useful for one-off generation outside the scheduled cycle.

Building a custom report

Implement ReportInterface (generate, getName, getSupportedFormats) or subclass AbstractReport for the common shape (date range, format selection, file output). Bind your class in a service provider and register via ReportGenerator::extend('my_report', MyReport::class).