Skip to main content
Back to ScopeForged

ScopeForged Documentation

Technical documentation, guides, and feature references for the ScopeForged client portal.

Search & Analytics/Analytics

Analytics & Business Intelligence Guide

Last Updated: 2026-01-10 Status: Implemented Plan References:

  • 037-analytics-business-intelligence.md
  • 052-analytics-enhancement.md

Overview

The Analytics & Business Intelligence system provides data-driven insights into portal usage, business performance, and trends. It includes interactive dashboards, KPI tracking, trend analysis, predictive insights, drill-down exploration, period comparisons, and comprehensive export capabilities to help administrators make informed decisions.


Table of Contents

  1. Accessing Analytics
  2. Dashboard Overview
  3. Key Metrics
  4. Charts & Visualizations
  5. Period Comparisons
  6. Trend Analysis
  7. Drill-Down Exploration
  8. Export Options
  9. Custom Dashboards
  10. Technical Architecture
  11. Related Features

Accessing Analytics

Access PointLocationURLRole
Analytics DashboardAdmin sidebar/admin/analyticsAdmin
Financial AnalyticsAnalytics menu/admin/analytics/financialAdmin
Client AnalyticsAnalytics menu/admin/analytics/clientsAdmin
Project AnalyticsAnalytics menu/admin/analytics/projectsAdmin
ComparisonsAnalytics menu/admin/analytics/comparisonsAdmin
TrendsAnalytics menu/admin/analytics/trendsAdmin
Drill-DownAnalytics menu/admin/analytics/drill-downAdmin
ExportsAnalytics menu/admin/analytics/exportsAdmin

Permissions

ActionAdminClient User
View analytics dashboardYesNo
Create custom dashboardsYesNo
Export analytics dataYesNo
Configure KPIsYesNo
Use drill-downYesNo
Create comparisonsYesNo
View trend analysisYesNo

Dashboard Overview

Main Dashboard

The analytics dashboard provides at-a-glance insights:

SectionContent
KPI CardsKey performance indicators
Revenue ChartRevenue over time
Client GrowthNew clients trend
Project StatusProjects by status
Recent ActivityLatest portal activity

Time Period Selection

PeriodDescription
TodayCurrent day
This WeekCurrent week
This MonthCurrent month
This QuarterCurrent quarter
This YearCurrent year
CustomSelect date range

Key Metrics

Revenue Metrics

MetricDescriptionCalculation
Total RevenueAll-time revenueSum of paid invoices
Monthly RevenueThis monthPaid invoices this month
MRRMonthly recurringSubscription-based revenue
Revenue GrowthMonth-over-month(Current - Previous) / Previous
Average InvoiceMean invoice valueTotal / Invoice count

Client Metrics

MetricDescriptionCalculation
Total ClientsAll clientsClient count
Active ClientsWith active projectsClients with status=active projects
New ClientsAdded this periodCreated in date range
Churn RateLost clientsInactive / Total
Client Lifetime ValueAverage revenue per clientTotal revenue / Client count
Client Retention RateReturning clientsRetained / Previous period clients

Project Metrics

MetricDescriptionCalculation
Total ProjectsAll projectsProject count
Active ProjectsCurrently activeStatus = active
Completion RateCompleted projectsCompleted / Total
Average DurationDays to completeAvg(completion - start)
Projects per ClientAverage projectsProjects / Clients

Engagement Metrics

MetricDescriptionCalculation
Daily Active UsersUnique logins todayDistinct users logged in
Monthly Active UsersUnique logins this monthDistinct monthly logins
Average SessionTime spentAvg session duration
Portal AdoptionClients using portalActive clients / Total
File DownloadsDownloads per periodDownload count

Charts & Visualizations

Chart Types

The system supports 18 chart types via the ChartBuilder service:

