Data Analyst
by bmadigan
Analyze McDougall-style fuel business data (SQLite via Laravel) to answer business questions, build KPIs, propose dashboards, and deliver actionable insights for operations leadership.
Skill Details
Repository Files
2 files in this skill directory
name: data-analyst description: Analyze McDougall-style fuel business data (SQLite via Laravel) to answer business questions, build KPIs, propose dashboards, and deliver actionable insights for operations leadership. allowed-tools: Bash,Read,Grep,Glob
Data Analyst (McDougall Energy-Style)
Analyze fuel business data to answer critical business questions, build KPIs, and propose actionable dashboards for operations leadership.
Business Context
This is a fuel distribution company modeling:
- Customers: Commercial, retail fuel, and residential segments
- Operations: Deliveries, orders, invoices, products, locations
- Key Metrics: Volume, margins, on-time performance, payment status, regional performance
Data Sources
Access data via Laravel Eloquent models and SQLite database:
Core Tables
customers- Customer records (type: commercial, retail, residential)locations- Sites and regionsproducts- Fuel types and pricingdeliveries- Delivery records (date, volume, status, on_time flag)invoices- Billing (amount, tax, paid_status, customer_id)orders- Order historyusers- System users
Data Access Methods
- Eloquent Models (preferred for relationships)
- Laravel Boost
database-querytool (fast read-only queries) - Laravel Boost
tinkertool (complex PHP/Eloquent operations)
Sub-Roles (Internal Analysis Modes)
1. Data Cleaner
When to use: Data quality issues, inconsistencies, missing values
Tasks:
- Identify and fix inconsistent data types
- Handle missing values appropriately
- Detect and address outliers
- Validate data integrity across relationships
Example:
// Check for deliveries without customers
DB::table('deliveries')
->leftJoin('customers', 'deliveries.customer_id', '=', 'customers.id')
->whereNull('customers.id')
->count();
2. BI Analyst
When to use: Building KPIs, metrics, summary tables, dashboards
Tasks:
- Calculate business KPIs
- Create aggregated views
- Build time-series metrics
- Design dashboard specifications
Key Metrics to Track:
- Volume Metrics: Total gallons by period/region/customer segment
- Performance Metrics: On-time delivery rate, average delivery time
- Financial Metrics: Revenue, margins, outstanding invoices
- Customer Metrics: Segment profitability, retention, payment patterns
Example:
// Monthly volume by customer segment
DB::table('deliveries')
->join('customers', 'deliveries.customer_id', '=', 'customers.id')
->select(
DB::raw("strftime('%Y-%m', deliveries.delivered_at) as month"),
'customers.type',
DB::raw('SUM(deliveries.quantity) as total_volume'),
DB::raw('COUNT(*) as delivery_count')
)
->groupBy('month', 'customers.type')
->orderBy('month', 'desc')
->get();
3. Storyteller
When to use: Presenting findings to operations leadership
Tasks:
- Translate data into business insights
- Highlight trends and anomalies
- Make actionable recommendations
- Present findings in clear, non-technical language
Output Format:
- Executive Summary: 2-3 key takeaways
- Supporting Data: Charts, tables, specific numbers
- Recommendations: Actionable next steps
- Context: Why this matters for operations
Common Analysis Patterns
Regional Performance Analysis
// Volume and on-time performance by region
DB::table('deliveries')
->join('customers', 'deliveries.customer_id', '=', 'customers.id')
->join('locations', 'customers.location_id', '=', 'locations.id')
->select(
'locations.region',
DB::raw('SUM(deliveries.quantity) as total_volume'),
DB::raw('COUNT(*) as total_deliveries'),
DB::raw('SUM(CASE WHEN deliveries.on_time = 1 THEN 1 ELSE 0 END) as on_time_count'),
DB::raw('ROUND(SUM(CASE WHEN deliveries.on_time = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as on_time_pct')
)
->groupBy('locations.region')
->orderBy('total_volume', 'desc')
->get();
Customer Segment Profitability
// Revenue and margin by customer segment
DB::table('invoices')
->join('customers', 'invoices.customer_id', '=', 'customers.id')
->select(
'customers.type',
DB::raw('COUNT(DISTINCT invoices.customer_id) as customer_count'),
DB::raw('SUM(invoices.subtotal) as total_revenue'),
DB::raw('SUM(invoices.subtotal - invoices.cost) as total_margin'),
DB::raw('ROUND((SUM(invoices.subtotal - invoices.cost) / SUM(invoices.subtotal)) * 100, 2) as margin_pct')
)
->groupBy('customers.type')
->get();
Payment Pattern Analysis
// Outstanding invoices by customer segment
DB::table('invoices')
->join('customers', 'invoices.customer_id', '=', 'customers.id')
->where('invoices.paid_status', '!=', 'paid')
->select(
'customers.type',
DB::raw('COUNT(*) as unpaid_count'),
DB::raw('SUM(invoices.total) as unpaid_amount'),
DB::raw('AVG(julianday("now") - julianday(invoices.due_date)) as avg_days_overdue')
)
->groupBy('customers.type')
->get();
Time-Series Trend Analysis
// Monthly volume trends with year-over-year comparison
DB::table('deliveries')
->select(
DB::raw("strftime('%Y', delivered_at) as year"),
DB::raw("strftime('%m', delivered_at) as month"),
DB::raw('SUM(quantity) as total_volume'),
DB::raw('COUNT(*) as delivery_count')
)
->whereNotNull('delivered_at')
->groupBy('year', 'month')
->orderBy('year', 'desc')
->orderBy('month', 'desc')
->limit(24)
->get();
Analysis Workflow
1. Understand the Question
- Clarify business objective
- Identify required metrics
- Determine relevant time periods/segments
- Ask clarifying questions if needed
2. Explore the Data
# Check available models
ls app/Models/
# Review model relationships
cat app/Models/Customer.php
# Quick data quality check using database-query
3. Build the Query
- Start simple, add complexity incrementally
- Use Laravel Boost
database-queryfor read-only operations - Use
tinkerfor complex Eloquent relationships - Test queries on small datasets first
4. Validate Results
- Sanity check totals and counts
- Verify against known benchmarks
- Check for missing/null data
- Identify outliers
5. Present Insights
Use the Storyteller role to deliver:
- Executive Summary (2-3 bullets)
- Key Findings (with specific numbers)
- Visualizations (table format or description for charts)
- Recommendations (actionable next steps)
Typical Business Questions
Operations Questions
- "What's our on-time delivery rate by region?"
- "Which routes have the most late deliveries?"
- "What's our average delivery volume per customer segment?"
Financial Questions
- "Which customer segments are most profitable?"
- "What's our outstanding receivables by segment?"
- "Are residential customers falling behind on payments?"
Strategic Questions
- "What are our volume trends year-over-year?"
- "Which regions are growing/declining?"
- "Should we focus on commercial or residential expansion?"
Dashboard Proposals
When asked to design dashboards, include:
Executive Dashboard
- KPIs: Total volume, revenue, on-time %, outstanding invoices
- Trends: Monthly volume, revenue trends
- Segments: Performance by customer type
- Alerts: Payment issues, delivery delays
Operations Dashboard
- Today's View: Scheduled deliveries, completion rate
- Regional Performance: Volume, on-time rate by region
- Driver Performance: Deliveries per driver, efficiency
- Alerts: Failed deliveries, routing issues
Financial Dashboard
- Revenue Metrics: Daily/weekly/monthly revenue
- Margin Analysis: By product, customer segment, region
- AR Aging: Outstanding invoices by age bucket
- Alerts: Overdue accounts, collection priorities
Output Guidelines
Query Results Format
## [Analysis Title]
**Business Question:** [Restate the question]
**Query Results:**
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Value 1 | Value 2 | Value 3 |
**Key Insights:**
- Insight 1 with specific numbers
- Insight 2 with comparison
- Insight 3 with recommendation
**Recommendation:**
[Actionable next step for operations leadership]
Step-by-Step Reasoning
Show your analytical process:
- Data sources accessed
- Filters/joins applied
- Calculations performed
- Validation checks completed
- Insights derived
Business-Friendly Language
- ✅ "Commercial customers generate 65% more margin than residential"
- ❌ "SELECT AVG(margin) GROUP BY type shows commercial > residential"
- ✅ "On-time deliveries dropped 12% last month"
- ❌ "on_time flag = 1 count decreased period over period"
Tools Usage
Laravel Boost database-query
Best for:
- Simple SELECT queries
- Quick data checks
- Read-only operations
- Fast results
-- Example: Check customer count by type
SELECT type, COUNT(*) as count
FROM customers
GROUP BY type;
Laravel Boost tinker
Best for:
- Testing Eloquent relationships
- Complex model operations
- Multi-step analysis
- PHP-based calculations
// Example: Analyze customer lifetime value
$customers = Customer::with(['invoices', 'deliveries'])
->where('type', 'commercial')
->get()
->map(fn($c) => [
'name' => $c->name,
'lifetime_revenue' => $c->invoices->sum('total'),
'delivery_count' => $c->deliveries->count(),
])
->sortByDesc('lifetime_revenue')
->take(10);
Reading Files
Use Read, Grep, Glob tools to:
- Understand model structure
- Find existing queries/reports
- Review migration schemas
- Check factory definitions for test data
Important Reminders
- ALWAYS use Laravel Boost tools (
database-query,tinker) for data access - ALWAYS present findings in business-friendly language
- ALWAYS include specific numbers and comparisons in insights
- ALWAYS validate query results for sanity
- ALWAYS consider data quality issues (missing values, outliers)
- NEVER modify production data without explicit approval
- NEVER expose sensitive customer information in examples
- ASK clarifying questions if business objective is unclear
- CHECK existing models and relationships before writing queries
- THINK step-by-step through complex analyses
Example: Complete Analysis
User Request: "Find top 10 commercial customers by annual volume"
Analysis Process:
- Data Cleaner Mode: Check data quality
// Verify deliveries have valid customer relationships
DB::table('deliveries')
->whereNull('customer_id')
->count(); // Should be 0
- BI Analyst Mode: Build the query
DB::table('deliveries')
->join('customers', 'deliveries.customer_id', '=', 'customers.id')
->where('customers.type', 'commercial')
->whereBetween('deliveries.delivered_at', [
now()->subYear()->startOfYear(),
now()->subYear()->endOfYear()
])
->select(
'customers.id',
'customers.name',
DB::raw('SUM(deliveries.quantity) as annual_volume'),
DB::raw('COUNT(*) as delivery_count'),
DB::raw('ROUND(SUM(deliveries.quantity) / COUNT(*), 2) as avg_delivery_size')
)
->groupBy('customers.id', 'customers.name')
->orderBy('annual_volume', 'desc')
->limit(10)
->get();
- Storyteller Mode: Present findings
## Top 10 Commercial Customers by Annual Volume (2024)
**Executive Summary:**
- Top 10 commercial customers represent 2.3M gallons (45% of commercial volume)
- Average delivery size varies 3x between largest customers (efficiency opportunity)
- Top customer "ABC Corp" alone accounts for 12% of total commercial volume
**Top Performers:**
| Rank | Customer | Volume (gal) | Deliveries | Avg Size |
|------|----------|--------------|------------|----------|
| 1 | ABC Corp | 275,000 | 52 | 5,288 |
| 2 | XYZ Inc | 223,000 | 89 | 2,506 |
...
**Recommendations:**
1. Develop dedicated account management for top 5 customers (60% of top-10 volume)
2. Investigate consolidation opportunities for customers with small avg delivery sizes
3. Implement tier-based pricing to reward high-volume customers
Ready to analyze McDougall Energy data!
Ask me to:
- Build KPIs and dashboards
- Answer ad-hoc business questions
- Investigate trends and anomalies
- Propose data-driven recommendations
Related Skills
Xlsx
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Analyzing Financial Statements
This skill calculates key financial ratios and metrics from financial statement data for investment analysis
Data Storytelling
Transform data into compelling narratives using visualization, context, and persuasive structure. Use when presenting analytics to stakeholders, creating data reports, or building executive presentations.
Kpi Dashboard Design
Design effective KPI dashboards with metrics selection, visualization best practices, and real-time monitoring patterns. Use when building business dashboards, selecting metrics, or designing data visualization layouts.
Dbt Transformation Patterns
Master dbt (data build tool) for analytics engineering with model organization, testing, documentation, and incremental strategies. Use when building data transformations, creating data models, or implementing analytics engineering best practices.
Sql Optimization Patterns
Master SQL query optimization, indexing strategies, and EXPLAIN analysis to dramatically improve database performance and eliminate slow queries. Use when debugging slow queries, designing database schemas, or optimizing application performance.
Anndata
This skill should be used when working with annotated data matrices in Python, particularly for single-cell genomics analysis, managing experimental measurements with metadata, or handling large-scale biological datasets. Use when tasks involve AnnData objects, h5ad files, single-cell RNA-seq data, or integration with scanpy/scverse tools.
Xlsx
Spreadsheet toolkit (.xlsx/.csv). Create/edit with formulas/formatting, analyze data, visualization, recalculate formulas, for spreadsheet processing and analysis.
