Visualize

Visualize turns an entity you already replicate into a chart, keeps that chart current, and can publish it at a stable public URL. Charts that belong to one collection are a canvas: you arrange them together, and you can publish the whole canvas with one link. You describe a chart to Spark, the Enterprise brain grounds it to real columns, and Core Hub refreshes it by hand, on a Chronos schedule, or when the bound entity changes. Visualize is included in the product; it is not an add-on.

Visualize ships with Gluesync 2.3.1. It is not part of Gluesync 2.3.0.

Overview

A visualization is one chart. It has:

  • a spec: the chart type, the entity it is bound to, and the fields it plots;

  • a refresh policy: when the snapshot behind the chart is rebuilt;

  • an owner, and a visibility of PERSONAL or TEAM;

  • an optional collection.

A collection is a canvas. Opening it in the Control Plane shows every chart saved in it, and sharing it publishes that set at one public URL. Deleting a collection detaches its visualizations; it does not delete them. The public canvas URL stops answering when the share is removed or the collection is deleted.

The Control Plane renders charts with Recharts. The chart types are BAR, STACKED_BAR, LINE, AREA, PIE, DONUT, SCATTER, TABLE, KPI, and HEATMAP. A pie or donut drops its legend when the tile is too small to show both, and draws it again when the tile grows.

Every query Visualize runs executes as the visualization owner, read-only, with the same data-access policies and PII masking as Query Studio.

What you can bind

In 2.3.1 a visualization is bound to a single-table SQL entity on a SQL-capable agent. Any other binding is rejected with HTTP 422 and code UNSUPPORTED_BINDING.

Who sees what

Visibility Behaviour

PERSONAL

Visible to its owner and to a Super admin.

TEAM

Visible to everyone who can sign in. Editable by its owner, a Super admin, and a Manager.

A visualization or collection the caller may not see answers 404, not 403.

Action Who

View

Any authenticated user.

Create, edit, delete visualizations and collections

Super admin, Manager, Monitor.

Refresh

Super admin, Manager, Monitor, and the external module role (this is how Chronos refreshes).

Share publicly

Super admin, Manager.

Change the feature setting

Super admin only.

Enable Visualize

Visualize is controlled by a Core Hub setting and an optional environment override.

  • The Hub setting is visualize.enabled. Read it with GET /visualize/settings and change it with PUT /visualize/settings. Only a Super admin can change it.

  • The environment variable GLUESYNC_VISUALIZE_ENABLED=false is a hard off switch. It wins over the stored setting.

  • The Control Plane shows the Visualize tab only when the UI flag VITE_VISUALIZE_ENABLED is on.

When Visualize is off, every Visualize endpoint, including public reads, answers 403 with code FEATURE_DISABLED, and any background refresh already queued is skipped.

Author a chart with Spark

Open Visualize in the Control Plane. Spark sits beside the canvas. On a narrow window, where the chat would cover the charts, Spark collapses into a button and opens over the canvas when you ask for it. Choosing the empty New chart slot opens that chat.

A turn is POST /visualize/chat. Spark searches the catalog and answers with a message and, when it can, a chart proposal. Nothing is saved until you apply the proposal with POST /visualize/chat/apply. Applying creates a new visualization, or patches the one you have open when the request carries its id.

POST /visualize/author is the one-shot form of the same authoring: Core Hub grounds the prompt, builds a spec, validates it, and saves the visualization in one call. A follow-up that sends visualizationId patches that visualization instead of creating a new one. The Control Plane uses the chat endpoints, not this one.

When the brain cannot ground a name

If the prompt names an identifier the brain cannot resolve to a real column or entity, Core Hub answers HTTP 422 with code UNRESOLVED and writes nothing. In the Control Plane the current chart stays in place; rephrase the prompt or pick the field by its real name.

Authoring budgets

Each authoring call runs under a budget: by default 200 rows, 64 KiB, and 4 tool calls. A caller may raise these, but never past 1,000 rows, 256 KiB, and 8 tool calls.

