cellar-health-analyzer

Lbstrydom's avatarfrom Lbstrydom

Analyzes cellar health and generates improvement recommendations. Use when user asks about cellar status, drinking priorities, collection balance, or says "analyze cellar", "cellar health", "what should I drink", "collection balance".

0stars🔀0forks📁View on GitHub🕐Updated Jan 10, 2026

When & Why to Use This Skill

The Cellar Health Analyzer is a sophisticated management tool designed to optimize wine collection longevity and variety. It performs deep-dive analytics on inventory data to calculate drinking window risks, assess collection diversity, and evaluate event readiness. By consolidating data into a unified health report, it provides collectors with actionable insights to prevent wine spoilage and maintain a balanced, high-quality cellar.

Use Cases

  • Inventory Risk Management: Identify 'Critical' and 'High Risk' bottles that are past their peak or nearing expiration to ensure premium wines are consumed at their optimal quality.
  • Strategic Collection Building: Analyze diversity gaps across wine colors, countries of origin, and price points to inform smarter purchasing decisions and create a more balanced portfolio.
  • Event & Hospitality Planning: Automatically assess if the current cellar inventory is prepared for various social scales, from intimate dinners to large gatherings, with specific bottle recommendations.
  • Smart Fridge Maintenance: Compare current wine fridge contents against ideal 'par levels' to receive automated restock suggestions from the main cellar for immediate accessibility.
namecellar-health-analyzer
descriptionAnalyzes cellar health and generates improvement recommendations. Use when user asks about cellar status, drinking priorities, collection balance, or says "analyze cellar", "cellar health", "what should I drink", "collection balance".
allowed-toolsRead, Bash(node:*), Glob, Grep

Cellar Health Analyzer Skill

Overview

Performs comprehensive analysis of the wine cellar to identify wines at risk, collection imbalances, readiness for events, and actionable recommendations. Consolidates data from multiple sources into a unified health report.

When to Use

  • Periodic cellar health check
  • Planning wine purchases
  • Preparing for events/parties
  • Identifying wines to drink soon
  • User says: "analyze cellar", "cellar health", "what should I drink", "collection balance", "cellar report"

Health Metrics

The cellar health service (src/services/cellarHealth.js) calculates:

1. Drinking Window Risk

Risk Level Criteria Action
Critical Past drink_until date Drink immediately or discard
High Within 3 months of drink_until Drink within weeks
Medium Past peak, before drink_until Drink within months
Low At or approaching peak Optimal drinking time
None Before drink_from Continue aging

2. Collection Diversity Score

Measures balance across:

  • Colours: Red/White/Rosé/Sparkling/Dessert ratio
  • Countries: Geographic diversity
  • Styles: Variety of wine styles
  • Price points: Distribution across budget/mid/premium
  • Vintages: Age distribution

3. Event Readiness

Assesses ability to host events with suitable wines:

  • Casual dinner (2-4 people): Need 2-3 bottles
  • Dinner party (6-8 people): Need 4-6 bottles
  • Large gathering (12+): Need 8+ bottles

Considers:

  • Fridge-ready bottles (chilled whites/rosé/sparkling)
  • Reduce-now candidates (drink urgency)
  • Style variety for pairing options

4. Fridge Gap Analysis

Compares current fridge contents to par levels:

const PAR_LEVELS = {
  'Sparkling': 2,
  'Light White': 2,
  'Full White': 1,
  'Rosé': 1,
  'Light Red': 1,  // For chilling
  'Dessert': 1
};

Analysis Process

Step 1: Gather Data

Query the database for:

-- All wines with drinking windows
SELECT w.*,
       dw.drink_from, dw.drink_peak, dw.drink_until,
       COUNT(s.id) as bottle_count
FROM wines w
LEFT JOIN drinking_windows dw ON w.id = dw.wine_id
LEFT JOIN slots s ON s.wine_id = w.id
GROUP BY w.id;

-- Fridge contents
SELECT * FROM slots WHERE location_code LIKE 'F%';

-- Reduce-now list
SELECT * FROM reduce_now ORDER BY priority;

Step 2: Calculate Risk Scores

function calculateRiskScore(wine, today) {
  if (!wine.drink_until) return { level: 'unknown', score: 0 };

  const daysUntilExpiry = daysBetween(today, wine.drink_until);
  const daysUntilPeak = wine.drink_peak ? daysBetween(today, wine.drink_peak) : null;

  if (daysUntilExpiry < 0) return { level: 'critical', score: 100 };
  if (daysUntilExpiry < 90) return { level: 'high', score: 80 };
  if (daysUntilPeak && daysUntilPeak < 0) return { level: 'medium', score: 50 };
  if (daysUntilPeak && daysUntilPeak < 180) return { level: 'low', score: 30 };
  return { level: 'none', score: 0 };
}

Step 3: Analyze Diversity

function calculateDiversityScore(wines) {
  const metrics = {
    colourBalance: calculateDistributionScore(wines, 'colour'),
    countrySpread: calculateDistributionScore(wines, 'country'),
    styleVariety: calculateDistributionScore(wines, 'style'),
    vintageRange: calculateVintageSpread(wines),
    priceDistribution: calculatePriceDistribution(wines)
  };

  return {
    overall: average(Object.values(metrics)),
    breakdown: metrics,
    gaps: identifyGaps(wines)
  };
}

