A seed script is a program, separate from the migration history, that inserts baseline or demo data into an existing schema — typically checking whether that data already exists so the script is safe to run more than once.
In simpler words
A seed is a “make sure these demo accounts and sample rows exist” script — it never changes the schema, and running it twice should not create duplicates.
This course’s seed script is exactly how admin@course.local and member@course.local (password123) get into a fresh database.
After this you can
Explain why seed.ts checks for an existing row before creating one
Run migrations then seeds in the correct order on a fresh database
State the boundary between what belongs in a migration versus a seed
What seed.ts actually does
Definition
This repo’s seed script initializes the same DataSource used by the migration CLI, looks up each seed user by email, creates it only if missing, hashes its password with bcrypt, and inserts three sample tickets only if the tickets table is empty.
In simpler words
Every insert is guarded by a check — that is what makes it safe to run again without duplicating data.
users.findOne({ where: { email } }) before users.save(...) is the idempotency check for each seed user.
tickets.count() === 0 gates the sample tickets — once any ticket exists, the seed skips inserting more.
bcrypt.hash(..., 12) never stores the plaintext password — even in seed data, hash it for real.
Seeds vs migrations
Definition
Migrations change what a database’s schema is (and occasionally essential reference data every environment must have), while seeds populate non-essential sample or development data on top of an already-migrated schema.
In simpler words
A migration should never be the place a demo user quietly gets created; a seed should never be the place a column quietly gets added.
If removing the seed script would break the app’s schema, that content belongs in a migration instead.
If removing a migration step would just mean fewer demo rows, that content belongs in a seed instead.
Boundary in one line
Migrations → schema shape + required reference data
Seeds → demo/dev convenience data (admin/member users, sample tickets)
Keep schema changes reviewable in migrations; keep demo data disposable in seeds.
Running seeds locally
Definition
A seed script runs after the schema exists — after migrations have applied — since it inserts rows into tables the migrations are responsible for creating.
In simpler words
The correct fresh-database order is always: run migrations first, then run the seed.
pnpm db:seed (root alias for pnpm --filter @repo/api seed) runs apps/api/src/database/seed.ts via ts-node against the same DataSource the CLI uses.
After seeding, admin@course.local and member@course.local both work with password123 for logging in locally.