TypeUse CaseExample
Line ChartTrends over timeRevenue by month
Bar ChartComparisonsRevenue by client
Horizontal BarRanked comparisonsTop clients by revenue
Pie ChartProportionsProjects by status
Donut ChartCompositionInvoice status breakdown
Area ChartCumulative trendsCumulative revenue
Stacked AreaMultiple series areasRevenue by category
Stacked BarGrouped comparisonsMonthly revenue by type
Grouped BarSide-by-side comparisonThis year vs last year
Radar ChartMulti-dimensionalClient health score
Polar AreaRadial proportionsCategory distribution
Scatter ChartCorrelation analysisPrice vs quantity
SankeyFlow visualizationRevenue flow by source
FunnelConversion stagesSales pipeline
WaterfallIncremental changesCash flow analysis
Bubble3D data pointsClient size/revenue/age
SparklineInline trendsDashboard KPI trends
Multi-AxisDual Y-axisRevenue + Count

Advanced Chart Types (Plan 052)

Sankey Chart

  • Visualizes flow of values between categories
  • Shows source → target relationships with proportional widths
  • Use for: Revenue flows, customer journey, resource allocation

Funnel Chart

  • Shows conversion through stages
  • Each stage shows value and percentage of previous
  • Use for: Sales pipeline, lead conversion, process completion

Waterfall Chart

  • Displays incremental changes to a starting value
  • Shows positive (green) and negative (red) changes
  • Supports subtotals at specific indices
  • Use for: Cash flow, budget variance, cumulative impact

Bubble Chart

  • 3-dimensional scatter plot (x, y, radius)
  • Can group by category with different colors
  • Use for: Client analysis, portfolio visualization

Sparkline Chart

  • Compact inline chart for dashboards
  • Shows trend direction and change percentage
  • Minimal chrome, maximum data density
  • Use for: KPI cards, tables with trends

Period Comparisons

Overview

Compare metrics across multiple time periods to identify trends and performance changes.

Location: /admin/analytics/comparisons

Comparison Types

TypeDescriptionExample
Year-over-Year (YoY)Compare same periods across years2024 vs 2023 revenue
Quarter-over-Quarter (QoQ)Compare sequential quartersQ1 vs Q2 performance
Month-over-Month (MoM)Compare sequential monthsMonthly trend analysis
Custom PeriodsDefine custom date rangesCampaign periods
Period-over-PeriodCompare any defined periodsPre/post launch

Available Metrics

MetricDescription
RevenueTotal paid invoice revenue
InvoicesInvoice count
ProjectsProject count
ClientsNew client count
Collection Rate% of invoices collected
Project Completion% of projects completed
Client Retention% of clients retained

Comparison Output

Each comparison returns:

[
    'metric' => 'revenue',
    'metric_label' => 'Revenue',
    'comparison_type' => 'year_over_year',
    'periods' => [
        [
            'label' => '2023',
            'start' => '2023-01-01',
            'end' => '2023-12-31',
            'value' => 150000,
            'change' => null,
            'change_percent' => null,
            'trend' => 'neutral',
        ],
        [
            'label' => '2024',
            'start' => '2024-01-01',
            'end' => '2024-12-31',
            'value' => 185000,
            'change' => 35000,
            'change_percent' => 23.33,
            'trend' => 'up',
        ],
    ],
    'summary' => [
        'overall_change' => 35000,
        'overall_change_percent' => 23.33,
        'overall_trend' => 'up',
        'best_period' => '2024',
        'worst_period' => '2023',
        'average' => 167500,
        'max' => 185000,
        'min' => 150000,
    ],
];

Saving Comparisons

Save frequently-used comparisons for quick access:

  1. Configure comparison parameters
  2. Click "Save Comparison"
  3. Name the comparison
  4. Optionally pin to dashboard
  5. Access from saved comparisons list

Trend Analysis

Overview

Analyze data trends using statistical methods for insights and forecasting.

Location: /admin/analytics/trends

Analysis Components

