Skip to main content
Version: 1.0.8

Platform Architecture

RabbitQA is a set of services behind a single API gateway, with one web application in front of them. Knowing which service owns what explains most of the behavior you will meet — why a call needs a workspace header, why a module can be switched off for one workspace but not another, and why some screens appear under two different modules.

Request path

Every call from the web application takes the same route:

Browser (Next.js application)

│ Authorization: Bearer <jwt>
│ X-Workspace-Id: <id>

API Gateway ──── validates the token
│ ──── checks the workspace is reachable
│ ──── checks the workspace is entitled to the module

├──────────────► Organization identity, workspaces, teams, roles, credits
├──────────────► Test Management TestPilot, CaseWriter, Analyzer, Smart PBI,
│ SmartRequest, DataCrate, Accessibility, FileHub
├──────────────► AutoRunner automation projects, scenarios, plans, runs
├──────────────► HealthCheck System, Security and Business Check
└──────────────► Device Farm MobileHub and BrowserHub devices and sessions

The path prefix selects the service. See the API Overview for the full prefix table.

Services

ServiceOwns
API GatewayRouting, token validation, token blocklist, workspace validation, module entitlement, CORS
OrganizationAccounts, authentication, companies, workspaces, teams, roles, permissions, notifications, credits and billing
Test ManagementThe product modules that work with documents, test cases and results, plus shared file storage
AutoRunnerAutomation sources, scenarios, plans, runs, schedules, engines and the element registry
HealthCheckUptime and synthetic monitoring, security scanning and business assessments. Deployed as its own application with its own database.
Device FarmPhysical and virtual devices, browsers, and live and automated sessions. An external service reached through the gateway.
AI generationDocument analysis, scoring and generation used by Analyzer, Smart PBI, CaseWriter, SmartRequest and DataCrate

Authentication was extracted from Test Management into the Organization service, so identity endpoints live under /api/v1 while product endpoints live under a module prefix. That split is why user, role and company calls do not carry a /tmt prefix.

Tenancy

RabbitQA nests four levels, and all four are checked on a request:

  1. Company — the top-level tenant. Users, roles and billing belong to it.
  2. Workspace — the working container. Projects, test cases, runs, datasets and sessions all belong to one workspace, and the active workspace travels on the X-Workspace-Id header.
  3. Module entitlement — each workspace has a set of enabled modules. The gateway refuses a call to a module the workspace does not have, before the owning service ever sees it.
  4. Permissions — granular keys such as TESTPILOT_READ or autorunner:testdata:reveal, granted through roles and enforced by the owning service.

The practical consequence: the same account sees different data, and a different set of modules, depending on which workspace it is in.

note

HealthCheck is scoped to the company rather than the workspace, so its monitors and incidents are the same whichever workspace you are in.

Shared screens

Some screens are implemented once and mounted under several modules. This is deliberate, and it is why the same page can appear in two places:

ScreenImplemented inAlso appears as
File ManagementAnalyzerCaseWriter Files, Smart PBI Files
SettingsAnalyzerSmart PBI Settings, CaseWriter Settings — the tab set changes with the host module
Test RepositoryCaseWriterTestPilot Test Repository
Issue TrackerTestPilotAccessibility Issue Tracker, MobileHub Issue Tracker, AutoRunner Issue Tracker
Device session controlsMobileHubBrowserHub sessions

How work flows between modules

Modules hand work to each other rather than duplicating it:

Requirements documents

├─► Analyzer ──────► quality score, analysis sessions

├─► Smart PBI ─────► epics, features, stories ──► Jira / Azure DevOps

└─► CaseWriter ────► generated test cases ──► review ──► test repository

TestPilot ◄─────────────┤
(plans, runs, results) │

AutoRunner ◄────────────┘
(automated scenarios and runs)

SmartRequest feeds Smart PBI and CaseWriter as a source of requirements, DataCrate supplies test data to AutoRunner environments, and Impact Analyzer compares document versions to propose a regression set for TestPilot.

Technology

LayerTechnology
Web applicationNext.js 16, React 19, Tailwind CSS 3
UI componentsRadix UI primitives with a shared component package
Client stateZustand and SWR
GatewaySpring Cloud Gateway on Java 21
Organization, Test Management, HealthCheckSpring Boot 3 on Java 21
AutoRunnerSpring Boot on Kotlin 2.1 and Java 21
AI generationPython service exposing an HTTP API
DatabasePostgreSQL
Cache and countersRedis
Object storageMinIO
MessagingNATS
Packaging and deliveryDocker images built in GitLab CI

Security

Authentication

  • Sign-in returns a signed JWT access token, valid for 8 hours by default, plus an opaque refresh token held server-side.
  • Every service validates the same token independently; the gateway additionally checks a blocklist, so signing out invalidates a token immediately rather than at expiry.
  • Some integrations authenticate with a scoped credential instead of a user token: HealthCheck API keys, Device Farm API keys, and AutoRunner engine tokens.

See Authentication for the endpoints and headers.

Access control

  • Role-based, with granular permission keys rather than coarse role checks.
  • Workspace isolation is enforced on the server: responses are scoped by the active workspace, not filtered in the browser.
  • Module entitlement is checked at the gateway, independently of permissions.

Data protection

  • Traffic to the gateway is served over TLS.
  • Files are held in object storage and served through short-lived pre-signed URLs rather than public paths.
  • Sensitive automation values, such as test data secrets, are redacted in the interface and revealing them requires a specific permission.
  • Sign-in, password reset and sign-up endpoints are rate limited to resist credential stuffing and enumeration.