ConfigService
Hierarchical configuration with location-based inheritance
Overview
ConfigService provides a cascading configuration system that inherits settings through the location hierarchy. Configuration values set at a higher level (e.g., institution) are inherited by all descendants (campuses, buildings, floors, rooms) unless overridden at a more specific level.
import { ConfigService } from '@roomkit/nestjs';Methods
set
Set a configuration value at a specific location node or globally.
async set(locationNodeId: string | null, key: string, value: string): Promise<ConfigEntry>| Parameter | Type | Description |
|---|---|---|
locationNodeId | string | null | Location node ID, or null for a global default |
key | string | Configuration key (must match [a-zA-Z0-9._]+) |
value | string | Configuration value |
// Set a global default
await configService.set(null, 'booking.maxDurationMinutes', '480');
// Override for a specific building
await configService.set('building-science', 'booking.maxDurationMinutes', '240');Throws ConfigKeyInvalidError if the key does not match the pattern [a-zA-Z0-9._]+.
resolve
Resolve a single configuration key for a location node. Walks up the location hierarchy until a value is found.
async resolve(locationNodeId: string, key: string): Promise<ConfigEntry | null>| Parameter | Type | Description |
|---|---|---|
locationNodeId | string | The location node to resolve from |
key | string | The configuration key to look up |
Returns the most specific ConfigEntry found, or null if the key is not set at any level.
// If 'room-a1' has no override, walks up to floor, building, campus, institution, then global
const entry = await configService.resolve('room-a1', 'booking.maxDurationMinutes');
if (entry) {
console.log(`Max duration: ${entry.value} (set at ${entry.locationNodeId ?? 'global'})`);
}resolveMany
Batch-resolve multiple configuration keys for a location node.
async resolveMany(locationNodeId: string, keys: string[]): Promise<Map<string, ConfigEntry | null>>| Parameter | Type | Description |
|---|---|---|
locationNodeId | string | The location node to resolve from |
keys | string[] | Array of configuration keys to look up |
Returns a Map where each key maps to its resolved ConfigEntry or null.
const config = await configService.resolveMany('room-a1', [
'booking.maxDurationMinutes',
'booking.advanceBookingDays',
'booking.requireApproval',
]);
for (const [key, entry] of config) {
console.log(`${key}: ${entry?.value ?? '(not set)'}`);
}getEffectiveConfig
Get the full effective configuration for a location node by merging configs from all ancestors (root to node). More specific values override less specific ones.
async getEffectiveConfig(locationNodeId: string): Promise<Map<string, ConfigEntry>>| Parameter | Type | Description |
|---|---|---|
locationNodeId | string | The location node to compute effective config for |
Returns a Map of all configuration keys and their effective values. When a ConfigEntry has inheritFromParent set to false, that key is locked at that level and parent values are ignored.
const effectiveConfig = await configService.getEffectiveConfig('room-a1');
for (const [key, entry] of effectiveConfig) {
console.log(`${key} = ${entry.value} (from ${entry.locationNodeId ?? 'global'})`);
}ConfigEntry
interface ConfigEntry {
locationNodeId: string | null; // null for global entries
key: string;
value: string;
inheritFromParent: boolean; // false locks the key at this level
createdAt: Date;
updatedAt: Date;
}Setting inheritFromParent to false on a config entry prevents descendant nodes from inheriting overrides from ancestors above that level. This is useful for locking a configuration value at a specific point in the hierarchy.