Skip to main content

Demo Provisioning

Demo provisioning has three distinct surfaces. Use the deployed support flow for a durable demo organization, the simulator for local generated activity, and the GCE VM helper only for an isolated ephemeral environment. None of these paths provisions a normal customer organization.

Choose the correct flow

FlowStatus and scopeOwnerPersistence
Support portal DemosCurrent deployed admin flow. Available only to callers with demo IAM permissions.management-api, with merchant-api, terminal-api, terminal-onboarding, Auth, and Gateway dependenciesDurable application and Gateway state until an authorized demo deletion completes
Local simulatorCurrent local/dev and test-data flow. It targets an already running local stack and can optionally provision through management-api.tools/simulatorWhatever persistence the selected local stack provides
GCE demo VM helperManual demo-only helper for an isolated emulator-backed VM. It is not the deployed platform provisioning path.tools/demo/demo.sh and tools/demo/vm-startup.shEphemeral VM, Spanner emulator, and Firebase Auth emulator state

The old issue-tracking description is not an operating contract. Current behavior is defined by the controller, durable provisioning worker, simulator, and scripts listed below.

Deployed support flow

The support portal pages are:

  • apps/websites/portals/support/src/pages/DemosPage.tsx
  • apps/websites/portals/support/src/pages/DemoDetailPage.tsx

They call management-api at /api/v1/demo-orgs. The controller separates read, use, create, and delete permissions (MGMT_DEMOS_READ, MGMT_DEMOS_USE, MGMT_DEMOS_CREATE, and MGMT_DEMOS_DELETE) and scopes agent callers to their accessible demo organizations and agent subtree. Agents may create and delete demos only through these scoped routes; staff remain unscoped. Do not call the API with a broad service credential or bypass the portal permission check.

Creation lifecycle

DemoOrgService.create creates an inactive demo organization and enqueues durable provisioning. DemoOrgProvisioner then, under a task lock:

  1. creates or reuses the demo store;
  2. creates or reuses the terminal;
  3. verifies or relinks the store's Gateway authorization;
  4. writes a PEAK_GATEWAY Android/native Tap-to-Pay payment configuration;
  5. grants the demo product entitlements and feature-plan settings;
  6. seeds IAM, a demo administrator, and merchant demo data; and
  7. activates the organization only after provisioning succeeds.

Creation therefore requires an active root agent with Gateway credentials. Staff callers select an eligible root when more than one exists; agent callers are pinned to their own scoped agent when the request omits agentId, and any supplied agent must remain within their authoritative subtree. A response with status provisioning is not ready for card or catalog demonstrations; the list/detail status becomes ready only after the durable task is complete and a Gateway store binding is operationally authorized.

The implementation sources are:

  • apps/microservices/management-api/src/main/java/com/myriad/management_api/controller/orgs/DemoOrgController.kt
  • apps/microservices/management-api/src/main/java/com/myriad/management_api/service/DemoOrgService.kt
  • apps/microservices/management-api/src/main/java/com/myriad/management_api/service/DemoOrgProvisioner.kt
  • apps/microservices/merchant-api/src/main/java/com/myriad/merchant_api/controller/internal/InternalDemoController.kt

Deletion boundary

Demo deletion is destructive and intentionally rejects non-demo organizations. It is blocked while provisioning is pending or running. For a demo organization it removes merchant seed data, terminal onboarding tokens, terminal payment configuration and terminal records, Gateway store bindings and organization state, entitlements, stores, and the organization row. External cleanup failures stop final deletion rather than hiding partial cleanup. Agent callers may delete only demo organizations in their authoritative accessible organization set; staff callers remain unscoped.

Use the support portal only after confirming the exact demo organization ID. Never use this delete path as customer offboarding. If cleanup fails, preserve the error and reconcile the named dependency before retrying; do not manually delete the final organization row.

Local simulator

//tools/simulator:simulator is a Bazel java_binary. Its configuration lives in tools/simulator/src/main/kotlin/com/myriad/simulator/config/SimulatorConfig.kt. By default it points at the local Terminal, Merchant, Auth, and Management APIs and signs in to the local Firebase Auth emulator when explicit tokens are absent.

Start the local stack with its canonical local-validation workflow, then launch the simulator with Bazel:

bazel run //tools/simulator:simulator

Use JVM system properties for non-default IDs, URLs, seed, speed, or sim.auto-provision; do not paste real Firebase tokens into shell history. Auto-provisioning invokes ProvisionRunner through management-api, updates the simulator's in-memory IDs, and then proceeds to seed/live scenarios. Without auto-provisioning the simulator uses the configured IDs, which default to the deterministic local seed context.

Focused simulator verification is:

bazel test //tools/simulator:simulator_test

The simulator is not a production load generator. Do not point its mutation scenarios at production.

Ephemeral GCE demo VM helper

tools/demo/demo.sh creates, inspects, connects to, and deletes demo-* Compute Engine instances. tools/demo/vm-startup.sh installs Docker, pulls service images, starts the Spanner and Firebase Auth emulators, and schedules host shutdown after the configured TTL.

Treat this helper as privileged and demo-only:

  • up creates a VM and may create a public firewall rule; review the selected GCP project, image tag, zone, machine type, and TTL before running it.
  • down deletes the named VM and all emulator data; verify the generated demo-<name> instance before authorizing deletion.
  • The script defaults are convenience defaults, not evidence of the current deployed environment.
  • The generated environment uses emulator credentials and must not receive production secrets, customer data, or production access tokens.
  • Automatic host shutdown is not resource deletion. Use the authorized teardown path after the demonstration and confirm the instance is gone.

Use status, list, and logs for non-destructive inspection. Read the script's built-in usage before any up or down operation rather than copying a stale command from a ticket.

Failure ownership

SymptomFirst owner/check
Demo remains provisioningDurable onboarding task status and management-api logs
Creation says no eligible agentActive root-agent Gateway credential configuration
Gateway binding never becomes readyGatewayStoreBindingService result; do not replace the demo with cash-only to hide the failure
Seed/dashboard/catalog operation failsmerchant-api internal demo endpoint and internal-service authentication
Simulator cannot authenticateLocal Firebase emulator and the two configured tenant IDs
GCE VM bootstrap failstools/demo/vm-startup.sh serial/startup logs and image availability
Demo deletion failsThe specific external cleanup failure reported by DemoOrgService; retry only after reconciliation