ComponentDescription
Trend DirectionUp, down, or stable
SlopeRate of change
R-squaredTrend reliability (0-1)
StatisticsMean, median, std dev
Moving AveragesSMA and EMA
ForecastPredicted future values
AnomaliesUnusual data points
SeasonalityRecurring patterns
Growth AnalysisPeriod-over-period growth

Trend Calculation

// Example trend result
[
    'direction' => 'up',        // up, down, stable, insufficient_data
    'slope' => 2.5,             // Rate of change per period
    'r_squared' => 0.95,        // Correlation coefficient
    'intercept' => 100,         // Y-intercept
    'strength' => 'strong',     // Trend strength
]

Moving Averages

TypeDescription
SMA (Simple)Equal-weighted average over window
EMA (Exponential)Recent values weighted more heavily

Forecasting

Uses linear regression with confidence intervals:

[
    'periods' => [
        [
            'period' => '2024-07',
            'value' => 182500,
            'confidence_lower' => 165000,
            'confidence_upper' => 200000,
        ],
        // ... more forecast periods
    ],
    'method' => 'linear_regression',
    'confidence_level' => 0.95,
]

Anomaly Detection

Identifies unusual values using Z-score analysis:

[
    [
        'period' => '2024-04',
        'value' => 500000,
        'expected' => 150000,
        'z_score' => 4.5,
        'type' => 'high',       // high or low
    ],
]

Growth Analysis

[
    'total_growth_percent' => 33.1,
    'average_period_growth' => 10.0,
    'cagr' => 8.5,              // Compound annual growth rate
    'growth_consistency' => 0.85,
]

Drill-Down Exploration

Overview

Explore data hierarchically, drilling from summary to detail levels.

Location: /admin/analytics/drill-down

Available Hierarchies

HierarchyLevelsDescription
RevenueYear → Quarter → Month → Week → DayTime-based revenue drill-down
TimeYear → Quarter → Month → Week → Day → HourGeneral time hierarchy
ClientsIndustry → Size → Region → ClientClient segmentation
ProjectsStatus → Type → Client → ProjectProject organization
GeographyCountry → State → CityLocation-based analysis

Using Drill-Down

  1. Select Hierarchy: Choose the dimension to explore
  2. View Summary: See top-level aggregation
  3. Click to Drill: Select a value to drill deeper
  4. View Breadcrumb: Track your drill path
  5. Navigate: Use breadcrumb to jump to any level
  6. Save Path: Bookmark useful drill paths

Drill-Down Response

[
    'hierarchy' => 'revenue',
    'hierarchy_name' => 'Revenue',
    'metric' => 'revenue',
    'current_level' => 1,
    'current_level_name' => 'year',
    'next_level' => 'quarter',
    'can_drill_deeper' => true,
    'path' => ['2024'],
    'breadcrumb' => [
        ['level' => 'year', 'value' => '2024'],
    ],
    'data' => [
        ['dimension' => '1', 'label' => 'Q1 2024', 'value' => 45000, 'drillable' => true],
        ['dimension' => '2', 'label' => 'Q2 2024', 'value' => 52000, 'drillable' => true],
        ['dimension' => '3', 'label' => 'Q3 2024', 'value' => 48000, 'drillable' => true],
        ['dimension' => '4', 'label' => 'Q4 2024', 'value' => 55000, 'drillable' => true],
    ],
    'total' => 200000,
]

Saved Drill Paths

Save and bookmark frequently-used drill paths:

FieldDescription
NameDescriptive name
HierarchyWhich hierarchy
PathArray of drill values
FiltersOptional filters applied
Is BookmarkedQuick access flag

Export Options

Overview

Export analytics data in multiple formats for reporting and external analysis.

Location: /admin/analytics/exports

Supported Formats

