# Analytics agent

Haris Muhibić built an internal analytics app where staff ask questions about company data in plain language and get dashboards and scheduled reports. The text-to-SQL behind it is designed to hold up in production.

- Role: Architect, near-sole author
- When: 2026
- Stack: Redshift, Zero-ETL, Node.js, React, ECharts, Bedrock, Gemini, Puppeteer, CDK

## The problem

Every metric question went to an engineer, and dashboards went stale. The company needed self-serve answers that stay correct when filters change.

## How it evolved

This started as a dbt warehouse on Redshift. Once the production database replicated into Redshift through Zero-ETL, I turned it into a product: a chat agent that queries the warehouse, builds dashboard widgets and schedules PDF, Excel or CSV reports by email.

## What makes the SQL trustworthy

- **Filter placeholders.** Saved widgets use placeholders for customer and date filters, so they rerun correctly when someone changes the dashboard filters.
- **Validate before save.** Every widget's SQL runs against the warehouse before it is saved.
- **Linting.** Widgets with hardcoded dates or IDs are rejected.
- **Correct time ranges.** "Last week" is computed in the customer's timezone, with explicit start and end times.
- **Real cancellation.** The Stop button cancels the running database query, not just the chat.
- **Numbers stay untouched.** Replies are cleaned up in code, which never changes a number.
- **Fallbacks.** Models fall back across providers when one is throttled, and token cost is tracked per user.

## A lesson worth sharing

In a Zero-ETL database you can't create views, and late-binding views break across databases. Derived data has to be materialised as tables that the agent refreshes.

---
Haris Muhibić · chern0.dev · haris@chern0.dev · Book a call: https://calendar.app.google/qiN9zJrS5gSqQPky8
