$npx -y skills add agents-inc/skills --skill api-database-typeormDecorator-based ORM for TypeScript with Active Record and Data Mapper patterns
| 1 | # Database with TypeORM |
| 2 | |
| 3 | > **Quick Guide:** Use TypeORM for decorator-based database access with full TypeScript support. Schema defined via entity classes with `@Entity`, `@Column`, `@PrimaryGeneratedColumn`. Use Data Mapper pattern (repositories) over Active Record for non-trivial apps. **Never use `synchronize: true` in production** - use migrations. Prefer `insert()`/`update()` over `save()` when you know the operation type - `save()` always executes a SELECT first. Use `QueryRunner` transactions for full control. Eager relations only work with `find*` methods, not QueryBuilder. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | <critical_requirements> |
| 8 | |
| 9 | ## CRITICAL: Before Using This Skill |
| 10 | |
| 11 | > **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants) |
| 12 | |
| 13 | **(You MUST NEVER use `synchronize: true` in production - it can drop columns and lose data when entities change)** |
| 14 | |
| 15 | **(You MUST use `insert()`/`update()` instead of `save()` when the operation type is known - `save()` always runs an extra SELECT query)** |
| 16 | |
| 17 | **(You MUST use the provided transaction `manager` parameter or `queryRunner.manager` inside transactions - NEVER use the global entity manager or repository)** |
| 18 | |
| 19 | **(You MUST define relations with explicit `@JoinColumn()` on the owning side of `@OneToOne` and optionally `@ManyToOne`, and `@JoinTable()` on one side of `@ManyToMany`)** |
| 20 | |
| 21 | </critical_requirements> |
| 22 | |
| 23 | --- |
| 24 | |
| 25 | **Auto-detection:** typeorm, TypeORM, DataSource, @Entity, @Column, @PrimaryGeneratedColumn, @ManyToOne, @OneToMany, @ManyToMany, createQueryBuilder, getRepository, EntityManager, QueryRunner, migration:generate, migration:run |
| 26 | |
| 27 | **When to use:** |
| 28 | |
| 29 | - Decorator-based entity definitions with TypeScript |
| 30 | - Applications requiring both Active Record and Data Mapper patterns |
| 31 | - Complex queries needing QueryBuilder with joins and subqueries |
| 32 | - Projects where class-based ORM feels natural (especially with DI-based frameworks) |
| 33 | |
| 34 | **When NOT to use:** |
| 35 | |
| 36 | - Schema-first workflows (consider schema-first ORMs instead) |
| 37 | - Needing fully type-safe queries without runtime decorators (consider lighter ORMs) |
| 38 | - Edge/serverless with minimal cold start (decorator metadata adds weight) |
| 39 | - Projects avoiding `reflect-metadata` and `experimentalDecorators` |
| 40 | |
| 41 | **Key patterns covered:** |
| 42 | |
| 43 | - DataSource configuration and entity registration |
| 44 | - Entity definitions with decorators and column types |
| 45 | - Relations (OneToOne, OneToMany, ManyToOne, ManyToMany) |
| 46 | - Repository CRUD and QueryBuilder |
| 47 | - Migrations (generate, run, revert) |
| 48 | - Transactions (EntityManager callback, QueryRunner manual) |
| 49 | - `save()` vs `insert()`/`update()` performance |
| 50 | |
| 51 | **Detailed Resources:** |
| 52 | |
| 53 | - [examples/core.md](examples/core.md) - DataSource setup, entities, CRUD, repository patterns |
| 54 | - [examples/relations.md](examples/relations.md) - All relation types, eager/lazy loading, cascades |
| 55 | - [examples/query-builder.md](examples/query-builder.md) - Joins, subqueries, pagination, raw queries |
| 56 | - [examples/migrations.md](examples/migrations.md) - Generate, run, revert, CLI configuration |
| 57 | - [examples/transactions.md](examples/transactions.md) - EntityManager, QueryRunner, isolation levels |
| 58 | - [examples/advanced.md](examples/advanced.md) - Subscribers, listeners, tree entities, embedded entities |
| 59 | - [reference.md](reference.md) - Decision frameworks, anti-patterns, performance, checklists |
| 60 | |
| 61 | --- |
| 62 | |
| 63 | <philosophy> |
| 64 | |
| 65 | ## Philosophy |
| 66 | |
| 67 | **TypeORM** uses TypeScript decorators to define database entities as classes. It supports both the Active Record and Data Mapper patterns, giving teams flexibility in how they structure data access. |
| 68 | |
| 69 | **Core principles:** |
| 70 | |
| 71 | 1. **Decorator-based schema** - Entities are classes decorated with `@Entity`, `@Column`, etc. |
| 72 | 2. **Pattern flexibility** - Active Record for simplicity, Data Mapper for separation of concerns |
| 73 | 3. **QueryBuilder power** - SQL-like fluent API for complex queries beyond simple `find*` |
| 74 | 4. **Migration-driven** - Schema changes through versioned migration files, never auto-sync in production |
| 75 | |
| 76 | **Active Record vs Data Mapper:** |
| 77 | |
| 78 | - **Active Record**: Entities extend `BaseEntity`, call `User.find()`, `user.save()` directly. Good for small apps and rapid prototyping. |
| 79 | - **Data Mapper**: Entities are plain classes, repositories handle persistence (`userRepo.find()`, `userRepo.save()`). Better for complex apps, testing, and separation of concerns. |
| 80 | |
| 81 | **Recommendation:** Use Data Mapper for any non-trivial application. Active Record couples domain logic to persistence, making testing and refactoring harder. |
| 82 | |
| 83 | </philosophy> |
| 84 | |
| 85 | --- |
| 86 | |
| 87 | <patterns> |
| 88 | |
| 89 | ## Core Patterns |
| 90 | |
| 91 | ### Pattern 1: DataSource Configuration |
| 92 | |
| 93 | Configure the DataSource as a singleton. Export it for both the application and migration CLI. |
| 94 | |
| 95 | ```typescript |
| 96 | // data-source.ts |
| 97 | import { DataSource } from "typeorm"; |
| 98 | import { User } from "./entities/user.entity"; |
| 99 | import { Post } from "./entities/post.entity"; |
| 100 | |
| 101 | export const AppD |