Admin Dashboard
Tech stack: React 19 + Vite + TanStack Router + Zustand + React Query + AWS SDK + Tailwind CSS
Terminology: “Nodes” and “Node ID” throughout (matching ESP RainMaker Neo specs). “Thing” only in internal code/AWS SDK calls.
Route Structure
The route tree is declared once; the router, the sidebar and the breadcrumbs are all projected from that one declaration.
/ — redirects to /login
/login, /forgot-password, /set-password, /logout
/error, /oauth-preview
/static/terms-of-use, /static/privacy-policy — public, render without runtime config
/home — redirects to /home/node-management/nodes
/home/node-management
/nodes — Node list
/$thingName — Node details; redirects to /overview
/overview /tags /attributes /ota-jobs
/node-groups — Node Group list
/new — Create group
/$groupName — redirects to /nodes
/nodes /ota-jobs
/register — Registration jobs
/new — Register nodes (single + bulk)
/generate — Generate nodes
/home/ota — redirects to /home/ota/images
/images — OTA images
/new — Upload OTA image
/jobs — OTA jobs
/new — Create OTA job
/$jobId — redirects to /overview
/overview /nodes
/home/settings — redirects to /voice-assistants
/voice-assistants — redirects to /alexa
/alexa /gva
/push-notifications
/post-deployment
/home/account-settings — /profile, /preferences, /password
Nodes Page
Default columns: Node ID, Status (with “since” timestamp), Groups (linked to group detail)
Hidden columns (toggle via Columns): Device Type, Model, Firmware, Thing Type
Status column: Merged status + timestamp. Prefers connectivity data (AWS IoT Core real-time, if indexing enabled) over iparams shadow online field. Shows colored dot (green=online, gray=offline) with “since
Status filter dropdown: All / Online / Offline — appends to SearchIndex query.
Detail page tabs:
Overview — Node ID, ARN, Online Status, Last Status Update, Groups (linked)
Tags — Admin/Device/User tags in tables with Key, Value, Last Updated columns. Collapsible raw JSON.
Attributes — IoT Thing attributes (currently only
group_id)OTA Jobs — Job execution history with status badges
Advanced search:
Predefined fields: Created By, Registered From, Registration Batch, Device Model, Device Type, Firmware Version, Online Status, Room, User Location
Custom tag support: type any tag key → pick source (Admin/Device/User) → shadow path auto-constructed
Value suggestions: via
GetBucketsAggregation(graceful fallback if no IAM permission)
API calls: SearchIndexCommand (primary, returns shadow + connectivity inline), ListThingsCommand (fallback), DescribeThingCommand, GetBucketsAggregationCommand (value suggestions, graceful fallback)
Node Groups Page
List columns: Group Name, Description, Parent Group, ARN (hidden by default), Delete action
Search: Uses SearchIndex on AWS_ThingGroups index as primary search method (falls back to ListThingGroupsCommand if indexing unavailable). Supports both simple name search and advanced search with fields: Group Name, Description, Parent Group. Value suggestions via GetBucketsAggregation.
Detail page:
Overview section — ARN, Description (editable inline via
UpdateThingGroupwith error feedback), Created date, Parent Group (linked with hierarchy breadcrumb), Child Groups (linked), Node countNode list — with add/remove functionality, “Load more” only shown when more pages exist
API calls: SearchIndexCommand (primary, AWS_ThingGroups index), ListThingGroupsCommand (fallback), GetBucketsAggregationCommand (value suggestions), DescribeThingGroupCommand, ListThingsInThingGroupCommand, AddThingToThingGroupCommand, RemoveThingFromThingGroupCommand, UpdateThingGroupCommand
OTA Pages
Images and jobs are separate pages (/home/ota/images, /home/ota/jobs), each
with a create route, and a job detail page with Overview and Nodes tabs.
Shows:
OTA images: Name, Size, Uploaded date; upload via
/images/newOTA jobs: Job ID, Status, Created At; create via
/jobs/newJob detail: Overview (job config + Device Metrics chart) and per-node execution status
API calls: ListObjectsV2Command (S3), ListJobsCommand, DescribeJobCommand, CreateJobCommand, CreateStreamCommand
Known gaps
Already Accessible (No IAM Changes Needed)
Feature |
Data Source |
Notes |
|---|---|---|
Add/remove things from groups in thing detail view |
|
Permission exists, partially wired |
Alexa/GVA integration config |
|
Voice assistant setup |
Cancel OTA job |
|
Permission exists, not wired up |
Connectivity details |
|
|
DescribeThing extra fields |
|
thingId, billingGroupName, defaultClientId, version |
Device telemetry charts |
|
Historical + real-time sensor data |
Download firmware binary |
|
Permission exists, not wired up |
Firmware file ETag/hash |
|
Content integrity verification |
Full iparams shadow display |
|
Currently only selected fields shown |
Group automations/schedules |
|
Group-level service configs |
Job process details |
|
Detailed queue/in-progress/success/fail/timeout counts |
Job timeout & abort config |
|
Currently not displayed |
Mobile push platform management |
|
APNS + GCM credential management |
Node registration UI (single + bulk + status tracking) |
|
Full CRUD for device provisioning |
Node service details |
|
Device-reported service params |
Node’s ESP RainMaker Neo group membership |
|
Shows group + subgroup IDs |
ESP RainMaker Neo group hierarchy |
|
Groups + subgroups + capabilities + Matter config |
Sharing management |
|
Admin view of pending shares |
Requires IAM Changes
Feature |
Missing Permission |
Change Needed |
|---|---|---|
~~Edit group description~~ |
~~ |
Done — Added to |
~~Value suggestions in filters~~ |
~~ |
Done — Added to |
Index additional shadow names |
Fleet Indexing config |
Update |
List named shadows per device |
|
Add to |
Read any named shadow (not just iparams) |
|
Add to |
Scope admin access to specific groups |
Resource conditions |
Add IAM conditions / scoped policies |
Update device shadow from dashboard |
|
Add to |
Requires CDK Infrastructure Changes
Feature |
Change |
Impact |
|---|---|---|
~~Group search by substring, list with descriptions~~ |
~~Add |
Done — Dashboard uses |
Reliable online/offline status |
Add |
Dashboard already handles gracefully |
Reliable online/offline status needs
thingConnectivityIndexingMode: "STATUS"on the fleet-indexing configuration. Until then the dashboard prefersconnectivitydata when present and falls back to theiparamsshadow’sonlinefield.Only the
iparamsnamed shadow is readable.AdminDeviceUsersRoleholds noiot:GetThingShadoworiot:ListNamedShadowsForThing, and fleet indexing filtersnamedShadowNamestoiparams, so other named shadows (params-<group>,notify, …) are not visible here.Admin access is not scoped to specific groups. A super-admin sees the whole fleet; per-group scoping would need IAM resource conditions.
Shadows are read-only from the dashboard — no
iot:UpdateThingShadow.