Skip to main content

Sandbox (nex_test_ keys)

Requests authenticated with a nex_test_ API key use the same production database as live traffic, but only see and mutate rows marked is_sandbox = true. Live keys (nex_live_), personal access tokens (nex_pat_), and normal browser sessions only see rows where is_sandbox is false (legacy rows without the flag are treated as live). For the full rationale and migration notes, see ADR 0003 in the repository (docs/decisions/0003-sandbox-environment.md).

Isolation rules

New rows created while handling a sandbox request are stored with is_sandbox = true. Updates and deletes apply only within that partition, so test keys cannot modify production shift/staff/credential/payroll rows and production traffic cannot touch sandbox copies.

Tables in Phase 1 scope

Row-level isolation is enforced today on the highest-traffic transactional surfaces, including:
  • Shifts (related assignments and shift-linked flows follow shift visibility)
  • Staff
  • Credentials
  • Payroll runs
  • API key usage events (each request log carries is_sandbox)
Other domains may not yet filter on is_sandbox everywhere. If you call an endpoint outside this scope, assume isolation is not guaranteed until covered by the same pattern.

Side effects

Sandbox requests do not deliver real user notifications (push, SMS, email); attempts are skipped and logged. Outbound platform webhooks are not emitted for sandbox-key traffic.

Usage analytics and outcomes

All GET /api/api-usage/* aggregates (summary, timeseries, by-agent, by-tool, by-key, outcomes) include production traffic only: rows with is_sandbox = true are excluded so outcome counts align with billing-oriented views.

Retention (TTL) and reset

Two independent mechanisms keep the sandbox tidy:
  • Retention purge (global safety net). Sandbox rows older than 30 days are deleted by a daily background job. Purge order favors dependents (e.g. shifts first where cascading applies), then staff, credentials, payroll runs, and sandbox usage-event rows.
  • On-demand reset (immediate, facility-scoped). POST /api/sandbox/reset clears a single facility’s sandbox rows and re-seeds a small synthetic dataset (5 workers, 10 open shifts) so you can start from a predictable slate.
Via CLI (same session constraint — login with device-code / browser session, not an API key):
Reset is a dashboard/session operation restricted to NexSpace 365 administrators. It cannot be called with an API key (including a nex_test_ key) — this prevents a low-scope token from wiping data. Sign in and call it with your session, use nexspace fixtures sandbox-reset, or trigger it from the developer settings UI.
The response reports what was cleared and re-seeded: