Changelog — What Shipped
The running record of what shipped on the FCR Dashboard platform, newest first. This page is the single home for feature news — the README and architecture docs link here instead of restating it. Add new entries at the top of the current month when a feature ships (one bullet, bold name, ship month, what it does, key files/surfaces).
July 2026
Section titled “July 2026”- NBA DF-completion re-draft sweep (2026-07-01) — when a Digital Footprint audit finishes for a deal with a pending next-best-action, a sweep auto-completes the draft from the finished report (
draft_from_reportmode — no re-scan), keyed on the report’ssynced_at+ score. Routedashboard-nba-draft-completion-run; see Next-Best-Action. - PMax spend restored across ads surfaces (2026-06-30 → 07-02) — Google stopped emitting
ad_network_type=MIXEDfor Performance Max (last data 2026-05-19), silently blanking PMax rows.dashboard-ads-mtd,dashboard-ads-statsanddashboard-ads-account-detailnow read2_Ads_Data_view, which buckets PMax by the campaign’sadvertising_channel_type(never by campaign name). Brief:docs/DEV_BRIEF_pmax_channel_type_2026-06-30.md. - Planning Studio front-end live (2026-07-02) — the Marketing & Planning Studio UI is live on the dashboard over the segment engine (
dashboard-segment-build/-crossmatch/-save,dashboard-planning-advise).
June 2026
Section titled “June 2026”- Next-Best-Action (NBA) engine + sales-editable playbooks (mid-June, precompute live for pilot owners) — the deal book now gets ready-to-review next actions without the rep asking. Deterministic code decides WHAT (playbook: channel frame from
deal_source, gates, priority); an autonomous advisor run decides HOW (drafts in the rep’s voice from the deal brief). Two halves: the precompute (pull) side is LIVE — after a brief composes for an open pilot deal, a background run persists a rich deal glance + next-action draft todeal-nba:<id>so the HubSpot card renders both instantly; the sweep (push) side — new-deal detection → HubSpot review task + Roam DM, plus a stall sweep — is built but gated off (NBA_ENABLED=0, dry-run) pending the HubSpottasks.writescope. Named sales leads edit the natural-language playbooks (frame + forbidden moves, never control flow) on the dashboard’s Playbooks tab — BQ source of truth, KV-rendered prompt block, audit rows. Full page: Next-Best-Action. - Ahrefs June enrichment — three plays, ~3M units (2026-06-29) — Play 1: +5,007 prospect-domain overviews (DR + organic traffic) →
dim_seo; Play 2: top-50 organic keywords for the thin-but-ranking outreach kit, +142K rows →dim_seo_keywords; Play 3: live IE SERPs for each head keyword landing every ranker’s URL + DR + traffic, 23K rows →dim_seo_serp_competitors(new endpointdashboard-prospect-serp-competitors). Head-of-SEO deliverable: the competitor-DR explorer atquick.fcrinsights.ie/seo-competitor-dr. - SayMore engagement programme + monthly refresh (June) — the SayMore hub (population spine + engagement cohorts reconciled to the 1,945 active-SayMore baseline) is rebuilt monthly from the latest Yext Active Services export via the
/saymore-refreshskill and republished on FCR Quick. Full page: SayMore — Engagement & Refresh. - Advisor per-AM standing preferences (2026-06-26) — AMs can tell the advisor “always do X” once: durable per-AM prefs in KV (
am-prefs:{id}, no TTL) with ask-first save/list/forget and a STANDING PREFERENCES prompt addendum; plus a global em-dash ban in drafts. - The 20-Minute Market — opportunity tiers — a measured map of where each FCR web product is the honest recommendation, for every Irish business category in every town.
fcr_operations.v_opportunity_tierserves one row per (category × locality) at the category’s class minutes (destination = 20-minute drive-time packs, service-area trades = 30): a competitive verdict (THIN — no established site in the pack, BizSite genuinely wins / CONTESTED — outrank an incumbent, LocalRank-SitePro / SATURATED), a market-depth prize grade (households per competitor: SHALLOW/MID/DEEP), CSO population + purchasing-power context, and confidence/desert/wide-radius flags. Built on 1,601 calibrated Valhalla/OSM drive-time catchments, a 100%-coverage category bridge (4,479 raw labels → 179 canonical markets), and two independent evidence streams: 483 managed clients’ GBP outcomes (no-site clients earn 0.97× peers in THIN markets vs 0.67× in CONTESTED) and 9,094 real Google searches recovered from the SerpAPI archive (serp_grid_results, 109K rows — 88% of visible top-3 rankers have a website; proximity beats authority). All boundaries signed off 2026-06-11/12. Surfaces: docs page /opportunity-tier, Claude Code skill/opportunity-tier, rebuild toolingscripts/opportunity-tier/(quarterly re-measure runbook), 16-slide deck + full report (Present pack). Next: wiringopportunity-rules.jsso the advisor/HubSpot card recommend the honest rung per deal. - HubSpot card latency cut (2026-06-10) — the deal brief is injected pre-LLM via
_anchorDealId(one model pass, zero tool calls) with parallelised setup and prewarm dedupe. - Autonomous DF audit-followup emails (2026-06-10) —
audit_followupdrafts run single-request with no confirm gates, a disclosure block, and an omit-don’t-guess competitor rule;get_insites_reportgained await_sparam. - Advisor context bridging (2026-06-09) — pasting a
/proposalor/rlink into a new Roam session re-hydrates the saved context cross-user (proposal-meta sidecar + REPORTS KV,lib/artefact-rehydrate.js). - Advisor async reports + BQ guardrail (2026-06-06) — heavy Roam reports hand off to
ADVISOR_QUEUEand post when ready, with a downloadable.mdartifact at/report/{key};run_bigquerydry-runs block >30 GB scans and steer to rollups. - docs.fcrinsights.ie on Starlight (2026-06-04) — the docs site moved to Astro Starlight (
docs-starlight/,nav.mjssingle source of truth, deploy viascripts/deploy-docs-starlight.sh), replacing the legacy generated micro-site.
May 2026
Section titled “May 2026”- Post Studio — live Yext publishing (2026-05-31) — first real Google Business Profile post published through Yext (
accounts/{subscriberId}/posts), with draft grounding off crawled URLs and structured business/product fields. FB/IG/LinkedIn channels and gallery persistence still pending. - Deal Patterns promoted out of spike — the
dashboard-deal-patternshandler, dormant on FCR-only since the engagement back-catalogue load, is now live on both CF accounts with the full surface. New advisor toolextract_deal_patternsin Roam,/deal-patterns/{slug}public HTML report (30-day KV TTL, mirrors/proposal/{slug}), closed-only default (outcome ∈ {won, lost}unlessinclude_open: true), top-level shortcut filters (outcome,service_trade,close_year,county,owner_name), and a topK auto-expand that re-queries Vectorize when the matched cohort has fewer than 8 deals with typed engagement bodies. Telemetry wired viaSKILL_ROUTES. - Hold-spacebar push-to-talk in the HubSpot card voice modal — the
/voice-sttiframe now records while the spacebar is held and sends on release, alongside the existing click-to-toggle mic. Cross-origin focus is hard inside HubSpot’sopenIframeModal, so the page also shows a “click here first to enable space” hint when focus isn’t on the iframe and forces focus back to body on any pointer interaction. Listeners attach on bothwindowanddocument(capture phase). Files:worker/src/handlers/stt.js(VOICE_STT_HTML). - PROSPECT_LISTINGS continuous Pleper refresh — Cloudflare Worker
scheduled()handler (every-minute cron on FCR Media production only) drains stale pids through Pleper one at a time. First scheduled job in the worker codebase — all prior cron jobs live in n8n.- Schema: PROSPECT_LISTINGS now carries
last_updated(bumped on every successful write),pleper_error+pleper_error_at(last failure message + 7-day back-off timestamp). - Staleness signal: pids whose newest GBP_SERVICES row is older than 30 days OR who have never been Pleper-checked. Stale rows are pulled FIFO-by-
last_updated. - Sentinel rows (option-a) — when Pleper successfully returns 0 services for a pid, the cron writes a single GBP_SERVICES row with
service_name=NULL+scrape_status="pleper_zero_sentinel". Subsequentcompetitor-enrichcalls see the sentinel, skip the live Pleper call, and reportenrichment_status: "complete"(knowing “there are zero” is information, not “unknown”). enrichment_statuson competitor-enrich — every pid gets"complete" | "pending_pleper". UI surfaces (grid-map cards, comparison table, hero chips, peer medians, Claude insights, advisor tool instructions) all branch on it so pids that timed out render “Enriching…” instead of unconfirmed zeros.- Files:
worker/src/handlers/prospect-pleper-refresh.js(new),worker/src/handlers/competitor-enrich.js,worker/src/handlers/prospect-enrich.js,worker/src/handlers/grid-map-build.js,worker/src/handlers/discovery-insights.js,worker/src/handlers/ai-advisor.js.[env.fcr.triggers] crons = ["* * * * *"]inworker/wrangler.toml. Design notes: prospect-listings-refresh-plan.md. - Known gap — subscriber_id backfill job: every LRC’s competitor place_ids quietly grow PROSPECT_LISTINGS via competitor-enrich, but new rows write
subscriber_id: NULLand there’s no periodic job linking them to FCR clients viadim_listings_with_subscriber_id/active_clients. Marked as next.
- Schema: PROSPECT_LISTINGS now carries
- AM guides at
/guides/{slug}— permanent FCR-styled HTML pages served by the worker. Content is baked intoworker/src/handlers/guides.js(no KV TTL); add a new guide by appending to theGUIDESmap + redeploy. First guide: /guides/voice-notes — how AMs log HubSpot Calls and save proposals via voice messages in Roam. - Roam advisor closes the proposal loop — three-part shipment that takes AI-generated proposals from “copy-paste into HubSpot” to one-click on-deal posting in the AM’s own voice:
save_proposal_to_dealadvisor tool posts AI-assisted proposals as notes on the resolved HubSpot deal (association type 214). AM line auto-fills fromroam_usersidentity; attribution names the AM (“Posted via Roam by Sharon Orr”).roam_usersBQ table maps Ro.ambody.sender→ person + role + canonical AM name + per-AM template. 45 staff seeded. Working message now greets by first name (“Hi Sharon — analysing…”).am_email_templatestable +save_my_email_template/delete_my_email_templatetools — AMs save their voice once per context (cold_outreach / audit_followup / winback / …) and the advisor picks the right one based on conversational context. Trigger phrase: “save my email template”.
- Session facts persistence —
deal_id/subscriber_id/company_nameharvested from tool results during the loop, persisted to KV alongside chat history, surfaced in the system addendum next turn. Closes the long-running “advisor forgot the deal_id” bug — “post that to the deal” now resolves without re-querying. get_dealslive HubSpot fallback — when BQhubspot_dealsreturns zero for a company filter, retries viadashboard-hubspot-deals-searchwithdealNameContains. Closes the gap for fresh creates / just-won deals not yet in the BQ sync.- GA4/GSC partition-aware date window — analytics cards anchor on the latest month present in the BigQuery shards via
/dashboard-data-freshness, so May 1–7 doesn’t show an empty April column before the 8th-of-month ETL lands. - LRC grid map upgrades — multi-circle “Draw to inspect” demographics, plus per-satellite × keyword avg rank, presence %, and a top-3 competitor mini-table on the rankings sidebar. Both
build_lrc_grid_map.pyand the worker portworker/src/handlers/grid-map-build.js.
Earlier (March–April 2026)
Section titled “Earlier (March–April 2026)”- Discovery (Alpha) — stepped LRC + AI insights + DF compare, baked into a shareable
/r/:idmap. Seeworker/src/handlers/discovery-*.js. - Multi-grid LRC — home + 2 satellites, SAB centre override, shared + geo keywords. Driven by the
/prospectskill. - Area Intelligence Map — census + purchasing power + growth + commercial properties at small-area resolution (cathaldev3.fcrweb.ie). Worker handlers:
area-map-embed,circle-demographics,meta-reach,meta-reach-batch. - Vector search —
fcr-site-portfolio(similar prospects) +fcr-company-knowledge(case studies, SayMore + fcrmedia.ie content) indices. Toolsfind_similar_sites+search_company_knowledgeare live in the Roam advisor. - Roam AI Advisor (v3) — 73 tools including HubSpot deal-by-id (with inline screenshots + attachments), HubSpot note posting, revenue bridge with DEA installment spreading, prospect intel, area demographics, and keyword intelligence.
- Worker deploy gate —
scripts/deploy-worker.shrefuses dirty trees and tags every deploy.
Ask the docsRAG over this site
Ask anything about the FCR Dashboard platform — architecture, BigQuery, the worker routes, billing rules, the LRC stack, scoring… Answers are grounded in this documentation, with source links.
How does the deal-brief refresh work? Which routes are Worker vs n8n? How is account health scored?