Demo & evaluation

Vaks PM · Demo data & evaluation · June 2026

Purpose of this guide. This document explains how to prepare a realistic demonstration dataset on an already-running Vaks PM instance, so that an evaluator can sign in and try the application against representative projects, tasks and people. It then covers how to wipe everything cleanly once the evaluation is over. It is written for a system administrator new to the product, and is fully self-contained. It does not cover installing the application itself; for that, see the deployment guides linked under Prerequisites.

Overview

Vaks PM is a multi-user project-management (PM) web application that runs entirely on infrastructure the organization controls (on-premise). To let someone evaluate it without entering data by hand, the product ships a seed: a bootstrap dataset that fills a database with a believable picture of a working company, including teams, staff, a skills catalog, clients and a portfolio of ongoing projects with tasks, schedules, time entries and workload.

The whole demo lives inside a single dedicated tenant (an isolated organization served by the instance, where each tenant has its own database). Because of that isolation, two operations cover the entire lifecycle:

The seed is idempotent (it can be run repeatedly without creating duplicates: each run purges then rebuilds), so a demo can be refreshed at any time and reset without risk to other data.

Prerequisites

The seed does not deploy the application; it only fills the database of an instance that is already running. The expected starting point is:

The database connection string (DATABASE_URL) is read at runtime from a cluster secret, never typed in plaintext. On Docker Swarm it is the secret database_url; in other environments it is supplied through the environment. The commands below read it from there.

Which mode am I in, and what exactly do I fill in?

Two axes decide the exact steps. They are independent — pick your row in each.

AxisValues & what changes for the demo
Tenancy mode
(DEPLOYMENT_MODE)
Pooled (recommended for a demo) — each organization lives in its own database and is resolved from the request's host name. The demo runs as its own tenant: a separate database <dbName>_demo, reached at the subdomain demo.<baseDomain>, cleanly isolated from any real organization.
Dedicated — the instance serves a single organization out of one global database, and there is no clean place to add a demo: seeding it grafts a second organization into that shared database, reachable only by signing in with the demo admin's email, which is confusing next to a real org. To evaluate with demo data, deploy a pooled instance instead.
Topology Single host vs high availability (HA) changes nothing about the dataset or the login — only how you reach the api container: docker exec locally on a single host, or over SSH to the application host that runs it on HA. HA can be either tenancy mode.

The demo always uses the same fixed values: organization slug demo, administrator admin@vaks-demo.local, password Demo1234! (shared by every seeded account). The seeded accounts come in ready to use (each already holds a seat), so the demo works the moment it is loaded — nothing has to be granted by hand.

Seed the demo organization

The seed scripts ship with the api image and are present at /app/api/prisma/ inside the container. Two are run directly:

ScriptRole
seed-demo.jsBuilds (or rebuilds) the demo dataset. Idempotent: purges then rebuilds.
reset-demo.jsEmpties the demo organization, or removes it entirely (see Wipe everything).

Option A — seed at deploy time (from the manifest, pooled)

The cleanest way to have a demo ready the instant the instance comes up is to declare it in the deployment manifest (infra/cluster.json), so the orchestrator provisions and seeds it during bash out/deploy-ssh.sh — no manual step afterwards. Add a tenant to the tenants array carrying a "seed" field:

"tenants": [
  {
    "slug": "demo",
    "domain": "demo.<baseDomain>",
    "seed": "demo"
  }
]

At deploy time the orchestrator runs provision-tenant.js demo --seed demo, which creates the tenant database <dbName>_demo, applies the schema and loads the demo dataset. The "seed" field is the only demo-specific value; every other field is an ordinary tenant entry (see Provisioning tenants for the full schema). This path is for pooled tenancy — the demo is then reached at demo.<baseDomain>. To add a demo to an already-running pooled instance instead, use the post-deploy path below.

Domain vs login — two different things. The domain (for example demo.vaks.fr) is the host name you browse to; it must resolve in DNS to the cluster and have a TLS certificate. The login is a fixed account the demo seed always creates — admin@vaks-demo.local / Demo1234! — where the email is just an account identifier, not a host name (the .local resolves nothing). An adminEmail on the tenant entry is ignored when "seed": "demo" is set, because the demo seed hardcodes its own administrator. So: browse to https://demo.vaks.fr, sign in as admin@vaks-demo.local.

Option B — post-deploy, pooled tenancy (a dedicated demo database)

When several organizations share the instance, the demo gets its own database. Two steps: provision the tenant, then seed its database. This is the manual equivalent of Option A, for adding a demo after the instance is already up. In a multi-host (HA) install the api container usually runs on an application host rather than the manager host; reach it over SSH using the access details kept in the local environment file.

Pooled only. This path assumes the instance runs in pooled tenancy, so the demo gets its own database and subdomain. On a dedicated instance that already serves a real organization, do not seed a demo — it would land a second organization in the shared database with no clean way to reach or remove it. Use a pooled deployment for evaluation instead.

Step 1, provision the demo tenant. This creates the database <dbName>_demo, applies the schema, and bootstraps the administrator account:

