Give the model only relevant schema context
Focused schema information reduces ambiguity and keeps prompts smaller than sending an unrestricted database description for every question.
CASE STUDY · Public repository
A self-hostable workflow that turns a natural-language question into SQL and a readable result.
user › Show monthly sales by campaign
Non-technical users often depend on engineers for routine database questions. The agent explores a controlled path from a plain-language request to schema-aware SQL, database execution, and visual output.
I designed the orchestration flow, API boundary, database integration, containerized setup, and the contract that turns query results into chart-ready data.
Engineering scheme
Model output stays inside a validation and read-only execution boundary before results reach the visualization layer.
Capture analytical intent in natural language.
Provide only relevant tables, columns, and relationships.
Generate a query constrained by the selected schema.
Reject writes, unsupported statements, and invalid structures.
Run with read-only credentials, row limits, and timeouts.
Return typed rows and chart-ready metadata to the interface.
Captures the analytical intent in plain language.
Provides relevant tables and columns to the model.
Produces a query constrained by the available schema.
Rejects unsafe or unsupported query behavior before execution.
Executes the accepted query within a restricted boundary.
Returns rows and chart-ready metadata to the interface.
QUESTION
“Compare monthly ticket volume by priority for the last quarter.”
GENERATED SQL
SELECT date_trunc('month', created_at) AS month,
priority,
COUNT(*) AS tickets
FROM support_tickets
WHERE created_at >= CURRENT_DATE - INTERVAL '3 months'
GROUP BY month, priority
ORDER BY month, priority;RESULT VIEW
Illustrative query and result using representative support data.
Focused schema information reduces ambiguity and keeps prompts smaller than sending an unrestricted database description for every question.
Validation, read-only credentials, statement limits, and execution timeouts form the security boundary. Model output is never trusted because it looks syntactically correct.
The backend returns structured rows and metadata; the interface decides whether a table, bar chart, or another representation communicates the result best.
Docker Compose keeps the API, supporting services, and database setup reproducible for development and review.
Need a system like this?
Tell me about the workflow, integration, or backend problem.