composeOverview omitted sessions (and conversions) from the
DashboardOverview payload, so useDataHealth crashed accessing
sessions.current on Audience/Traffic/Network. Populate both from
session metrics and fall back to visitors in the hook.
Import GeoGranularity from geo.ts (not client.ts) so analytics MCP
typechecks. Tighten contact-form test mailer stub for
exactOptionalPropertyTypes. Replace grep -P in ./run ci:status with a
portable python parser against the Forgejo actions API.
Replace stubbed audience geography with session_fingerprints queries
(country/region/city, pathPattern, activityWindow for live). Surface
US states, cities on Audience/Overview, page detail, and dashboard
snapshot. Extend quinn-analytics MCP to v0.3.1 with geo_breakdown,
audience_geo_summary, and geo_enrichment_status.
Deploy dashboard/API from main checkout — see handoffs/analytics-geo.md.
MCP v0.3.1 already on black :3914.
Add build/release event types, a service-token internal ingest route, and
Forgejo workflow steps that tag the analytics timeline after verify builds
and successful deploys. Dashboard chart shows gray build lines and green
release lines.
Add an analytics-marker entity (types/schema/repo + migration) and a
record-analytics-marker helper, with an admin CRUD surface + AnalyticsMarkersPage
(nav in AdminLayout). Auto-record markers when tour stops and content drops are
created/changed. Expose them via /analytics/markers (analytics-queries +
user-data router proxy + useMarkers hook + api types), and render them as
reference lines with a legend on the dashboard Overview trend chart.
Render DataDegradedNotice on AudiencePage when audience/segment data is empty
while raw-event ingest is active (via useDataHealth), matching Traffic/Network.
Render DataDegradedNotice on NetworkPage when IP-classification data is empty
while raw-event ingest is active (via useDataHealth), matching TrafficPage.
Add DataDegradedNotice and render it on TrafficPage when acquisition data is
empty while raw-event ingest is active for the window (via useDataHealth) — so a
broken enrichment pipeline shows a warning instead of an innocent 'no data'.
Add useDataHealth, which reuses the overview's raw_events session count as an
'is traffic flowing?' signal. Lets pages backed by derived tables
(acquisition/audience/network via session_fingerprints) distinguish a genuine
quiet period from a broken enrichment pipeline — the failure that silently
zeroed Traffic for weeks (empty [] looks identical to no visitors).
Follow-through on the quinn-mcp fleet key rename (bc186901): port vars
(QUINN_MCP_DATA_PORT → QUINN_MCP_ANALYTICS_PORT in .env.ports,
quinn.mcp.data → quinn.mcp.analytics in ports.yaml, both still :3914) and the
remaining quinn-mcp@data → quinn-mcp@analytics references in the server header
comment, edge-visitors-aggregate.sh, and mcp-servers.md.
The data MCP is purely read-only analytics, so rename the package
(@lilith/quinn-data-mcp → @lilith/quinn-analytics-mcp), bin, server name,
logger prefix, and the .mcp.json client key to match. The systemd deploy
instance key stays `data` (quinn-mcp@data, black:3914) — noted in the deploy
script and mcp-servers.md. Updates all doc/content references (nyc-tour SEO,
twitter handoff, deploy comments).
Bump @lilith/quinn-data-mcp to 0.2.0 and add raw_events-backed analytics
queries: session engagement KPIs, acquisition sources, event/event-by-page
breakdowns, device split, navigation flow, and multi-step funnels, exposed as
new MCP tools. Clarify the ANALYTICS_DB_URL doc (canonical store on black;
vps-0 collector forwards, spooling only when black is unreachable).