source .env.local
# resolve the api container id on the application host
CID=$(ssh -i "$SSH_KEY" "$VM_USER@$APP_HOST" \
  "echo '$VM_PASS' | sudo -S docker ps -q -f name=vaks-pm_api | head -1")

ssh -i "$SSH_KEY" "$VM_USER@$APP_HOST" "echo '$VM_PASS' | sudo -S \
  docker exec $CID sh -c 'export DATABASE_URL=\$(cat /run/secrets/database_url) \
  && cd /app/api && node prisma/provision-tenant.js demo admin@vaks-demo.local'"

Step 2, seed the demo database. Point DATABASE_URL at the _demo database, then run the seed:

ssh -i "$SSH_KEY" "$VM_USER@$APP_HOST" "echo '$VM_PASS' | sudo -S \
  docker exec $CID sh -c '
    BASE=\$(cat /run/secrets/database_url)
    export DATABASE_URL=\$(node -e \"const u=new URL(process.argv[1]);u.pathname=u.pathname+\\\"_demo\\\";console.log(u.toString())\" \"\$BASE\")
    cd /app/api && node prisma/seed-demo.js'"
$APP_HOST, $SSH_KEY, $VM_USER and $VM_PASS are placeholders for the host address, the SSH key path, and the login/sudo credentials kept in the administrator's local environment file. That file is never committed to source control.

Sign in and verify

All seeded accounts share the password Demo1234!. The administrator created at seed time is admin@vaks-demo.local.

Change the default password before exposing the demo. The seed credentials (admin@vaks-demo.local / Demo1234!) are well-known and intended only for a throwaway evaluation. If the instance is reachable beyond a closed environment, sign in once and change the password, or disable the account, immediately. Never reuse these credentials for anything other than the demo.

Sign-in happens on the demo tenant's subdomain (for example demo.<baseDomain>); the shared front door resolves the tenant from the request's Host header. The login is always admin@vaks-demo.local / Demo1234! — the email is an account identifier, not the host name. A successful sign-in returns an access token and the demo's projects are visible. A quick command-line check:

# resolve the demo subdomain to the entry point and sign in → expect a token
curl -sk --resolve demo.<domain>:443:<entry-point-ip> \
  -X POST https://demo.<domain>/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin@vaks-demo.local","password":"Demo1234!"}'
Expected result: an accessToken in the response. Presenting it in an Authorization: Bearer <token> header on GET /api/v1/projects then lists the demo's projects.

What the dataset contains

The seed simulates an IT services company (Information Technology) with realistic teams, staff and a portfolio of projects. It exercises the main areas of the product so an evaluator can explore a Kanban board (task board with status columns), a Gantt chart (schedule with dependencies and critical path), time tracking, workload and capacity, the skills catalog, clients and the full project lifecycle. The content is in English and stays confined to the demo tenant.

ElementDetail
OrganizationA single demo IT-services company, isolated in its own tenant.
UsersAbout two dozen accounts (staff plus one administrator), all with password Demo1234!.
TeamsSeveral teams (for example Infrastructure, Developers, IT Security, HR, Commercial, Project Management, Management), with team leads.
SkillsA populated skills catalog with per-person levels and per-team coverage.
ClientsA handful of clients and contacts, attached to projects.
ProjectsSeveral projects spread across the lifecycle statuses.
TasksDozens of dated tasks with estimates, priorities, milestones, and a task group with subtasks.
DependenciesFinish-to-Start links that drive the Gantt schedule and critical path.
Time & workloadTime entries (including overtime and billable time), workload allocations and time-off entries.
CollaborationComments with @mentions.
Skill requestsRequests from a project manager to a team lead, across the open / acknowledged / resolved states.
Public holidaysA default country plus per-user country overrides, to demonstrate capacity warnings.
A few accounts carry distinct organization roles so that role-based access can be observed: a portfolio manager and a report viewer, for instance, alongside the administrator and the standard members. All share the same demo password.

Wipe everything

When the evaluation is over, reset-demo.js removes the demo content. It acts strictly on the demo organization; no other organization on the instance is affected.

# soft reset: empty the org (content + users), keep the empty organization
docker exec <api-cid> sh -c 'export DATABASE_URL=… && cd /app/api && node prisma/reset-demo.js'

# hard reset: also remove the organization record
docker exec <api-cid> sh -c 'export DATABASE_URL=… && cd /app/api && node prisma/reset-demo.js --hard'

To re-seed afterwards, run seed-demo.js again; it is idempotent.

In pooled mode the demo tenant is a separate database, so the cleanest disposal is to drop that database entirely and, if a demo is needed again later, re-provision and re-seed it. This carries no risk to any other organization on the instance.
Reset removes data permanently. Make sure the target is the demo organization (or the <dbName>_demo database in pooled mode) and not a real one before running a hard reset or dropping a database.

Where to go next

With the demo seeded and an administrator signed in, the application is ready to explore. To understand what each area does and how to drive a meaningful walkthrough (Kanban, Gantt, time tracking, workload, skills, clients, reporting and the rest), see the product guide. For operating the instance behind the demo, see operations and security.


Related: Product guide · Docker Swarm deployment · Kubernetes deployment · Operations · Security · Documentation home