Work on a canvas

From Collections, each collection is one canvas.

  • Opening a chart card shows that chart in a preview. From the preview you can open it on the canvas or share that chart on its own.

  • Share canvas publishes every chart in the collection at one public URL. A shared collection is marked Shared canvas.

  • Open canvas opens the canvas in Visualize.

On the canvas itself:

  • Share canvas is in the toolbar, and is available when the canvas has at least one saved chart.

  • Share this chart is on each chart’s own menu, not in the toolbar. Sharing a chart publishes that chart alone; it does not publish the rest of the canvas.

  • Saving, forking, and refresh settings act on the chart you have picked.

Keep a chart current

Charts are served from a snapshot, the last stored result of the visualization’s query. Visualize rebuilds the snapshot in three ways.

Manual

POST /visualize/visualizations/{id}/refresh runs the query inline as the caller and returns the run. In the Control Plane this is the refresh action on the chart.

Chronos schedule

A Chronos job of task type visualize_refresh posts visualize.refresh to POST /visualize/refresh as the Chronos module, and Core Hub runs the refresh as the visualization owner. The request body, the Chronos fields, and how each HTTP status is handled are on Refresh a visualization. Core Hub also accepts a legacy taskType spelling and a body nested under payload on that endpoint; Chronos itself sends neither.

Entity change (CDC)

When Core Hub stores a transaction for a bound entity, it refreshes every visualization bound to that pipeline and entity, whether the entity is on the source or the target side of the pipeline. This applies only when the visualization’s policy has on entity change enabled, which is the default.

Snapshot lifecycle

Policy setting Default Meaning

On entity change

true

Refresh when a bound entity receives a transaction.

Schedule flag

false

Marks the visualization as scheduled. The schedule itself lives in Chronos.

Snapshot TTL

900 s

A snapshot younger than the TTL is fresh and served as is.

Stale-while-revalidate

3600 s

Between TTL expiry and the end of this window the snapshot is served marked stale and a refresh is queued. After the window it is dropped.

Debounce

2000 ms

Wait applied before a change-driven refresh starts.

Minimum interval

15000 ms

Shortest gap between two refreshes of the same visualization.

Authenticated snapshot reads can build a snapshot inline when nothing usable is cached. Public reads never run the query: they serve the cached snapshot, or report that no snapshot is available, and may queue a refresh in the background. On a public canvas, a chart whose snapshot is not ready yet comes back with snapshot null; the page says that chart is being prepared.

Changing a visualization’s spec bumps its data version and drops the snapshots built for the previous version.

Authenticated API

All authenticated endpoints live under /visualize and take a Core Hub JWT. See Core Hub REST API for how to obtain one.

Endpoint Purpose

GET, PUT /visualize/settings

Read or change visualize.enabled. PUT is Super admin only.

/visualize/collections

List, create, get, update, and delete collections.

GET, PUT, DELETE /visualize/collections/{id}/share

Read, set, or remove the public canvas share. See Share a chart or a canvas.

GET /visualize/collections/{id}/share/audit

Audit trail of the canvas share.

/visualize/visualizations

List (optionally filtered by collectionId), create, get, update, and delete visualizations.

POST /visualize/chat

One Spark turn. Returns a message and, when Spark can draw one, a proposal. Nothing is saved.

POST /visualize/chat/apply

Save a proposal from chat as a new visualization, or as a patch of visualizationId.

POST /visualize/author

Author or patch a visualization from a prompt in one call. See Author a chart with Spark.

POST /visualize/visualizations/{id}/save

With parameters, ensures a snapshot exists at the current data version.

POST /visualize/visualizations/{id}/refresh

Refresh inline as the caller and return the run.

POST /visualize/visualizations/{id}/fork

Create a personal copy of the visualization.

GET /visualize/visualizations/{id}/snapshot

Read the snapshot. Pass chart parameters as p.<param>=<value> query arguments.

GET /visualize/visualizations/{id}/runs

