PrimebrickPrimebrick
  • Primebrick.dev
  • GitHub
  • Documentation
  • Services
  • Libraries
  • API Catalog
Resources
  • Landing Page
  • API Catalog
  • GitHub
PrimebrickPrimebrick

© 2026 Primebrick. MIT License.

github
DAL Library
SDK Library
    Architecture: Ports & AdaptersBuild, Tooling & CI/CDCI/CD & NPM PublishingConfiguration ManagementCore ModulesDatabase MigrationsEnvironment ValidationGetting StartedGlossaryHTTP Server & Health ChecksLifecycle & Graceful ShutdownModule Test PatternsNATS Messaging ClientOverviewService Registration & HeartbeatTest Infrastructure & ConfigurationTestingTypeScript Build ConfigurationREADME
powered by Zudoku
SDK Library

Configuration Management

Configuration Management

Relevant source files

The following files were used as context for generating this wiki page:

  • src/config/tests/config-loader.test.ts
  • src/config/config-loader.ts
  • src/config/iconfig-entity.ts
  • src/ports/config-repository-port.ts

The Config module provides a standardized, dictionary-style configuration system designed to be shared across all microservices. It implements a Load-Cache-Get pattern that ensures high performance by avoiding database hits on the hot path while maintaining a DB-agnostic architecture through the use of ports.

Data Shape: IConfigEntity

Configuration data is modeled as a simple key-value pair system. Each configuration entry is represented by the IConfigEntity interface, which mirrors a standard configuration table structure where every row represents a single setting.

PropertyTypeDescription
keystringThe unique identifier for the setting (e.g., "brevo_api_key").
valuestring | nullThe raw text value. null indicates the key exists but is not yet set.
label_keystring (optional)i18n key for UI display titles.
description_keystring (optional)i18n key for UI display descriptions.

Sources: src/config/iconfig-entity.ts:10-19

The ConfigRepositoryPort Contract

To maintain the SDK's database-agnostic philosophy, the ConfigLoader does not interact with a database directly. Instead, it depends on the ConfigRepositoryPort. Consuming microservices must provide an adapter that implements this interface using their specific Data Access Layer (DAL) or raw SQL.

Code
classDiagram class ConfigRepositoryPort { <<interface>> +findAll() Promise~Array~ } class ConfigLoader { -repo: ConfigRepositoryPort -cache: Map~string, string | null~ +load() Promise +get(key) string } ConfigLoader --> ConfigRepositoryPort : uses

Sources: src/ports/config-repository-port.ts:8-14, src/config/config-loader.ts:8-18

ConfigLoader Lifecycle

The ConfigLoader manages an in-memory cache to ensure that once configuration is loaded, access is instantaneous.

1. Load & Cache

The load() method must be called once at application startup src/config/config-loader.ts:24-31. It fetches all rows via the ConfigRepositoryPort.findAll() method and populates an internal Map src/config/config-loader.ts:25-29.

2. Access (Get)

Once loaded, values are retrieved from the Map. If get() or require() is called before load(), the loader throws an error to prevent inconsistent application states src/config/config-loader.ts:38-40.

3. Invalidation

The invalidate() method clears the internal cache src/config/config-loader.ts:86-88. This forces the next call to load() to perform a fresh fetch from the underlying data source src/config/config-loader.ts:13-13.

Data Flow Diagram

Code
sequenceDiagram participant App as "Microservice Entry" participant CL as "ConfigLoader" participant Port as "ConfigRepositoryPort (Adapter)" participant DB as "Database (Config Table)" App->>CL: load() CL->>Port: findAll() Port->>DB: SELECT key, value FROM config DB-->>Port: rows[] Port-->>CL: Array<{key, value}> CL->>CL: Populate Map (Cache) Note over App, CL: Application Hot Path App->>CL: get("port") CL-->>App: "8080" (from Cache) Note over App, CL: Cache Invalidation App->>CL: invalidate() CL->>CL: cache = null App->>CL: load() CL->>Port: findAll() (Refreshes Cache)

Sources: src/config/config-loader.ts:15-89, src/config/tests/config-loader.test.ts:22-81

Typed Accessors and Error Handling

Since the database stores all values as TEXT src/config/iconfig-entity.ts:13-13, the ConfigLoader provides utilities for type conversion and mandatory field validation.

Accessor Methods

MethodReturn TypeBehavior on Missing/Null
get(key)string | nullReturns null. src/config/config-loader.ts:37-42
require(key)stringThrows Error. src/config/config-loader.ts:47-53
getTyped(key, conv)T | nullReturns null. src/config/config-loader.ts:59-63
requireTyped(key, conv)TThrows Error. src/config/config-loader.ts:68-71

Type Conversion

The getTyped and requireTyped methods accept a converter function (e.g., Number, Boolean, or a custom parser) to transform the raw string into the desired runtime type src/config/config-loader.ts:59-71.

Error Handling

The loader enforces strict presence for "required" keys. If require() or requireTyped() encounters a null or empty string, it throws an error: Missing required config key: <key> src/config/config-loader.ts:49-51.

Sources: src/config/config-loader.ts:47-71, src/config/tests/config-loader.test.ts:42-59


Last modified on July 13, 2026
CI/CD & NPM PublishingCore Modules
On this page
  • Data Shape: IConfigEntity
  • The ConfigRepositoryPort Contract
  • ConfigLoader Lifecycle
    • 1. Load & Cache
    • 2. Access (Get)
    • 3. Invalidation
    • Data Flow Diagram
  • Typed Accessors and Error Handling
    • Accessor Methods
    • Type Conversion
    • Error Handling