feature flags
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { loadFeatureConfig } from '../../config/feature-loader';
|
||||
import { FlattenedFeatures } from '../../config/feature-types';
|
||||
|
||||
export type OperationalMode = 'normal' | 'maintenance' | 'test';
|
||||
export type FeatureState = 'enabled' | 'disabled' | 'coming_soon' | 'hidden';
|
||||
@@ -72,24 +74,18 @@ export class PolicyService {
|
||||
};
|
||||
}
|
||||
|
||||
const anyEnvConfigured =
|
||||
Boolean(process.env.GRIDPILOT_OPERATIONAL_MODE) ||
|
||||
Boolean(process.env.GRIDPILOT_FEATURES_JSON) ||
|
||||
Boolean(process.env.GRIDPILOT_MAINTENANCE_ALLOW_VIEW) ||
|
||||
Boolean(process.env.GRIDPILOT_MAINTENANCE_ALLOW_MUTATE);
|
||||
|
||||
const raw: RawPolicySnapshot = {};
|
||||
// Load from TypeScript config file
|
||||
const configResult = await loadFeatureConfig();
|
||||
const raw: RawPolicySnapshot = {
|
||||
capabilities: convertFlattenedToCapabilities(configResult.features),
|
||||
};
|
||||
|
||||
// Include other env vars if set
|
||||
const operationalMode = process.env.GRIDPILOT_OPERATIONAL_MODE;
|
||||
if (operationalMode) {
|
||||
raw.operationalMode = operationalMode;
|
||||
}
|
||||
|
||||
const capabilities = parseFeaturesJson(process.env.GRIDPILOT_FEATURES_JSON);
|
||||
if (capabilities) {
|
||||
raw.capabilities = capabilities;
|
||||
}
|
||||
|
||||
const maintenanceAllowView = parseCsvList(process.env.GRIDPILOT_MAINTENANCE_ALLOW_VIEW);
|
||||
const maintenanceAllowMutate = parseCsvList(process.env.GRIDPILOT_MAINTENANCE_ALLOW_MUTATE);
|
||||
|
||||
@@ -102,7 +98,7 @@ export class PolicyService {
|
||||
|
||||
return {
|
||||
raw,
|
||||
loadedFrom: anyEnvConfigured ? 'env' : 'defaults',
|
||||
loadedFrom: configResult.loadedFrom === 'config-file' ? 'file' : 'defaults',
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -191,16 +187,6 @@ function parseFeatureState(value: unknown): FeatureState | null {
|
||||
}
|
||||
}
|
||||
|
||||
function parseFeaturesJson(raw: string | undefined): unknown {
|
||||
if (!raw) {
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(raw) as unknown;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function parseCsvList(raw: string | undefined): readonly string[] | undefined {
|
||||
if (!raw) {
|
||||
@@ -226,4 +212,11 @@ function normalizeStringArray(value: unknown): readonly string[] {
|
||||
.filter(Boolean);
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
// NEW: Helper function to convert flattened features to capabilities
|
||||
function convertFlattenedToCapabilities(
|
||||
flattened: FlattenedFeatures
|
||||
): Record<string, FeatureState> {
|
||||
return flattened as Record<string, FeatureState>;
|
||||
}
|
||||
Reference in New Issue
Block a user