with one click
nappi-dashboard-update
// Update the Flight Deck Brewing distribution dashboard with the latest Nappi Distributors daily reports from Google Drive.
// Update the Flight Deck Brewing distribution dashboard with the latest Nappi Distributors daily reports from Google Drive.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | nappi-dashboard-update |
| description | Update the Flight Deck Brewing distribution dashboard with the latest Nappi Distributors daily reports from Google Drive. |
Update the Flight Deck Brewing Nappi dashboard with any new daily reports.
Nappi Distributors emails two PDF reports to nate@flightdeckbrewing.com each weekday evening:
A separate Google Apps Script (managed outside this project) automatically pulls these PDFs from Gmail, uploads them to Google Drive folder 1OG70gPUMeCrYtFGTejqFdx8p1HhOhUt0 ("Nappi Reports"), and creates Google Doc copies (triggering OCR) named YYYY-MM-DD - REPORTNAME.
This task simply reads the Google Docs from that Drive folder, parses them, and updates the dashboard. It does NOT touch Gmail.
All paths are relative to the nappi-dashboard folder inside the user's selected folder. Use ls /sessions/*/mnt/FD\ Claude\ Projects/nappi-dashboard/ to find the working directory.
text/ — cached OCR text files, named FLIGHTDECK_YYYY-MM-DD.txt and RANKALLBRW_YYYY-MM-DD.txtdata/nappi_data.json — the full data store (JSON keyed by date)data/dashboard_data.json — compact dashboard data built by build_dashboard_data.pydashboard.html — the dashboard (has const D = {...}; embedded in a script tag)parse_nappi.py — Python parser with parse_sales_comp(), parse_accounts(), build_daily_snapshot()build_dashboard_data.py — builds compact dashboard data from nappi_data.json and updates dashboard.html. Has build_dashboard_data(data) and update_dashboard_html(dashboard_data, html_path) functions.nappi_gmail_to_drive.gs — reference copy of the Google Apps Scriptimport json
with open('data/nappi_data.json') as f:
existing = json.load(f)
print("Processed dates:", sorted(existing.keys()))
Use the Google Drive search MCP tool to list documents in the Nappi Reports folder:
api_query: '1OG70gPUMeCrYtFGTejqFdx8p1HhOhUt0' in parents and mimeType = 'application/vnd.google-apps.document'
Compare document titles (e.g. 2026-03-19 - FLIGHTDECK) against already-processed dates.
If no new documents exist, report the dashboard is up to date.
For each new date, use the Google Drive fetch MCP tool to get the full document text. Then save and parse:
import sys, os, re, json
sys.path.insert(0, '/path/to/nappi-dashboard')
from parse_nappi import parse_sales_comp, parse_accounts, build_daily_snapshot
# Save text files (the parser handles markdown stripping from Drive OCR)
with open(f'text/FLIGHTDECK_{date_str}.txt', 'w') as f:
f.write(flightdeck_text)
with open(f'text/RANKALLBRW_{date_str}.txt', 'w') as f:
f.write(rankallbrw_text)
# Parse
sc_data = parse_sales_comp(text_content=flightdeck_text)
ac_data = parse_accounts(text_content=rankallbrw_text)
snapshot = build_daily_snapshot(sc_data, ac_data, date_str)
import json
from build_dashboard_data import build_dashboard_data, update_dashboard_html
# Merge into data store
with open('data/nappi_data.json') as f:
all_data = json.load(f)
all_data[date_str] = snapshot
with open('data/nappi_data.json', 'w') as f:
json.dump(all_data, f, indent=2)
# Build compact dashboard data and update HTML
dashboard = build_dashboard_data(all_data)
compact = json.dumps(dashboard, separators=(',', ':'))
with open('data/dashboard_data.json', 'w') as f:
f.write(compact)
update_dashboard_html(dashboard, 'dashboard.html')
Note: The dashboard HTML uses const D = {...}; (not DATA). The update_dashboard_html function handles the regex replacement correctly.
The dashboard uses a compact JSON format built by build_dashboard_data.py. It contains:
trend[] — daily totals: date, mtd, on_hand, accounts, activeproducts{} — per-SKU trends: name, format, ce_factor, daily snapshotsaccounts{} — new_by_date, reorder_watch (5+ report-days since last order), upsell (1-2 product accounts), order_log (last 30 orders)reps{} — scorecard with mtd, accts, daily, new_accts, trend (up/down/steady), historyproduction{} — alerts (CRITICAL/ORDER_NOW), velocity, stockout_projections, format_mixtotals{} — latest sales comp totals45000: P3 Pale Ale 4PK CAN
45003: P3 Pale Ale 1/6 BBL
45005: Subhunter IPA 4PK CAN
45008: Subhunter IPA 1/6 BBL
45010: Wings Hazy IPA 4PK CAN
45013: Wings Hazy IPA 1/6 BBL
45015: Plane Beer Pilsner 6PK CAN
45018: Plane Beer Pilsner 1/6 BBL
45020: Remove Before Flight 4PK CAN
45023: Remove Before Flight 1/6 BBL
45038: Real Maine Italian Pilsner 1/6 BBL