FormatExtensionUse Case
PDF.pdfFormatted reports
Excel.xlsxData analysis
CSV.csvData import/export
JSON.jsonAPI integration
PNG.pngChart images
SVG.svgScalable graphics
PowerPoint.pptxPresentations

Export Types

TypeDescriptionFormats
DashboardFull dashboard exportPDF, PPTX
ChartSingle chart exportPNG, SVG, PDF
DataRaw data exportCSV, Excel, JSON
ReportFormatted reportPDF, PPTX
ComparisonComparison resultsPDF, Excel, CSV
Trend AnalysisTrend reportPDF, Excel

Creating an Export

  1. Navigate to analytics section
  2. Click "Export" button
  3. Select format
  4. Configure options:
    • Include charts
    • Include data tables
    • Date range
    • Filters
  5. Click "Generate Export"
  6. Download when ready (background processing for large exports)

Export Status

StatusDescription
PendingQueued for processing
ProcessingCurrently generating
CompletedReady for download
FailedError during generation
ExpiredDownload link expired

Automatic Cleanup

Exports are automatically cleaned up after configured retention period (default: 7 days).


Custom Dashboards

Creating a Dashboard

  1. Navigate to Admin → Analytics → Dashboards
  2. Click "Create Dashboard"
  3. Enter dashboard name
  4. Add widgets:
    • Click "Add Widget"
    • Select widget type (Chart, KPI, Table)
    • Configure data source
    • Set dimensions and metrics
  5. Arrange widgets by dragging
  6. Click "Save Dashboard"

Widget Types

TypeDescription
KPI CardSingle metric with trend (uses sparkline)
Line ChartTime series data
Bar ChartCategorical comparison
Pie ChartProportional breakdown
FunnelConversion stages
WaterfallIncremental changes
BubbleMulti-dimensional analysis
Data TableTabular data view
Metric ComparisonPeriod comparison
Goal TrackerProgress toward target

Sharing Dashboards

  1. Open dashboard
  2. Click "Share"
  3. Options:
    • Copy link (view-only)
    • Schedule email delivery
    • Export as PDF/PPTX

Technical Architecture

Models

SavedComparison Model: app/Models/SavedComparison.php

class SavedComparison extends Model
{
    protected $fillable = [
        'name',
        'description',
        'metric',
        'comparison_type',
        'periods',
        'filters',
        'visualization',
        'is_pinned',
        'created_by',
    ];

    protected $casts = [
        'periods' => 'array',
        'filters' => 'array',
        'visualization' => 'array',
        'is_pinned' => 'boolean',
    ];

    const METRICS = [
        'revenue' => 'Revenue',
        'invoices' => 'Invoice Count',
        'projects' => 'Project Count',
        'clients' => 'Client Count',
        'collection_rate' => 'Collection Rate',
        'project_completion' => 'Project Completion Rate',
        'client_retention' => 'Client Retention Rate',
    ];
}

AnalyticsExport Model: app/Models/AnalyticsExport.php

class AnalyticsExport extends Model
{
    protected $fillable = [
        'name',
        'type',
        'format',
        'status',
        'parameters',
        'file_path',
        'file_size',
        'error_message',
        'started_at',
        'completed_at',
        'expires_at',
        'created_by',
    ];

    protected $casts = [
        'parameters' => 'array',
        'started_at' => 'datetime',
        'completed_at' => 'datetime',
        'expires_at' => 'datetime',
    ];
}

AnalyticsDrillPath Model: app/Models/AnalyticsDrillPath.php

class AnalyticsDrillPath extends Model
{
    protected $fillable = [
        'name',
        'metric',
        'hierarchy',
        'path',
        'filters',
        'is_bookmarked',
        'user_id',
    ];

    protected $casts = [
        'path' => 'array',
        'filters' => 'array',
        'is_bookmarked' => 'boolean',
    ];