Step 4: Generate Recommendations

Prioritize recommendations by impact:

  1. Immediate actions (Critical wines)
  2. This week (High-risk wines, fridge restocking)
  3. This month (Medium-risk, event prep)
  4. Shopping list (Collection gaps)

Output Format

Summary Dashboard

╔══════════════════════════════════════════════════════════════╗
║                    CELLAR HEALTH REPORT                       ║
║                      10 January 2026                          ║
╠══════════════════════════════════════════════════════════════╣
║  Overall Health Score: 78/100  [████████░░] Good              ║
╠══════════════════════════════════════════════════════════════╣
║  Total Bottles: 127                                           ║
║  Unique Wines: 89                                             ║
║  Avg Age: 3.2 years                                           ║
║  Avg Value: R285/bottle                                       ║
╚══════════════════════════════════════════════════════════════╝

Risk Summary

DRINKING WINDOW STATUS
══════════════════════

🔴 Critical (Past Due):     3 bottles
   - Meerlust Rubicon 2015 (2 bottles) - 18 months overdue
   - Kanonkop Pinotage 2016 (1 bottle) - 6 months overdue

🟠 High Risk (< 3 months):  5 bottles
   - Mulderbosch Chenin 2019 - expires Feb 2026
   - Tokara Director's 2018 - expires Mar 2026

🟡 Approaching Peak:        12 bottles
   - Various wines entering optimal window

🟢 Optimal/Aging:           107 bottles

Diversity Analysis

COLLECTION BALANCE
══════════════════

By Colour:
  Red:       68% ████████████████░░░░ (86 bottles)
  White:     22% █████░░░░░░░░░░░░░░░ (28 bottles)
  Rosé:       4% █░░░░░░░░░░░░░░░░░░░ (5 bottles)
  Sparkling:  4% █░░░░░░░░░░░░░░░░░░░ (5 bottles)
  Dessert:    2% ░░░░░░░░░░░░░░░░░░░░ (3 bottles)

  ⚠️ Consider adding more white wines for balance

By Country:
  South Africa: 72% ██████████████░░░░░░ (91 bottles)
  France:       15% ███░░░░░░░░░░░░░░░░░ (19 bottles)
  Italy:         8% ██░░░░░░░░░░░░░░░░░░ (10 bottles)
  Other:         5% █░░░░░░░░░░░░░░░░░░░ (7 bottles)

Fridge Status

FRIDGE GAP ANALYSIS
═══════════════════

Current: 6/9 slots filled

Category        Have    Target   Status
─────────────────────────────────────────
Sparkling         1        2     ⚠️ Need 1 more
Light White       2        2     ✓ OK
Full White        1        1     ✓ OK
Rosé              1        1     ✓ OK
Light Red         1        1     ✓ OK
Dessert           0        1     ⚠️ Need 1

Suggested Restocks (from cellar):
  1. Graham Beck Brut → Sparkling slot
  2. Klein Constantia Vin de Constance → Dessert slot

Recommendations

RECOMMENDED ACTIONS
═══════════════════

IMMEDIATE (This Week):
  1. 🔴 Drink: Meerlust Rubicon 2015 - significantly past peak
  2. 🔴 Drink: Kanonkop Pinotage 2016 - past drinking window
  3. 🟠 Plan dinner: Mulderbosch Chenin 2019 expires Feb

THIS MONTH:
  4. Move to fridge: Graham Beck Brut (for sparkling par level)
  5. Consider drinking: 3 wines approaching peak

SHOPPING LIST (Gaps to Fill):
  - White wines (especially Chardonnay, Riesling)
  - Sparkling for events
  - Dessert wine for fridge par level

EVENT READINESS:
  ✓ Ready for casual dinner (3+ suitable bottles)
  ✓ Ready for dinner party (5+ bottles)
  ⚠️ Large gathering may need more variety in whites

API Endpoints

// Full health analysis
GET /api/cellar/health
Response: { score, risks, diversity, fridge, recommendations }

// Risk wines only
GET /api/cellar/health/risks
Response: { critical, high, medium }

// Diversity analysis
GET /api/cellar/health/diversity
Response: { colours, countries, styles, gaps }

// Fridge status
GET /api/cellar/fridge/status
Response: { current, parLevels, gaps, suggestions }

Key Files

File Purpose
src/services/cellarHealth.js Main health calculation logic
src/services/fridgeStocking.js Fridge par levels and suggestions
src/routes/cellarHealth.js API endpoints
src/config/cellarThresholds.js Risk thresholds and par levels

Example Usage

User: "How's my cellar looking? What should I drink soon?"

Claude will:

  1. Query all wines with drinking windows
  2. Calculate risk scores for each
  3. Analyze collection diversity
  4. Check fridge against par levels
  5. Generate prioritized recommendations
  6. Present dashboard summary with actionable items

User: "Prepare a health report for my cellar"

Claude will:

  1. Run full analysis
  2. Export detailed markdown report
  3. Highlight immediate actions
  4. Suggest shopping list for gaps
  5. Rate overall cellar health score