Design entities, relationships, and manage the migration lifecycle. Use when planning a data model, designing entities, choosing relationship patterns, adding cross-module references, or managing database migrations. Triggers on "design entity", "data model", "add entity", "database schema", "migration", "relationship", "many-to-many", "junction table", "foreign key", "jsonb", "add column".
Design entities, relationships, and manage the migration lifecycle following Open Mercato conventions.
When the developer describes data requirements:
import { Entity, Property, PrimaryKey, Index, Enum } from '@mikro-orm/core'
import { v4 } from 'uuid'
@Entity({ tableName: '<entities>' })
export class <Entity> {
@PrimaryKey({ type: 'uuid' })
id: string = v4()
@Index()
@Property({ type: 'uuid' })
organization_id!: string
@Index()
@Property({ type: 'uuid' })
tenant_id!: string
// --- Domain fields ---
// (see Field Types section)
// --- Standard columns ---
@Property({ type: 'boolean', default: true })
is_active: boolean = true
@Property({ type: 'timestamptz' })
created_at: Date = new Date()
@Property({ type: 'timestamptz', onUpdate: () => new Date() })
updated_at: Date = new Date()
@Property({ type: 'timestamptz', nullable: true })
deleted_at: Date | null = null
}
| Column | Type | Purpose | Indexed |
|---|---|---|---|
id | uuid | Primary key (v4 auto-generated) | PK |
organization_id | uuid | Tenant organization scope | Yes |
tenant_id | uuid | Tenant scope | Yes |
is_active | boolean | Soft active/inactive flag | No |
created_at | timestamptz | Creation timestamp | No |
updated_at | timestamptz | Last update (auto) | No |
deleted_at | timestamptz? | Soft delete timestamp | No |
| Data | MikroORM Type | PostgreSQL Type | Decorator |
|---|---|---|---|
| Short text (name, title) | varchar | varchar(255) | @Property({ type: 'varchar', length: 255 }) |
| Long text (description, notes) | text | text | @Property({ type: 'text' }) |
| Integer | int | integer | @Property({ type: 'int' }) |
| Decimal (money, quantity) | decimal | numeric(precision,scale) | @Property({ type: 'decimal', precision: 10, scale: 2 }) |
| Boolean | boolean | boolean | @Property({ type: 'boolean', default: false }) |
| UUID reference | uuid | uuid | @Property({ type: 'uuid' }) |
| Date only | date | date | @Property({ type: 'date' }) |
| Date + time | timestamptz | timestamptz | @Property({ type: 'timestamptz' }) |
| Enum | varchar | varchar | @Enum({ items: () => MyEnum }) |
| Flexible JSON | jsonb | jsonb | @Property({ type: 'jsonb', nullable: true }) |
| Array of strings | jsonb | jsonb | @Property({ type: 'jsonb', default: '[]' }) |
varchar | varchar(320) | @Property({ type: 'varchar', length: 320 }) | |
| URL | text | text | @Property({ type: 'text' }) |
| Phone | varchar |
Use jsonb when:
Avoid jsonb when:
export enum OrderStatus {
DRAFT = 'draft',
PENDING = 'pending',
CONFIRMED = 'confirmed',
SHIPPED = 'shipped',
DELIVERED = 'delivered',
CANCELLED = 'cancelled',
}
@Enum({ items: () => OrderStatus })
varchar(50) |
@Property({ type: 'varchar', length: 50 }) |