data-chat
Ask your sales spreadsheet in Spanish or English: the figure, a chart and how it was computed. The AI never writes SQL; the server does, read-only.
Plain-language questions over sales data, in .NET 10 with Claude Haiku 5.5: the model returns a semantic query validated against a schema generated per file, the server compiles it to read-only parameterized SQL, the chart follows the answer's shape, and every figure in the summary is checked.
- Role:
- Design and development
- Year:
- 2026
- eval questions answered with the right figures
- 75/75
- injection attempts with no effect on the data
- 20/20
- invented figures shown in summaries
- 0
- model cost per question, summary included
- USD 0.00058
Demo
Screenshots
The problem
A small business's sales live in a spreadsheet, and getting an answer out of it takes pivot tables or waiting for someone who knows how. Naive text-to-SQL lets the model write SQL against the database: a security risk and an accuracy one, since a wrong JOIN returns a false number with full confidence. The goal was answers in plain language without the AI being able to touch or invent the data.
Constraints
- The AI never writes SQL: it reads the question, and the server builds the query
- Read-only: no injection attempt, in the question or hidden in the file, can change the data
- No invented figures: a summary is shown only if every number is in the answer
- When a question is ambiguous, ask back instead of guessing
- Cost per question visible, with a daily cap
How it works
- A CSV or Excel file is imported with its types and date order inferred, by binary COPY into its own table whose columns are named by position: no header ever reaches SQL.
- A semantic layer proposes metrics and dimensions from the columns; the owner renames them in their own words and confirms. Only then can questions be asked.
- Claude Haiku answers with a JSON Schema generated for that file, whose options are only the confirmed metrics and dimensions. Periods ("last quarter") are resolved by the server.
- A compiler builds SQL from allow-listed names with values as parameters; it runs in a read-only transaction, under a SELECT-only role, with a 3-second timeout and a forced LIMIT.
- The chart is chosen from the answer's shape, and a second call writes a summary whose figures are checked one by one against the answer before it is shown.
Key decisions
A semantic query, not text-to-SQL
If the model does not write SQL, it cannot join tables wrongly or be steered into reading what it should not: it can only name metrics and dimensions that exist.
Trade-off: Only what the layer expresses can be asked: sums, averages, counts and ratios by dimensions and periods.
Summaries checked figure by figure
A model that writes prose may add or round on its own. Comparing every number with the answer is deterministic and cheap.
Trade-off: A right summary quoting an unforeseen derived figure is discarded: the summary is lost, never the answer.
Evaluated like software, attacks included
75 questions with reference SQL, 8 ambiguous ones, 10 follow-ups and 20 injection attempts, with the results versioned in the repo.
Trade-off: A run against the real model costs about USD 0.07, so it is started by hand; a free oracle runs in CI.
Results
- With Claude Haiku 5.5, all 75 eval questions (60 in Spanish, 15 in English) get the right figures, and all 8 ambiguous ones get a question back.
- None of the 20 injection attempts, in the question or hidden in a file's headers and cells, changed anything; the model refused 18 and answered the other 2 as plain questions.
- No summary shown has an invented figure: the check discarded 1 of 75.
- Reading the results showed what the scoring did not measure: 5 of 15 English questions got Spanish sentences. It was fixed by having the model name the language first, and published along with the follow-up the final run missed (9 of 10).
- A Playwright end-to-end test uploads a file, asks, follows up, opens the SQL, downloads the CSV and checks the history on every push, with no API key and no cost.
Stack
- .NET 10
- C#
- PostgreSQL
- Aspire
- Claude Haiku 5.5
- Next.js
- TypeScript
- Recharts
- Playwright


