An entity-relationship diagram (ERD) records the entities, their key attributes, and the relationships and cardinalities between them, providing an agreed schema plan to write against before a migration or entity file exists.
In simpler words
Before you write any code, sketch which things exist, what they hold, and how they connect — the migration should follow the sketch, not invent it.
This repo already has a small, real ERD: users and tickets, related by an optional assignment. Read the existing shape before extending it.
After this you can
Read the current users/tickets ERD from the entities
State a schema extension in plain language before writing SQL
Name the ON DELETE decision a new foreign key needs
The tickets domain ERD as it exists today
Definition
The current schema defines a User entity and a Ticket entity connected by an optional many-to-one relationship, where many tickets may reference at most one assignee and a ticket may have no assignee at all.
In simpler words
Every ticket points at zero or one user through assignee_id; a user can be the assignee of many tickets.
User: id (uuid pk), email (unique), passwordHash, name, role (admin | member). Ticket: id (uuid pk), title, description (nullable), status (open | in_progress | done), assignee_id (nullable fk → users.id, ON DELETE SET NULL), created_at, updated_at.
ON DELETE SET NULL on assignee_id is itself a planning decision: deleting a user should not delete their previously assigned tickets.
Read this alongside the InitSchema migration — the migration is the ERD, expressed as SQL.
Planning an extension before writing SQL
Definition
Extending a schema should start by stating the new or changed entity, its attributes and constraints, and its relationships to existing entities in plain language, so the migration and DTOs that follow only encode decisions that were already made.
In simpler words
Decide the shape on paper — or in a PR description — first: what is it, what does it hold, what does it relate to. Then let the migration generator encode that decision.
A plausible extension: a Comment entity with a many-to-one relation to Ticket and to User (author), each required, plus created_at — decide cascade behavior (does deleting a ticket delete its comments?) before generating anything.
Naming and nullability are planning decisions with real consequences: a nullable foreign key means “this relationship is optional” for every future query against that table.
A planning note before migration:generate
Comment
id uuid pk
ticket_id uuid fk -> tickets.id, NOT NULL, ON DELETE CASCADE
author_id uuid fk -> users.id, NOT NULL, ON DELETE SET NULL
body text NOT NULL
created_at timestamptz
Every foreign key’s ON DELETE behavior and every column’s nullability should be a stated decision, not an accident of a generator’s defaults.
Keep in mind
Read InitSchema as the reference ERD before adding a new entity.
State cardinality and nullability in plain language before generating a migration.
Decide ON DELETE behavior deliberately — it defines what a deletion elsewhere in the graph actually does.
Test
Check your understanding
At least 10 questions — mix of concept, syntax, practical, and logic. Score ≥ 80% (enforced by the API) to save progress.