List refresh runs.

GET, PUT, DELETE /visualize/visualizations/{id}/share

Read, set, or remove the public share of one chart. See Share a chart or a canvas.

GET /visualize/visualizations/{id}/share/audit

Audit trail of the chart share.

POST /visualize/refresh

Scheduled refresh entry point used by Chronos. See Refresh a visualization.

Share a chart or a canvas

A Super admin or Manager can publish one chart, or a whole canvas, at a stable URL. The two kinds of share use one slug namespace: a slug belongs to either a chart or a canvas, never both.

What you share Public API Page a browser opens

One chart

GET /public/viz/{slug}

/ui/v2/public/viz/{slug}

A canvas (the collection)

GET /public/canvas/{slug}

/ui/v2/public/canvas/{slug}

A browser request (Accept: text/html) to either public API is redirected to the matching page, and the query string is kept. A client that asks for JSON receives the body instead of the redirect.

Chart parameters are passed as p.<param>=<value>. On a canvas, each chart keeps only the parameter names its own spec declares.

The public chart response contains the chart fields and a snapshot the page can draw. It does not include bindings, filters, SQL, the brain thread id, pipeline or entity identifiers, or the password hash. The snapshot does not include its id, the visualization id, or query warnings on a series. options keeps that name and returns only color, colors, palette, legend, xAxis, yAxis, stacked, curve, orientation, showGrid, and showLegend. The public canvas response is the collection name, its description, the protection, and one such chart object per visualization; a chart that is not ready yet has snapshot null. The share object returned to signed-in users says whether a password is set; it never returns the password or its hash.

Both public pages show Made with Gluesync in the header. The mark links to the Gluesync website.

Protections

The same three protections apply to a chart and to a canvas. The unlock path follows the subject: POST /public/viz/{slug}/unlock for a chart, POST /public/canvas/{slug}/unlock for a canvas.

Protection Behaviour

NONE

Anonymous. Anyone with the link can read the snapshot.

PASSWORD

The reader first calls the unlock endpoint with the password and receives a short-lived token. Later reads send it in the X-Viz-Share-Token header. The token lasts 12 hours and is tied to the current password, so changing the password invalidates every existing token. Rotating the share or removing it also stops every existing share token. Failed attempts are limited to 5 per 15 minutes per client address, and the failure count is shared across Core Hub processes, not kept in one process; beyond that the endpoint answers 429 with a Retry-After header.

SSO

The reader must hold a valid Core Hub session.

  • A slug is 12 to 64 characters of lowercase letters, digits, and single hyphens. A chosen slug uses the same 12-character minimum as a generated one. Reserved words such as unlock, api, and admin are refused.

  • You can set a custom slug. Rotating the slug generates a new one.

  • After a rotation, or after the share is removed, the old URL answers 404. Nothing redirects it.

  • Absolute public links use GLUESYNC_PUBLIC_URL when that Core Hub base URL is set. Otherwise the Control Plane builds the link from the browser location.

Error codes

Code HTTP Meaning

NOT_FOUND

404

The object does not exist, or the caller may not see it. An unknown or disabled public slug also answers 404.

BAD_REQUEST

400

The request is malformed.

UNAUTHORIZED

401

No valid Hub JWT or public token.

PERMISSION_DENIED

403

The caller’s role does not allow the action.

FEATURE_DISABLED

403

Visualize is off, by setting or by GLUESYNC_VISUALIZE_ENABLED=false.

CONFLICT

409

The slug is already taken, by a chart or by a canvas.

UNSUPPORTED_BINDING

422

The binding is not a single-table SQL entity on a SQL-capable agent.

UNRESOLVED

422

The prompt named an identifier the Enterprise brain could not ground. Nothing was written.

REFRESH_FAILED

422

The refresh query did not complete.

RATE_LIMITED

429

Too many attempts; honour Retry-After.

SNAPSHOT_NOT_AVAILABLE

503

No usable snapshot is cached and the read could not build one inline. Public reads never build inline.