Saltar al contenido principal

Database Module

Path: apps/backend/src/database/ Type: Global infrastructure module (no endpoints)

Purpose

Provides a singleton Kysely<DB> instance to the entire backend via the DATABASE injection token. This is the only entry point for database access — every repository in the system depends on it.

Architecture

database/
├── database.module.ts # @Global() NestJS module with graceful shutdown
└── infrastructure/
└── database.providers.ts # DATABASE token, KyselyDatabase type, factory provider

How It Works

  1. databaseProvider is a NestJS factory provider that reads DATABASE_URL from ConfigService
  2. It calls getDatabaseInstance() from packages/backend/database/ which creates a pg.Pool + Kysely<DB> instance
  3. The instance is cached by connection string to prevent duplicate pools
  4. DatabaseModule is @Global() — imported once in AppModule, available everywhere
  5. On shutdown, onModuleDestroy() calls db.destroy() to drain the connection pool

Injection Pattern

import { DATABASE, type KyselyDatabase } from "@/database/infrastructure/database.providers";

@Injectable()
export class MyRepository {
constructor(@Inject(DATABASE) private readonly database: KyselyDatabase) {}
}

Connection Pool Configuration

Pool behavior is controlled via environment variables:

VariableDefaultDescription
DB_POOL_MAX3Max connections per instance
DB_POOL_MIN0Min idle connections
DB_POOL_IDLE_TIMEOUT300000Idle timeout (ms)
DB_POOL_CONNECTION_TIMEOUT10000Acquire timeout (ms)
DB_POOL_KEEP_ALIVE_DELAY5000Keep-alive ping interval (ms)
DB_STATEMENT_TIMEOUTQuery timeout (ms)
DB_POOL_MONITORINGEnable pool health logging in production

See connection-pool-management.md for capacity planning across environments.

Design Decisions

  • @Global() to avoid importing DatabaseModule in every feature module (115+ modules)
  • Connection string cache as defensive programming against duplicate pool creation in edge cases
  • Graceful shutdown via OnModuleDestroy to properly drain connections on restart/deploy
  • No domain/application layers — this is pure infrastructure, not a feature module