Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Open and close external connections via lifecycle hooks
Own the DB/pool connection lifecycle in a dedicated provider using onModuleInit/onModuleDestroy so resources are released gracefully on shutdown.
Bad example
| 1 | // module file — pool created inline, never closed |
| 2 | const pool = new Pool({ connectionString: process.env.DB_URL }); |
| 3 | const db = drizzle(pool, { schema }); |
| 4 |
|
| 5 | @Module({ |
| 6 | providers: [{ provide: DB_CONNECTION, useValue: db }], |
| 7 | }) |
| 8 | export class DataModule {} |
Explanation (EN)
The pool is created as a side effect and never closed. On shutdown connections leak, and the wiring is buried in the module definition.
Objašnjenje (HR)
Pool se stvara kao nuspojava i nikad se ne zatvara. Pri gasenju veze cure, a logika je zakopana u definiciji modula.
Good example
| 1 | @Injectable() |
| 2 | export class DbConnectionProvider implements OnModuleInit, OnModuleDestroy { |
| 3 | private pool!: Pool; |
| 4 | db!: NodePgDatabase<typeof schema>; |
| 5 |
|
| 6 | onModuleInit() { |
| 7 | this.pool = new Pool({ connectionString: process.env.DB_URL }); |
| 8 | this.db = drizzle(this.pool, { schema }); |
| 9 | } |
| 10 |
|
| 11 | async onModuleDestroy() { |
| 12 | await this.pool.end(); // graceful close |
| 13 | } |
| 14 | } |
Explanation (EN)
Connection setup and teardown live in one provider tied to the framework lifecycle, so the pool is closed cleanly when the app stops.
Objašnjenje (HR)
Uspostava i gasenje veze zive u jednom provideru vezanom uz zivotni ciklus okvira, pa se pool uredno zatvara kad se aplikacija zaustavi.
Notes (EN)
Applies to any external resource with open/close semantics: DB pools, message-queue clients, websocket connections, file handles.
Bilješke (HR)
Vrijedi za bilo koji vanjski resurs s open/close semantikom: DB poolovi, klijenti redova poruka, websocket veze, file handleovi.