claude-desktop-skills/analytics-builder/SKILL.md
You are an expert at building analytics solutions and business intelligence systems.
npx skillsauth add ViggyV/claude-skills Analytics BuilderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are an expert at building analytics solutions and business intelligence systems.
This skill activates when the user needs help with:
Ask about:
┌─────────────────────────────────────────────────────────────────┐
│ ANALYTICS ARCHITECTURE │
├─────────────────────────────────────────────────────────────────┤
│ RAW DATA TRANSFORM AGGREGATE SERVE │
│ ┌─────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Event│───────▶│ Cleaned │────▶│ Fact │───▶│Dashboard│ │
│ │Logs │ │ Data │ │ Tables │ │ BI │ │
│ └─────┘ └─────────┘ └─────────┘ └─────────┘ │
│ ┌─────┐ │ │ │ │
│ │ DB │──────────────┘ ┌──────┴──────┐ │ │
│ └─────┘ │ Dim Tables │ │ │
│ ┌─────┐ └─────────────┘ │ │
│ │ API │────────────────────────────────────────────┘ │
│ └─────┘ │
└─────────────────────────────────────────────────────────────────┘
-- Dimension Tables
CREATE TABLE dim_date (
date_key INT PRIMARY KEY,
full_date DATE NOT NULL,
year INT NOT NULL,
quarter INT NOT NULL,
month INT NOT NULL,
month_name VARCHAR(20),
week INT NOT NULL,
day_of_week INT NOT NULL,
day_name VARCHAR(20),
is_weekend BOOLEAN,
is_holiday BOOLEAN
);
CREATE TABLE dim_customer (
customer_key INT PRIMARY KEY,
customer_id VARCHAR(50) NOT NULL,
customer_name VARCHAR(200),
email VARCHAR(255),
segment VARCHAR(50),
tier VARCHAR(20),
city VARCHAR(100),
country VARCHAR(100),
created_at TIMESTAMP,
-- SCD Type 2 columns
effective_from TIMESTAMP,
effective_to TIMESTAMP,
is_current BOOLEAN
);
CREATE TABLE dim_product (
product_key INT PRIMARY KEY,
product_id VARCHAR(50) NOT NULL,
product_name VARCHAR(200),
category VARCHAR(100),
subcategory VARCHAR(100),
brand VARCHAR(100),
unit_cost DECIMAL(10,2),
is_active BOOLEAN
);
-- Fact Table
CREATE TABLE fact_sales (
sale_key BIGINT PRIMARY KEY,
date_key INT REFERENCES dim_date(date_key),
customer_key INT REFERENCES dim_customer(customer_key),
product_key INT REFERENCES dim_product(product_key),
quantity INT NOT NULL,
unit_price DECIMAL(10,2) NOT NULL,
discount_amount DECIMAL(10,2) DEFAULT 0,
gross_amount DECIMAL(10,2) NOT NULL,
net_amount DECIMAL(10,2) NOT NULL,
order_id VARCHAR(50),
created_at TIMESTAMP
);
-- Indexes for common queries
CREATE INDEX idx_fact_sales_date ON fact_sales(date_key);
CREATE INDEX idx_fact_sales_customer ON fact_sales(customer_key);
CREATE INDEX idx_fact_sales_product ON fact_sales(product_key);
-- Daily revenue trend
SELECT
d.full_date,
d.day_name,
COUNT(DISTINCT f.order_id) as total_orders,
COUNT(DISTINCT f.customer_key) as unique_customers,
SUM(f.net_amount) as total_revenue,
AVG(f.net_amount) as avg_order_value
FROM fact_sales f
JOIN dim_date d ON f.date_key = d.date_key
WHERE d.full_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY d.full_date, d.day_name
ORDER BY d.full_date;
-- Customer cohort analysis
WITH first_purchase AS (
SELECT
customer_key,
DATE_TRUNC('month', MIN(created_at)) as cohort_month
FROM fact_sales
GROUP BY customer_key
),
monthly_activity AS (
SELECT
f.customer_key,
fp.cohort_month,
DATE_TRUNC('month', f.created_at) as activity_month,
SUM(f.net_amount) as revenue
FROM fact_sales f
JOIN first_purchase fp ON f.customer_key = fp.customer_key
GROUP BY f.customer_key, fp.cohort_month, DATE_TRUNC('month', f.created_at)
)
SELECT
cohort_month,
activity_month,
(EXTRACT(YEAR FROM activity_month) - EXTRACT(YEAR FROM cohort_month)) * 12 +
(EXTRACT(MONTH FROM activity_month) - EXTRACT(MONTH FROM cohort_month)) as months_since_first,
COUNT(DISTINCT customer_key) as customers,
SUM(revenue) as total_revenue
FROM monthly_activity
GROUP BY cohort_month, activity_month
ORDER BY cohort_month, activity_month;
-- Product performance
SELECT
p.category,
p.product_name,
COUNT(DISTINCT f.order_id) as times_ordered,
SUM(f.quantity) as units_sold,
SUM(f.net_amount) as total_revenue,
SUM(f.net_amount) / SUM(SUM(f.net_amount)) OVER() * 100 as revenue_pct
FROM fact_sales f
JOIN dim_product p ON f.product_key = p.product_key
WHERE f.date_key >= (SELECT date_key FROM dim_date WHERE full_date = CURRENT_DATE - INTERVAL '30 days')
GROUP BY p.category, p.product_name
ORDER BY total_revenue DESC;
-- RFM Analysis
WITH rfm AS (
SELECT
customer_key,
CURRENT_DATE - MAX(d.full_date)::date as recency_days,
COUNT(DISTINCT order_id) as frequency,
SUM(net_amount) as monetary
FROM fact_sales f
JOIN dim_date d ON f.date_key = d.date_key
WHERE d.full_date >= CURRENT_DATE - INTERVAL '1 year'
GROUP BY customer_key
),
rfm_scores AS (
SELECT
customer_key,
NTILE(5) OVER (ORDER BY recency_days DESC) as r_score,
NTILE(5) OVER (ORDER BY frequency) as f_score,
NTILE(5) OVER (ORDER BY monetary) as m_score
FROM rfm
)
SELECT
customer_key,
r_score, f_score, m_score,
CONCAT(r_score, f_score, m_score) as rfm_segment,
CASE
WHEN r_score >= 4 AND f_score >= 4 THEN 'Champions'
WHEN r_score >= 3 AND f_score >= 3 THEN 'Loyal'
WHEN r_score >= 4 AND f_score <= 2 THEN 'New Customers'
WHEN r_score <= 2 AND f_score >= 3 THEN 'At Risk'
WHEN r_score <= 2 AND f_score <= 2 THEN 'Lost'
ELSE 'Other'
END as segment_name
FROM rfm_scores;
-- Pre-aggregated daily metrics
CREATE MATERIALIZED VIEW mv_daily_metrics AS
SELECT
date_key,
COUNT(DISTINCT order_id) as orders,
COUNT(DISTINCT customer_key) as customers,
SUM(quantity) as units_sold,
SUM(net_amount) as revenue,
AVG(net_amount) as avg_order_value
FROM fact_sales
GROUP BY date_key;
CREATE UNIQUE INDEX idx_mv_daily_metrics ON mv_daily_metrics(date_key);
-- Refresh strategy
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_daily_metrics;
-- Rolling metrics view
CREATE MATERIALIZED VIEW mv_rolling_metrics AS
SELECT
d.full_date,
SUM(m.revenue) OVER (ORDER BY d.full_date ROWS 6 PRECEDING) as revenue_7d,
SUM(m.revenue) OVER (ORDER BY d.full_date ROWS 29 PRECEDING) as revenue_30d,
AVG(m.avg_order_value) OVER (ORDER BY d.full_date ROWS 6 PRECEDING) as avg_aov_7d
FROM mv_daily_metrics m
JOIN dim_date d ON m.date_key = d.date_key;
import pandas as pd
import numpy as np
def calculate_growth_rate(df: pd.DataFrame, value_col: str, period_col: str) -> pd.DataFrame:
"""Calculate period-over-period growth rate."""
df = df.sort_values(period_col)
df['prev_value'] = df[value_col].shift(1)
df['growth_rate'] = (df[value_col] - df['prev_value']) / df['prev_value'] * 100
return df
def calculate_moving_average(df: pd.DataFrame, value_col: str, windows: list = [7, 30]) -> pd.DataFrame:
"""Add moving averages."""
for window in windows:
df[f'ma_{window}'] = df[value_col].rolling(window=window).mean()
return df
def segment_customers(df: pd.DataFrame) -> pd.DataFrame:
"""RFM segmentation."""
# Calculate RFM metrics
rfm = df.groupby('customer_id').agg({
'order_date': lambda x: (pd.Timestamp.now() - x.max()).days,
'order_id': 'count',
'amount': 'sum'
}).rename(columns={
'order_date': 'recency',
'order_id': 'frequency',
'amount': 'monetary'
})
# Score each metric
for col in ['recency', 'frequency', 'monetary']:
ascending = col == 'recency'
rfm[f'{col}_score'] = pd.qcut(rfm[col], q=5, labels=[1,2,3,4,5], duplicates='drop')
if ascending:
rfm[f'{col}_score'] = 6 - rfm[f'{col}_score'].astype(int)
return rfm
Provide:
data-ai
Use this skill for reinforcement learning tasks including training RL agents (PPO, SAC, DQN, TD3, DDPG, A2C, etc.), creating custom Gym environments, implementing callbacks for monitoring and control,
testing
You are an expert at optimizing SQL queries for performance and efficiency.
tools
Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a G
tools
21 production-ready scripts for iOS app testing, building, and automation. Provides semantic UI navigation, build automation, accessibility testing, and simulator lifecycle management. Optimized for A