    const HIERARCHIES = [
        'revenue' => [
            'name' => 'Revenue',
            'levels' => ['year', 'quarter', 'month', 'week', 'day'],
        ],
        'time' => [
            'name' => 'Time',
            'levels' => ['year', 'quarter', 'month', 'week', 'day', 'hour'],
        ],
        'clients' => [
            'name' => 'Clients',
            'levels' => ['industry', 'size', 'region', 'client'],
        ],
        'projects' => [
            'name' => 'Projects',
            'levels' => ['status', 'type', 'client', 'project'],
        ],
        'geography' => [
            'name' => 'Geography',
            'levels' => ['country', 'state', 'city'],
        ],
    ];
}

Services

ComparisonService: app/Services/Analytics/ComparisonService.php

MethodDescription
compare()Compare metrics across periods
yearOverYear()Year-over-year comparison
quarterOverQuarter()Quarter-over-quarter comparison
monthOverMonth()Month-over-month comparison
customPeriods()Custom period comparison
saveComparison()Save comparison configuration
getSavedComparisons()Get user's saved comparisons
runSavedComparison()Execute a saved comparison

TrendAnalyzer: app/Services/Analytics/TrendAnalyzer.php

MethodDescription
analyze()Full trend analysis
calculateTrend()Determine trend direction/slope
calculateStatistics()Basic statistics
calculateMovingAverages()SMA and EMA
forecast()Generate predictions
detectAnomalies()Find unusual values
detectSeasonality()Identify patterns
comparePeriods()Period-by-period changes
analyzeGrowth()Growth metrics

DrillDownService: app/Services/Analytics/DrillDownService.php

MethodDescription
getHierarchies()Get available hierarchies
drillDown()Drill into hierarchy level
saveDrillPath()Save drill path
getSavedDrillPaths()Get user's saved paths

AnalyticsExportService: app/Services/Analytics/AnalyticsExportService.php

MethodDescription
createExport()Create export record
processExport()Process pending export
exportToPdf()Generate PDF export
exportToExcel()Generate Excel export
exportToCsv()Generate CSV export
exportToJson()Generate JSON export
exportToImage()Generate PNG/SVG export
cleanupOldExports()Remove expired exports

ChartBuilder: app/Services/Reports/ChartBuilder.php

MethodDescription
build()Build any chart type
buildSankeyChart()Flow visualization
buildFunnelChart()Conversion funnel
buildWaterfallChart()Incremental changes
buildBubbleChart()3D scatter plot
buildSparklineChart()Inline trend
getChartTypes()List all chart types

Controllers

ControllerRoute PrefixDescription
ComparisonController/admin/analytics/comparisonsPeriod comparisons
TrendController/admin/analytics/trendsTrend analysis
DrillDownController/admin/analytics/drill-downDrill-down exploration
AnalyticsExportController/admin/analytics/exportsExport management

Routes

