- contact@insightaiviz.com
Everything runs on the shared VerticalServe platform: FastAPI on Postgres for metadata, DuckDB over Parquet for data, a React console, and the identity and connection registry every Insight product shares.
One engine, three runtimes, one query contract. The React app never talks to DuckDB directly: it sends a logical query and gets rows back through the gateway, which compiles it against the semantic model with the caller’s policies applied.
| Component | What it holds |
|---|---|
Postgres (schema viz) | workspaces, datasources, extracts, semantic models, dashboards, conversations, policies, query log, jobs — plus the platform’s identity and connection tables |
| Object store | the extracts: partitioned Parquet + manifest.json per version, and uploads awaiting import |
| DuckDB | in-process in the API; reads Parquet on file://, s3://, gs://, az:// through httpfs; result cache keyed on the immutable extract |
| Worker | in-process by default (VIZ_WORKER=1); a Postgres queue with SKIP LOCKED, so a second container is safe |
| Model provider | the platform’s chat model: Bedrock, Azure OpenAI, Vertex, OCI or an OpenAI-compatible endpoint |
The API and the console run from two directories; the platform packages come from the private insight-platform repository.
Docker. docker compose up in the product directory builds both images. The API image takes INSIGHT_PLATFORM=aws|azure|gcp|oci to pick the cloud SDKs, and a read-only git_token build secret for the platform packages.
| Variable | Meaning |
|---|---|
| INSIGHT_DATABASE_URL / _SECRET / _SCHEMA | the platform Postgres; the password is a secret ref (aws-sm://…, azure-kv://…, gcp-sm://…), never a value |
| VIZ_STORE_EXTRACTS | a store ref for extracts: s3://bucket/prefix, gs://…, az://…, file:///… |
| VIZ_STORE_UPLOADS | where dropped files and Tableau workbooks wait for the worker |
| VIZ_EXTRACT_TTL_DAYS | how long a client may use an extract before it must re-authenticate (default 7) |
| VIZ_LOCAL_EXTRACT_MAX_MB | extracts at or under this size may be served to a browser / desktop runtime (default 400) |
| VIZ_QUERY_MAX_ROWS, VIZ_DUCKDB_THREADS, VIZ_DUCKDB_MEMORY | engine limits per query |
| VIZ_AI_ENABLED, INSIGHT_LLM_PROVIDER, INSIGHT_CHAT_MODEL | the assistant, and which model answers |
| INSIGHT_JWT_KEY_REF | the token-signing key shared across Insight products |
A datasource is a named source inside a workspace: a platform connection plus the tables or queries to pull, a refresh schedule, and whether its extract may be served to a local runtime. A refresh writes a new extract under a new prefix; when it is ready the datasource’s pointer moves, so readers never see a half-written extract and the previous version stays for rollback until it expires.
Postgres and MySQL are attached natively by DuckDB and copied straight to Parquet; other SQL dialects stream through Arrow batches. CSV and Parquet drops become an extract of kind upload. Partition with order_date:month or a plain column.
The model is the contract between the data and everything that asks it. It names dimensions, metrics and joins with business labels, descriptions and synonyms; the compiler and the AI read nothing else. A model is derived on a datasource’s first extract and refined from there — by hand in the JSON editor, or by the AI (“Enrich”) for labels, descriptions and synonyms.
What the console, the dashboard document and the AI produce. None of them write SQL.
Operators: = != > >= < <= in not_in between contains starts_with is_null not_null. Time grains: year quarter month week day hour. Every name must be a dimension or metric of the model — nothing else is accepted, which is how the catalogue is the whole attack surface. Values are bound as parameters, never spliced.
A dashboard is a document: {layout, widgets: [{id, title, x, y, w, h, query, chart}], filters, parameters}. Chart specs are declarative — {type: bar|line|area|scatter|pie|table|kpi, x, y, series} — and rendered by the console with Vega-Lite. Publishing snapshots the definition as a version with a note; any version can be restored into the draft. POST /api/dashboards/{id}/run executes every widget with the page’s filters in one call.
The assistant is given the catalogue (names, labels, synonyms — never SQL) and two tools: run_query and draw_chart. It iterates — query, look, refine — then answers in words. The message carries the logical query, the SQL, the chart, a result sample and the tool trace, so “how was this computed” is a click. Answers can be kept as saved queries or added to a dashboard as widgets.
Drop a .twbx, .tdsx, .twb, .tds or .hyper. Every table in the Hyper extract becomes Parquet; the workbook XML becomes the semantic model (captions, roles, aggregations, hierarchies, calculated fields translated to SQL) and the dashboards (sheets → widgets, zones → grid). The fidelity report lists every sheet and calculation as converted, translated-verify or manual — LOD expressions and table calculations are always manual. A workbook with a live connection and no extract is reported with the connection details so the datasource can be created against your own connection.
{dimension, op, values} for a principal (an email, role:<name> or *), added to WHERE by the compiler.Every response is the envelope {status: SUCCESS|FAIL, data, error_message}. A bearer token from /api/auth/login or an API key authenticates. Interactive docs at /docs on the API host.
| Route | What |
|---|---|
| /api/workspaces | workspaces and members |
| /api/datasources | datasources, /refresh, extracts (/activate, /tables/{t}/preview, /presign), policies, /upload |
| /api/models | semantic models, /publish, /enrich, /suggest, /values/{dim}, saved queries |
| /api/query | the gateway; /compile for the SQL without running it; /log |
| /api/dashboards | documents, /publish, /versions, /run, /clone |
| /api/chat | conversations, /ask, /messages/{id}/save |
| /api/imports | /tableau, jobs and their SSE events |
| /api/connections, /api/user, /api/audit | the platform’s connection registry, identity admin and audit trail |