Skip to Content
Core ConceptsDemo mode

Demo mode

Every SeqDesk installation can host disposable demo workspaces — fully isolated, token-keyed copies of a researcher (or facility-admin) experience that anyone can spin up, poke at, and walk away from. The data lives in the same database as the rest of the install but is partitioned per token, so a demo session can’t see or affect real facility data. After a configurable expiry the workspace is deleted by a cleanup job.

This is what the seqdesk.com/demo URL points at, but the same surface is available in any install — handy for training, screencasts, or letting a prospective researcher click around before they sign up.

URLs

PathAudienceWhat it shows
/demoPublic researcher demoStandalone researcher dashboard with seeded orders/studies
/demo/adminPublic facility-admin demoSame install seen as a facility admin (form builders, modules, ENA settings)
/demo/embedEmbeddable researcher demoStripped-down chrome for use inside an iframe (e.g., on the marketing site)

All three flows share the same backend. The difference is just which demoExperience is requested at bootstrap and how the page chrome renders.

Lifecycle

The flow is bootstrap → use → reset (optional) → expire → cleanup.

1. Bootstrap

When a user first hits /demo, the page calls POST /api/demo/bootstrap. The server either reuses an existing workspace (matched by a token cookie) or creates a new one:

What gets createdDetail
DemoWorkspace rowNew id, fresh random token, hashed and stored as tokenHash, expiresAt set in the future
Demo userEither a researcher or facility-admin user, marked isDemo: true
Seed dataA small set of demo orders, samples, studies, and form fields — enough that the dashboard isn’t empty
Site-settings overridesDisplay name set to “SeqDesk Demo”, help text set to a “this is a disposable session” reminder
Modules configReset to defaults
Auth cookieA session token cookie scoped to the demo user, expiring at expiresAt

The bootstrap response includes:

{ "created": true, "workspaceId": "ckxx...", "expiresAt": "2026-05-12T12:00:00.000Z", "demoExperience": "researcher" }

2. Use

From this point on, every API request the demo session makes carries the session cookie. Server-side, isDemoSession() checks the user.isDemo flag and disables a small number of features that don’t make sense in a sandbox (see Restrictions).

3. Reset

A logged-in demo user can call POST /api/demo/reset to wipe their workspace and re-seed. The same workspaceId is kept; the auth session token is re-issued. Useful when a demo gets “messy” mid-walkthrough.

4. Expire

Each DemoWorkspace.expiresAt is set at bootstrap. Once that time passes the session cookie no longer authenticates and the workspace becomes a candidate for deletion.

5. Cleanup

GET /api/demo/cleanup deletes every DemoWorkspace whose expiresAt is in the past. The endpoint is gated behind a Bearer token check so it can be wired to a cron job (Vercel Cron, GitHub Actions, systemd timer) without exposing the cleanup ability to anonymous traffic. A typical setup runs it every 15 minutes.

Embed mode

/demo/embed renders the same researcher demo with chrome simplified for iframe embedding:

  • Top navigation collapsed
  • Branded SeqDesk header hidden
  • Sidebar minimized

The marketing site at seqdesk.com embeds this view to give visitors a working demo without leaving the page. The bootstrap, reset, and expiry flows are identical to the standalone /demo route — only the layout differs.

Restrictions

In a demo session the following are deliberately disabled:

  • File downloads/api/files/download returns 403 for isDemo users.
  • Assembly downloads — the Assemblies viewer hides the download column and shows a banner.
  • Real ENA submissions — submission attempts fall through to test mode regardless of the configured ENA settings.
  • Pipeline execution — pipelines can be inspected but not actually launched.

Outbound side effects (sending mail, calling external APIs) are also gated. Everything else — clicking through orders, editing forms, browsing studies — behaves exactly like the real app.

DemoWorkspace fields

Defined at prisma/schema.prisma:

FieldTypePurpose
idcuidWorkspace identifier
tokenHashunique stringSHA-256 of the bootstrap token; the raw token only lives in the browser cookie
userIdunique stringResearcher User row owned by this workspace
adminUserIdoptional stringFacility-admin User row, populated for admin demos
seedVersionintBumped when the seeder schema changes, used for migrations
lastSeenAtdatetimeUpdated on each request — useful for “active demos” telemetry
expiresAtdatetime, indexedCleanup query target
createdAt / updatedAtdatetimeStandard timestamps

Operating a public demo

A typical configuration for a public-facing demo:

# Run the cleanup endpoint every 15 minutes */15 * * * * curl -fsS -H "Authorization: Bearer $DEMO_CLEANUP_TOKEN" \ https://your-host/api/demo/cleanup

Set the cleanup token in your environment so the demo install can verify it. Workspace expiry is configured server-side; rebuild the install to change the default.

When to use it

  • Onboarding — give new researchers a working sandbox before exposing them to production.
  • Marketing — embed /demo/embed on a landing page; visitors can interact with a fully functional SeqDesk without account creation.
  • Training & screencasts — record against /demo so the URL reset flow gives you a clean state between takes.
  • Bug repro — file uploads and pipeline launches are gated, but everything else (form configuration, MIxS validation, study workflows) reproduces faithfully.