// Analytics routes (in web.php)
Route::prefix('admin/analytics')->middleware(['auth', 'admin'])->group(function () {
    // Existing routes...

    // Comparisons
    Route::get('comparisons', [ComparisonController::class, 'index']);
    Route::post('comparisons/compare', [ComparisonController::class, 'compare']);
    Route::get('comparisons/year-over-year', [ComparisonController::class, 'yearOverYear']);
    Route::get('comparisons/quarter-over-quarter', [ComparisonController::class, 'quarterOverQuarter']);
    Route::get('comparisons/month-over-month', [ComparisonController::class, 'monthOverMonth']);
    Route::resource('comparisons', ComparisonController::class)->only(['store', 'destroy']);
    Route::post('comparisons/{comparison}/run', [ComparisonController::class, 'run']);
    Route::patch('comparisons/{comparison}/toggle-pin', [ComparisonController::class, 'togglePin']);

    // Exports
    Route::get('exports', [AnalyticsExportController::class, 'index']);
    Route::post('exports', [AnalyticsExportController::class, 'store']);
    Route::get('exports/{export}', [AnalyticsExportController::class, 'show']);
    Route::get('exports/{export}/download', [AnalyticsExportController::class, 'download']);
    Route::delete('exports/{export}', [AnalyticsExportController::class, 'destroy']);
    Route::get('exports/meta/formats', [AnalyticsExportController::class, 'formats']);
    Route::get('exports/meta/types', [AnalyticsExportController::class, 'types']);
    Route::post('exports/cleanup', [AnalyticsExportController::class, 'cleanup']);

    // Drill-down
    Route::get('drill-down', [DrillDownController::class, 'index']);
    Route::get('drill-down/hierarchies', [DrillDownController::class, 'hierarchies']);
    Route::post('drill-down/explore', [DrillDownController::class, 'drillDown']);
    Route::post('drill-down/drill-into', [DrillDownController::class, 'drillInto']);
    Route::post('drill-down/drill-up', [DrillDownController::class, 'drillUp']);
    Route::post('drill-down/jump', [DrillDownController::class, 'jumpToLevel']);
    Route::resource('drill-down/paths', DrillDownController::class)->only(['store', 'destroy']);
    Route::get('drill-down/paths/{path}/load', [DrillDownController::class, 'load']);
    Route::patch('drill-down/paths/{path}/toggle-bookmark', [DrillDownController::class, 'toggleBookmark']);

    // Trends
    Route::post('trends/analyze', [TrendController::class, 'analyze']);
    Route::post('trends/trend', [TrendController::class, 'trend']);
    Route::post('trends/statistics', [TrendController::class, 'statistics']);
    Route::post('trends/moving-averages', [TrendController::class, 'movingAverages']);
    Route::post('trends/forecast', [TrendController::class, 'forecast']);
    Route::post('trends/anomalies', [TrendController::class, 'anomalies']);
    Route::post('trends/seasonality', [TrendController::class, 'seasonality']);
    Route::post('trends/growth', [TrendController::class, 'growth']);
    Route::post('trends/periods', [TrendController::class, 'periods']);
});

Data Caching

Analytics queries are cached for performance:

// Cache revenue metrics for 1 hour
Cache::remember('analytics:revenue:' . $period, 3600, function () use ($start, $end) {
    return $this->analyticsService->getRevenueMetrics($start, $end);
});

Cache Invalidation

Cache is cleared when relevant data changes:

// In Invoice observer
public function updated(Invoice $invoice): void
{
    if ($invoice->wasChanged('status') && $invoice->status === 'paid') {
        Cache::tags(['analytics', 'revenue'])->flush();
    }
}

Dependencies

FeatureRelationship
AuthorizationAdmin access required
InvoicingRevenue data source
Client ManagementClient metrics
Project ManagementProject metrics

Complementary Features

FeatureDescription
ReportsDetailed data exports
Admin DashboardOverview dashboard
Activity LoggingActivity metrics

Best Practices

For Data Accuracy

  1. Use consistent date ranges for comparisons
  2. Understand metric definitions
  3. Verify data sources before decisions
  4. Consider seasonality in trends
  5. Check anomaly context before acting

For Performance

  1. Cache expensive queries appropriately
  2. Use date range limits on large datasets
  3. Aggregate data for historical views
  4. Index analytical columns
  5. Use background jobs for exports

For Comparisons

  1. Compare like periods (same duration)
  2. Account for business changes between periods
  3. Use multiple metrics for context
  4. Consider external factors in analysis

For Drill-Down

  1. Save useful paths for repeated analysis
  2. Use breadcrumbs to navigate
  3. Apply filters at appropriate levels
  4. Export detail data for deep analysis

Troubleshooting

IssueSolution
Charts not loadingCheck JavaScript console
Wrong numbersVerify date range and filters
Slow dashboardReduce widgets, check cache
Missing dataVerify data exists in source
Export failsCheck storage permissions
Drill-down emptyVerify hierarchy has data
Trend insufficientNeed more data points

See Also