Generate actionable insights from transaction data. Use when implementing insight generators, anomaly detection, or data analysis features for financial/tax tracking applications.
Scanned 2/12/2026
Install via CLI
openskills install majiayu000/claude-skill-registry---
name: data-insights
description: Generate actionable insights from transaction data. Use when implementing insight generators, anomaly detection, or data analysis features for financial/tax tracking applications.
---
# Data Insights Skill
This skill provides patterns for generating actionable insights from transaction data, specifically designed for tax and expense tracking applications.
## When to Use This Skill
- Implementing insight generators for dashboards
- Detecting spending anomalies and patterns
- Computing aggregated statistics over time ranges
- Building ranked insight cards with drill-down capabilities
## Core Insight Types
### 1. Quiet Leaks (Small Recurring Expenses)
Detects small, frequent purchases that add up significantly.
**Trigger Rules:**
- Transaction appears 3+ times in the range
- Individual amounts ≤ $20
- Cumulative total ≥ $50
**Severity Calculation:**
```typescript
severity = Math.min(10, Math.floor(cumulativeTotal / 25))
```
**Query Pattern:**
```typescript
// Group by merchant, count occurrences, sum totals
const quietLeaks = transactions
.filter(t => parseFloat(t.totalAmount) <= 20)
.reduce((acc, t) => {
const key = t.merchant || 'Unknown';
if (!acc[key]) acc[key] = { count: 0, total: 0, transactions: [] };
acc[key].count++;
acc[key].total += parseFloat(t.totalAmount);
acc[key].transactions.push(t.id);
return acc;
}, {});
// Filter to those with 3+ occurrences and $50+ total
return Object.entries(quietLeaks)
.filter(([_, data]) => data.count >= 3 && data.total >= 50)
.map(([merchant, data]) => ({
type: 'QUIET_LEAK',
title: `${merchant} adds up`,
summary: `${data.count} purchases totaling $${data.total.toFixed(2)}`,
severityScore: Math.min(10, Math.floor(data.total / 25)),
supportingTransactionIds: data.transactions
}));
```
### 2. Tax Drag (High Tax Rate Merchants)
Identifies merchants or categories with unusually high effective tax rates.
**Trigger Rules:**
- Effective tax rate > 9% (above typical sales tax)
- At least $100 spent at merchant
**Severity Calculation:**
```typescript
severity = Math.min(10, Math.floor((effectiveTaxRate - 0.08) * 100))
```
**Query Pattern:**
```typescript
const taxDrag = transactions.reduce((acc, t) => {
const key = t.merchant || 'Unknown';
const taxRate = parseFloat(t.taxAmount) / parseFloat(t.totalAmount);
if (!acc[key]) acc[key] = { totalSpent: 0, totalTax: 0, transactions: [] };
acc[key].totalSpent += parseFloat(t.totalAmount);
acc[key].totalTax += parseFloat(t.taxAmount);
acc[key].transactions.push(t.id);
return acc;
}, {});
return Object.entries(taxDrag)
.filter(([_, data]) => {
const effectiveRate = data.totalTax / data.totalSpent;
return effectiveRate > 0.09 && data.totalSpent >= 100;
})
.map(([merchant, data]) => {
const effectiveRate = data.totalTax / data.totalSpent;
return {
type: 'TAX_DRAG',
title: `High tax burden at ${merchant}`,
summary: `${(effectiveRate * 100).toFixed(1)}% effective tax rate on $${data.totalSpent.toFixed(2)}`,
severityScore: Math.min(10, Math.floor((effectiveRate - 0.08) * 100)),
supportingTransactionIds: data.transactions
};
});
```
### 3. Spikes/Anomalies (Unusual Spending)
Detects month-over-month jumps, duplicates, or unusual amounts.
**Trigger Rules:**
- Single transaction > 2x average transaction
- Month-over-month increase > 50%
- Duplicate-like entries (same merchant + amount within 24h)
**Severity Calculation:**
```typescript
// For outliers
severity = Math.min(10, Math.floor((amount / average - 1) * 2))
// For MoM spikes
severity = Math.min(10, Math.floor((percentIncrease - 50) / 10))
```
**Query Pattern:**
```typescript
const average = transactions.reduce((sum, t) => sum + parseFloat(t.totalAmount), 0) / transactions.length;
// Find outliers
const outliers = transactions
.filter(t => parseFloat(t.totalAmount) > average * 2)
.map(t => ({
type: 'SPIKE',
title: `Unusual expense: $${parseFloat(t.totalAmount).toFixed(2)}`,
summary: `${t.merchant || 'Unknown'} - ${((parseFloat(t.totalAmount) / average - 1) * 100).toFixed(0)}% above average`,
severityScore: Math.min(10, Math.floor((parseFloat(t.totalAmount) / average - 1) * 2)),
supportingTransactionIds: [t.id]
}));
// Find duplicates
const potentialDuplicates = findDuplicates(transactions);
```
## Output Format
All insight generators must return this standardized format:
```typescript
interface Insight {
type: 'QUIET_LEAK' | 'TAX_DRAG' | 'SPIKE' | 'DUPLICATE' | 'MOM_INCREASE';
title: string; // Short, attention-grabbing headline
summary: string; // 1-2 sentence explanation
severityScore: number; // 1-10 scale for ranking
supportingTransactionIds: string[]; // For drill-down
}
```
## Implementation Structure
```
src/lib/insights/
├── index.ts # Main getInsights() function
├── types.ts # Insight interface definitions
├── generators/
│ ├── quiet-leaks.ts # detectQuietLeaks()
│ ├── tax-drag.ts # detectTaxDrag()
│ └── spikes.ts # detectSpikes()
└── __tests__/
├── quiet-leaks.test.ts
├── tax-drag.test.ts
└── spikes.test.ts
```
## Best Practices
1. **Pure Functions**: Each insight generator should be a pure function taking transactions and returning insights
2. **Configurable Thresholds**: Make trigger thresholds configurable via parameters
3. **Efficient Queries**: Compute all insights in a single pass when possible
4. **Test with Edge Cases**: Empty data, single transaction, all same merchant, etc.
5. **Sort by Severity**: Return insights sorted by severityScore descending
No comments yet. Be the first to comment!