For Training
Business view
This page teaches someone how to run the seeder and use a seeded sandbox. Audience: engineers, QA, and anyone who needs demo data locally or in a preview.
Lesson 1 — Log in to a preview sandbox (no setup)
- Open the PR. Find the "Sandbox live" comment.
- Click the Web link.
- Log in with the email + password from the comment, or with the **username +
company login name + password**.
- You're in a full clinic. Explore Patients, the Calendar, Finances, Inventory.
Every login in the roster shares one password. Pick the role you want to demonstrate — owner sees everything; receptionist1, accountant1, hrmanager1, doctor1/2 see their slice.
Lesson 2 — Seed a clinic on your own machine
From packages/server:
# Defaults: Saudi Arabia, 12 months of history, 80 patients, 2 branches, 4 doctors
yarn seed-dynamic
# Customize with env vars…
COUNTRY=AE PATIENTS=120 MONTHS=6 yarn seed-dynamic
# …or with CLI flags (flags win over env vars)
yarn seed-dynamic --country EG --patients 40 --naming descriptive
It prints a banner showing the target database and the parameters, builds the clinic step by step (S-1 … S-6), and finishes with a summary block: company login name, username owner, password, and record counts.
Lesson 3 — The safety rail
The seeder refuses to run against a non-local database unless you explicitly confirm. If your DATABASE_URL points at anything other than localhost / 127.0.0.1, you'll get an error telling you to re-run with --confirm. This is there so nobody seeds a shared or production database by accident. Read the banner before you confirm.
Lesson 4 — Clean up
To remove a seeded company:
yarn seed-dynamic --cleanup <companyId>
The company id is printed in the summary (SEED_COMPANY_ID). Cleanup is best-effort and additive-safe: if a stray foreign key blocks the final delete, the guidance is to drop the local database and re-seed fresh.
Teaching tips
- Start descriptive. Show trainees the descriptive naming first — *"Patient
011 · Insured 50%"* teaches the billing model faster than a random name.
- Follow one patient end to end. Pick an insured patient, open their invoices,
and trace the insurance split, VAT, and part-payment. It's a great tour of the whole billing flow.
- Show idempotency live. Run
yarn seed-dynamicwith the sameOWNER_EMAIL
twice; the second run refreshes passwords instead of duplicating the clinic.
Technical view
- Entry point / step order: index.js:51 runs S-1 provision → S-1b flags →
S-2 branches → S-3 people → S-4 assets → S-5 patients/visits → S-5b HR → S-6 coverage. HR and coverage no-op unless the accounting module is present (index.js:96-129).
- Script:
seed-dynamic=babel-node … dynamicSeed/index.js
(packages/server/package.json, scripts).
- Parameters: env var or
--flag value, CLI wins; parsed in
config.js:57. Defaults: BRANCHES=2, DOCTORS=4, STAFF=4, PATIENTS=80, AVG_OPS=4, MONTHS=12, COUNTRY=SA, NAMING=realistic, SEED=20260530 (config.js:62-84).
- Safety guard: assertSafeTarget throws for non-local hosts unless
--confirm / CONFIRM=1 (config.js:105-113); the banner prints the target first (config.js:93).
- Cleanup:
--cleanup <companyId>→ cleanupCompany, which validates the
id is a UUID, disables FK triggers for one transaction, and deletes children then the company (report.js:76-97, index.js:54-61).
- Default password when
PASSWORDisn't set:Dentolize@2026
(config.js:88).