← Back to Dashboard
Build Log · Internal

How the Dashboard Works

A running log of what's been built, how data flows in, what each piece of logic actually does, and what we still need to wire up. Update this as we go.

What the Dashboard Is

The Client Health Dashboard is a live snapshot of every HelloSciCom client we currently work with. Each card shows hours used vs. retainer this month, the hourly rate (with retainer discount), a link to the contract, the creative lead, and the status of next month's retainer. Cards are clickable for a detail/drill-down view.

Goal: at a glance, everyone on the team can answer "are we on track with this client, and is the client looped in?"

Where the Data Comes From

Storage: Cloudflare KV namespace CRM_DATA, key dashboard:v1. Reads via GET /api/dashboard-data, writes via PUT with header X-Potoo-Secret.

The Two Pieces of Logic That Drive Color

1. Countdown to the 15th (next month's retainer)

Each month, by the 15th, creative leads need to confirm next month's retainer with their clients. The countdown box on each card is a gentle nudge to make that happen.

2. Health bar color (hours used vs. retainer)

The bar fills with the percentage of retainer hours used. The colors mean:

Why the under-trigger is conservative: Sarah's note in the build meeting — err on the side of not triggering. Creative leads plan hours their own way and we don't know what's "normal" for each client. The 60% / 5-days / 10-hrs floor combo means this fires rarely, and there's a one-click dismiss for the rest of the month if it's a false alarm. Tunable in dashboard.htmlcomputeUnderTrigger().

The "Client informed of over/under?" toggle

Only appears when a trigger has fired (over or under). The most important thing is always communication to the client — going over or under is fine as long as they know. Once toggled on:

On the 1st of each month, signoff and dismissal state reset automatically (handled by the data layer).

Files & Endpoints

What I Need from Willa / Sarah

Data still to fill in

Recently confirmed

Changelog

2026-06-04
v2 (current) — Nav refactor, confirm flow, internal-strip scoping
Site-wide top navigation replaces the per-page hamburger menus. Built as a single partial (partials/nav.html) injected into every page via scripts/inject-nav.py. Structure: Chat · Clients ▾ (Dashboard, CRM, Prospects, Research) · Potoo Corner ▾ (Health, Mind, Skills) · North Star. Desktop hover-bridge dropdowns; mobile collapses to a left-side hamburger.

Standardized content widths to 1200px (chat at 1000px). All pages now feel desktop-first; mobile is responsive.

Next-month retainer confirm flow: unconfirmed cards now show "Suggested: XX hrs" in greyed italic + a clickable [unconfirmed] pill. Click → modal asks "Has next month been confirmed? For how many hours?" → on yes, PUTs new hours + confirmed=true + timestamp to KV; bar flips to confirmed state immediately.

Internal Hours strip moved inside the Retainer tab (was visible under both tabs).

Memory sync: retainer confirmations now flow into Potoo's heartbeat → MEMORY.md so I track the history of when each client confirmed each month.
2026-06-02 → 2026-06-03
Per-client detail pages
Built KV-backed detail page system (functions/api/dashboard-detail.js, key dashboard:detail:v1). Each client gets a profile with headline meta, contacts, latest activity, scope/objectives, working notes, and a "data needed from CL" reminder banner. Card layout adapts to clientType: "flat-rate" | "retainer".

Carnegie detail page fully populated (5 Carnegie contacts, 6 SOW sections, hosts, contract terms). RWJF skeleton built; filled in 2026-06-03 with Sarah's grant context: $113K HSC labor of $200K total, full Comedy Camp ownership map, 4-bucket budget structure, contractor lines (with $24K/$20K flagged for revision), 12-month timeline.

Info-request emails sent to Andrew (JLS, talkSTEM, RWJF), Hebba (Cobblestone, talkSTEM, IEEE), Sarah (RWJF + Carnegie). Sarah replied 2026-06-03; Andrew + Hebba pending (deadline: end of week).
2026-06-02
Two-tab split + flat-rate cards
Dashboard split into Monthly Retainer tab (Poley, Cobblestone, JLS, talkSTEM, IEEE) and Flat-rate / Project tab (RWJF, Carnegie). Flat-rate cards show $-spent / $-budget with progress bar (dollars-aware), event date / grant context, and lifetime hours.

Refresh script gained LIFETIME_START per-client filtering + Phase C lifetime aggregation. Carnegie scoped to Oct-2026 contract only ($-spent now reads 4% of $8K, not 263% of all-time work).
2026-05-22
RWJF Comedy-Camp invoice automation
Monthly cron c3ce752e-9518-4fb5-8590-d8960ed9e95a fires 12:15pm ET on the 1st: pulls RWJF (a.k.a. "Comedy Camp") hours per contractor from Avaza, multiplies by $200/hr, writes into the Labor_Detail tab of the Invoice Tracker (rows 7–11, Apr-26 → Mar-27 columns). Confirmed working April-2026 trial with Mattheus + Eli.
2026-05-14 · later same day
Build Log truth pass
Caught and corrected stale language on this page and on the dashboard: hours are not email-parsed — they sync live from Avaza via the existing REST API integration (LaunchAgent + Python script described above). Roadmap item "build the Avaza integration" reframed as "add a verifier pass to the existing sync."
2026-05-14
v2 — Smarter color logic, countdown windowing, build-log page
Countdown box now hides outside the 8th→15th window (and shows "OVERDUE" after the 15th if unconfirmed). The "Client informed?" pill no longer appears by default — it only surfaces when an over-trigger or under-trigger fires. Added a new under-trigger (≤5 days left + <60% used + retainer ≥10 hrs) with a one-click dismiss for the rest of the month. Created this page and moved all build notes here from the bottom of the dashboard.
earlier
v1 — Live Avaza hours
Hours pull directly from Avaza (current month, all entries). Sub-client roll-ups working for Poley and JLS. Retainer-tier rate discounts (-$20 at 10 hrs, -$30 at 20, -$40 at 40, -$50 at 60) applied to displayed rate. Sticky header + drill-down detail pages live.
v0
v0 — Draft / Internal Tool
Initial cards, seed data, KV-backed signoff toggle.

Roadmap

Done since v2

This page is internal to HelloSciCom. Last meaningful update: 2026-06-04.