Dentolize · Dynamic Clinic Seeder Walkthrough
On this pageBusiness viewTechnical view

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)

  1. Open the PR. Find the "Sandbox live" comment.
  2. Click the Web link.
  3. Log in with the email + password from the comment, or with the **username +

company login name + password**.

  1. 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-dynamic with the same OWNER_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).

--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 PASSWORD isn't set: Dentolize@2026

(config.js:88).