Dashboards, SCADA & Data Sources
Three related resources build the cloud UI layer:
- Dashboards (
/cgg/pages) — page-based applications made of widgets - SCADA screens (
/cgg/scada) — canvas-based process diagrams with tag bindings - Data sources (
/cgg/datasources) — reusable connections that queries run against
All routes require authentication, either an API key or a signed-in session.
Access rules
| Action | Personal item | Workspace item |
|---|---|---|
| Read | creator only | any workspace member, including tenant-only members |
| Write | creator only | owner, admins and members — not operators, not tenant-only members |
Failed reads return 400 (dashboards) or 403/404 (SCADA); failed writes
return 403 {"message":"No access to this workspace dashboard"} or 403 with an
empty body for SCADA.
Dashboards
Base path: /cgg/pages.
| Method | Path | Purpose |
|---|---|---|
| GET | /cgg/pages | List dashboards |
| GET | /cgg/pages/:id | Get one dashboard |
| POST | /cgg/pages | Create a dashboard |
| PUT | /cgg/pages/:id | Update a dashboard |
| DELETE | /cgg/pages/:id | Delete a dashboard |
| POST | /cgg/pages/import | Import a dashboard export file |
| GET | /cgg/pages/homepage/:workspaceId | Resolve a workspace's home page |
| POST | /cgg/pages/:id/setHomePage | Make this dashboard the workspace home page |
| POST | /cgg/pages/:id/unsetHomePage | Clear the home page flag |
| POST | /cgg/pages/:id/query/:queryId | Execute a dashboard query |
The dashboard object
{
"_id": "664c1a2b8c9d0e0011229901",
"name": "Boiler overview",
"description": "",
"workspace": "664a1f2b8c9d0e0011223344",
"isHomePage": true,
"pages": [
{
"id": "page-1",
"name": "Overview",
"components": [ /* widgets */ ],
"queries": [ /* per-page queries */ ]
}
],
"components": [ /* app-level widgets */ ],
"queries": [],
"scripts": [ /* app-level queries/scripts */ ],
"variables": [],
"createdAt": "…",
"updatedAt": "…"
}
A widget carries name, type, position (x, y), size (width,
height), properties, events and styles. A query carries id, name,
source (a data source _id), type, parameters and events.
List dashboards
GET /cgg/pages
| Query parameter | Description |
|---|---|
start | Offset, default 0 |
count | Page size, default 10 |
search | Case-insensitive match on name |
workspace | Return that workspace's dashboards instead of personal ones |
Returns the standard { count, data } envelope.
Create, update, delete
POST /cgg/pages
PUT /cgg/pages/:id
DELETE /cgg/pages/:id
Create body:
{
"name": "Boiler overview",
"components": [],
"workspace": "664a1f2b8c9d0e0011223344"
}
Returns the created dashboard. PUT applies only the properties present in the
body — name, pages, components and scripts — and returns 200 with an
empty body. Other fields (for example variables) must be set through import.
Invalid ids return 400 before any lookup, since :id must be a valid ObjectId.
Import a dashboard
POST /cgg/pages/import
{
"bundle": { "_type": "dashboard", "data": { "name": "…", "pages": [], "components": [] } },
"name": "Boiler overview (copy)",
"workspace": "664a1f2b8c9d0e0011223344"
}
The bundle must have _type: "dashboard" and a data object, otherwise
400 {"message":"Invalid dashboard export file"}. pages, components,
queries, scripts and variables are taken from data; name falls back to
the bundle name and then to "Imported Dashboard". The imported dashboard is
never marked as home page. Returns the created dashboard.
Home page
GET /cgg/pages/homepage/:workspaceId
POST /cgg/pages/:id/setHomePage
POST /cgg/pages/:id/unsetHomePage
Each workspace may designate one dashboard or one SCADA screen as its home
page. GET …/homepage/:workspaceId returns whichever is set, with a
discriminator:
{ "_id": "664c1a2b…", "name": "Boiler overview", "isHomePage": true, "homePageType": "dashboard" }
homePageType is dashboard or scada; 404 means no home page is set.
setHomePage clears the flag from every dashboard and SCADA screen in the
workspace before setting it, so the two never conflict. Personal dashboards
cannot be home pages
(400 {"message":"Only workspace dashboards can be set as home page"}).
Execute a query
POST /cgg/pages/:id/query/:queryId
{
"parameters": { "limit": 100 },
"workspace": "664a1f2b8c9d0e0011223344",
"tenant": "664a20338c9d0e0011223399"
}
:queryId is matched against the dashboard's app-level scripts and then each
page's scripts; unknown ids return 404. The query runs on the server with:
- the referenced data source's
properties, when the query has asource - or, for built-in types, an implicit context:
DevicesandDeviceEventsreceive{ user, workspace, tenant }, andrestapireceives no properties parametersfrom the request body, falling back to the query's storedparameters
Requires only read access, so a viewer can refresh data without edit rights. The
data source result is returned as-is; a failing query returns 500. A query with
neither a data source nor a supported built-in type returns 400.
SCADA screens
Base path: /cgg/scada. Behaviour mirrors dashboards, with a canvas model
instead of pages.
| Method | Path | Purpose |
|---|---|---|
| GET | /cgg/scada | List screens |
| GET | /cgg/scada/:id | Get one screen |
| POST | /cgg/scada | Create a screen |
| PUT | /cgg/scada/:id | Update a screen |
| DELETE | /cgg/scada/:id | Delete a screen |
| POST | /cgg/scada/import | Import a SCADA export file |
| POST | /cgg/scada/:id/setHomePage | Make this screen the workspace home page |
| POST | /cgg/scada/:id/unsetHomePage | Clear the home page flag |
| POST | /cgg/scada/:id/query/:queryId | Execute a screen query |
| GET | /cgg/scada/binding/devices | List devices and variables available for tag binding |
The screen object
{
"_id": "664c2b3c8c9d0e0011229902",
"name": "Plant overview",
"description": "",
"workspace": "664a1f2b8c9d0e0011223344",
"isHomePage": false,
"screens": [
{
"id": "screen-1",
"name": "Boiler house",
"canvasWidth": 1400,
"canvasHeight": 900,
"elements": [
{
"id": "el-1",
"type": "tank",
"label": "Tank A",
"position": { "x": 120, "y": 80 },
"size": { "width": 160, "height": 220 },
"tagBindings": { "level": "665f3c1e…:tankLevel" },
"alarmLimits": { "high": 90 },
"interactions": { },
"properties": { },
"styles": { }
}
],
"connections": [
{ "id": "c-1", "fromElementId": "el-1", "toElementId": "el-2", "animated": true }
],
"scripts": []
}
],
"scripts": [],
"canEdit": true
}
GET /cgg/scada/:id adds canEdit, telling the client whether to render the
editor or a read-only view.
List, create, update, delete
GET /cgg/scada
POST /cgg/scada
PUT /cgg/scada/:id
DELETE /cgg/scada/:id
List parameters are start, count, search and workspace, as for
dashboards. Create body:
{
"name": "Plant overview",
"description": "",
"screens": [],
"workspace": "664a1f2b8c9d0e0011223344"
}
PUT applies name, description, screens and scripts when present, and
returns the updated screen. Missing screens return 404.
Import
POST /cgg/scada/import
Identical to dashboard import, except the bundle must have _type: "scada" and
its data supplies screens and scripts.
Queries and tag binding
POST /cgg/scada/:id/query/:queryId
GET /cgg/scada/binding/devices
Query execution matches the dashboard endpoint, searching top-level scripts and
then each screen's scripts.
GET /cgg/scada/binding/devices is a helper for the screen editor: it lists the
devices the caller can bind to, with the union of their state and config
variable names.
| Query parameter | Description |
|---|---|
workspace | List that workspace's devices instead of personal ones |
tag | Only devices carrying this tag |
[
{
"_id": "665f3c1e9d1b4a0012a7c8d1",
"deviceId": "665f3c1e9d1b4a0012a7c8d1",
"name": "Boiler room controller",
"tags": ["boiler"],
"variables": ["mode", "setpoint", "tankLevel"]
}
]
Data sources
Base path: /cgg/datasources. Data sources are personal only — they are
always scoped to the creating user, with no workspace sharing.
| Method | Path | Purpose |
|---|---|---|
| GET | /cgg/datasources | List data sources |
| GET | /cgg/datasources/:id | Get one data source |
| POST | /cgg/datasources | Create a data source |
| PUT | /cgg/datasources/:id | Update a data source |
| DELETE | /cgg/datasources/:id | Delete a data source |
{
"_id": "664c3d4e8c9d0e0011229903",
"name": "Plant SQL",
"type": "MySQL",
"properties": {
"host": "db.acme.example",
"port": 3306,
"database": "plant",
"user": "reader",
"password": "…"
},
"createdAt": "…",
"updatedAt": "…"
}
Supported type values are MySQL, mongodb, restapi, Devices and
DeviceEvents. properties is free-form and interpreted by the corresponding
data source implementation — connection details for databases, base URL and
headers for restapi. The Devices and DeviceEvents types read the platform's
own data and are usually used without an explicit data source, in which case the
query receives the caller's user, workspace and tenant automatically.
List parameters are start, count and search; the response uses the
{ count, data } envelope.
POST takes name, type and properties and returns the created document.
PUT updates properties always and name when present, returning 200 with
an empty body — note that type cannot be changed after creation. Referencing a
data source you do not own returns 400.
properties may contain database passwords and API tokens. They are stored as
provided and returned by GET, so treat these endpoints as sensitive and keep
data sources out of exported bundles.