Amended by 0133:
model keys, rename-safe fields and lifecycle events. The state machine moves out of @stackra/model
to its own package (ADR 0161, wave 1 part 4, not on this branch).
Context
MikroORM is the ORM (0014). Models are decorated classes (0094), and their shapes are needed on the client too: forms, the API client and admin resources. MikroORM’s own decorators would pull the ORM into client bundles. The owner left open where MikroORM lives (Round 9 G1). A Nest ORM wrapper studied as a reference (nestjs-orm, also found atarchive/monorepo-main/packages/infra/orm)
already has the feature set products expect. The owner compared the plan against it and accepted it with five additions.
Decision
@stackra/modelholds the client-safe parts: model and field decorators built on@stackra/validation(0095), relations as metadata, scopes, eager-load declarations, a state machine,createTraitand the trait registry (0096). It imports no ORM.@stackra/databaseis the only package that imports@mikro-orm/*.stackra genemits MikroORMEntitySchemadefinitions from model metadata. MikroORM’s decorators are not used.- The feature list is ported from the nestjs-orm reference (its features, not its code): scopes, eager loading,
per-audience hidden and visible fields, morph relations, pivots, the trait runtime as a MikroORM subscriber, named filters,
three paginators with cursor as the default, chunk, upsert and bulk operations, typed flush errors, factories and seeders,
migrate, seed and make commands on
@stackra/console, a DataLoader, pruning, and a per-model connection resolver (0088). - Five additions from the reference:
- list filtering, sorting and includes, declared on the model and accepted by list actions;
@Storedand@Translatablefield storage (where and how a field is persisted, and per-locale values);- the rich CRUD API consumed by
@Crud(0105); - the reference’s schema registry, folded into the gen manifest rather than kept as a runtime registry;
- a database health check, and factory states.
- Read replicas are a new design, not ported.
Consequences
- Client bundles import model shapes without the ORM.
- Generated schemas mean ORM changes show up in gen output, not in hand-written mappings.
- A large feature surface to port and test. Each feature lands with its tests.
Enforcement
Planned:packages/tooling/oxlint/src/boundaries.jsonc bans @mikro-orm/* imports outside @stackra/database, and gen’s
--check covers emitted schemas. Nothing checks this today.
Supersedes and sources
Supersedes: none. Answers the open question of Round 9 G1. Sources: recommendation by the coordinating agent, 2026-10-19; accepted by the owner with the five additions (Round 11 O1). Reference: nestjs-orm (/Users/akouta/Downloads/2026/archive/monorepo-main/packages/infra/orm, informational).