What We’re Testing
DashboardPage.tsx loads all metrics in a single RPC call via useDashboardData, which calls api.rpc("get_dashboard_stats", { _org_id: orgId }). This maps to POST /api/db/_rpc with body { "fn": "get_dashboard_stats", "_org_id": "..." }, handled in db-crud.ts (handleRpc).
The RPC executes two primary queries plus six secondary queries in parallel:
- Primary 1:
machinestable — returns all machines for the org, sorted bylast_seen DESC - Primary 2:
org_membersLEFT JOINprofiles— returns all members withfull_nameandavatar_url - Secondary queries (parallel): pending invites, SSO enabled count, posture compliance totals, threats blocked, active certs, ACL rule count
The frontend derives:
machineCount— total machines (all statuses)onlineCount— machines wherestatus = 'online'offlineCount—machineCount - onlineCountpendingCount— machines wherestatus = 'pending'recentMachines— first 4 online machines (bylast_seen DESC)postureRate—Math.round((postureCompliant / postureTotal) * 100)lastHeartbeat—Math.maxof alllast_seentimestamps across all machines
The React Query cache key is ["dashboard", orgId]. Stale time is the React Query default — no custom staleTime is set.
The data is displayed on DashboardPage.tsx in the “Network Status” card (machine counts) and “Configuration” card (ACL rules, members), and in the “Active Machines” and “Team” lists at the bottom.
Your Test Setup
| Machine | Role |
|---|---|
| ⊞ Win-A | Browser + API testing machine — runs all curl commands and dashboard checks |
ST1 — Machine Count Matches API
What it verifies: The “Network Status” card shows the correct total, online, and pending machine counts drawn from the get_dashboard_stats RPC.
Steps:
- On ⊞ Win-A , set your credentials:
TOKEN="YOUR_ADMIN_JWT_TOKEN"
ORG_ID="YOUR_ORG_ID"
- Call the RPC directly:
curl -s -X POST https://login.quickztna.com/api/db/_rpc \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"fn\":\"get_dashboard_stats\",\"_org_id\":\"$ORG_ID\"}" | python3 -m json.tool
Expected response:
{
"success": true,
"data": {
"data": {
"machines": [...],
"machineCount": 3,
"onlineCount": 2,
"offlineCount": 1,
"members": [...],
"memberCount": 2,
"pendingInvites": 0,
"ssoEnabled": false,
"postureTotal": 3,
"postureCompliant": 2,
"threatsBlocked": 0,
"activeCerts": 1,
"aclRuleCount": 4
}
}
}
-
Open
https://login.quickztna.com/dashboardin a browser on ⊞ Win-A . -
Compare the “Network Status” card’s displayed counts (e.g., “2/3 Online”) against the
onlineCountandmachineCountfields from the API response.
Pass: The dashboard “Network Status” card displays onlineCount/machineCount Online. The count displayed matches the RPC response exactly. No rounding or formatting difference.
Fail / Common issues:
- Dashboard shows a stale count — the React Query cache has not expired. Hard-refresh the page (
Ctrl+Shift+R) to force a re-fetch. FORBIDDENfrom the API — the token belongs to a member role, not admin/owner. The RPC only requires org membership (isOrgMember), so membership is sufficient.
ST2 — Pending Count Display
What it verifies: Machines with status = 'pending' are counted and surfaced in the Network Status card as “N pending approval”.
Steps:
- On ⊞ Win-A , query pending machines directly:
curl -s "https://login.quickztna.com/api/db/machines?org_id=eq.$ORG_ID&status=eq.pending&select=id,name,status" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
-
Note the count of results.
-
Call the RPC and check
pendingCountis not in the RPC response directly — the frontend derives it frommachines.filter(m => m.status === 'pending').lengthclient-side. -
On the dashboard, the Network Status card displays the pending count line only when
pendingCount > 0. Verify this line appears (or is absent) consistent with the pending machine count from step 1.
Expected (when 1 pending machine exists): The Network Status card shows:
1 pending approval
Pass: The pending count label appears in the Network Status card when and only when pending machines exist. The count matches the raw DB query.
Fail / Common issues:
- Pending count is stale — a machine was recently registered and not yet approved. Refresh the dashboard. If still wrong, check whether the machine’s
statuscolumn in the DB actually readspending.
ST3 — ACL Rule Count and Member Count
What it verifies: The “Configuration” card (admin view) shows the correct ACL rule count and member count from the RPC.
Steps:
- On ⊞ Win-A , get the raw ACL rule count:
curl -s "https://login.quickztna.com/api/db/acl_rules?org_id=eq.$ORG_ID&select=id" \
-H "Authorization: Bearer $TOKEN" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('data',d.get('results',[]))))"
- Get the member count:
curl -s "https://login.quickztna.com/api/db/org_members?org_id=eq.$ORG_ID&select=user_id,role" \
-H "Authorization: Bearer $TOKEN" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('data',d.get('results',[]))))"
-
Compare against the RPC
aclRuleCountandmemberCountfields from the RPC call in ST1. -
On the dashboard Configuration card, the displayed values should read:
ACL Rules: 4
Members: 2
(matching your actual counts)
Pass: aclRuleCount in the RPC matches the raw count of rows in acl_rules for the org. memberCount matches the count of rows in org_members. The Configuration card displays both correctly.
Fail / Common issues:
aclRuleCountin RPC does not match the CRUD query count — the RPC usesSELECT COUNT(*) FROM acl_rules WHERE org_id = ?(all rules regardless ofenabledflag), while the CRUD query may use different filters. Both are expected to match when no filter is applied.- Configuration card is absent — you are logged in as a
memberrole. The Configuration card only renders forowneroradminroles. Members see the “Team” card instead.
ST4 — Posture Compliance Rate
What it verifies: The health card’s posture rate is correctly computed as Math.round((postureCompliant / postureTotal) * 100).
Steps:
- On ⊞ Win-A , query posture reports:
curl -s "https://login.quickztna.com/api/db/posture_reports?org_id=eq.$ORG_ID&select=compliant" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
-
Count the total and compliant rows from the response.
-
Compute expected rate:
round((compliant / total) * 100)— e.g., 2 compliant out of 3 total = 67%. -
Click “Show health and security details” on the dashboard to expand the advanced cards.
-
Read the “Health” card’s posture line — it reads
"Posture: N% compliant"or"Posture: No devices checked"whenpostureTotal === 0.
Expected (2 compliant, 3 total):
Posture: 67% compliant
Pass: The displayed percentage matches the manual calculation. When no posture reports exist, the card displays “No devices checked”.
Fail / Common issues:
- Rate appears as 0% — posture reports exist but
postureCompliantis 0, meaning no machines passed their posture checks. - “No devices checked” appears despite reports existing — the
postureTotalfield from the RPC is 0, which means theposture_reportstable join is not finding records for this org.
ST5 — Threats Blocked and Active Certs
What it verifies: The Security card (in advanced view) shows the correct “Threats blocked” count from threat_checks and active certificates from issued_certificates.
Steps:
- On ⊞ Win-A , query threats blocked:
curl -s "https://login.quickztna.com/api/db/threat_checks?org_id=eq.$ORG_ID&action_taken=eq.blocked&select=id" \
-H "Authorization: Bearer $TOKEN" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('data',d.get('results',[]))))"
- Query active certs:
curl -s "https://login.quickztna.com/api/db/issued_certificates?org_id=eq.$ORG_ID&revoked=eq.false&select=id,expires_at" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
Note: The RPC filters active certs with revoked = FALSE AND expires_at > NOW(). The CRUD query above does not apply the expiry filter, so the CRUD count may be higher if expired-but-not-revoked certs exist.
- On the dashboard, click “Show health and security details”. Read the Security card:
SSO: Off
Threats blocked: 0
Certs: 1 active
Pass: “Threats blocked” matches the count of rows with action_taken = 'blocked'. “Certs: N active” matches the count of non-revoked, non-expired certificates. SSO shows “Active” when at least one SSO configuration has enabled = TRUE.
Fail / Common issues:
- Cert count differs by 1 or more — the discrepancy is likely expired but not revoked certificates. The RPC applies
expires_at > NOW()which the direct CRUD query does not. - Threats blocked shows stale data — the dashboard uses React Query; if a threat check was run recently, force-refresh the page.
Summary
| Sub-test | What it proves | Pass condition |
|---|---|---|
| ST1 | Machine count RPC | machineCount/onlineCount in Network Status card match get_dashboard_stats response |
| ST2 | Pending count | ”N pending approval” line appears when and only when pending machines exist |
| ST3 | ACL rules and member count | Configuration card counts match raw DB row counts |
| ST4 | Posture compliance rate | Displayed percentage equals round((compliant/total) * 100) |
| ST5 | Threats blocked and certs | Security card values match threat_checks and issued_certificates queries |