50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
|
|
import { prisma } from '@/lib/prisma'
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Feature flag keys — used to control progressive rollout of new architecture.
|
||
|
|
* Stored as SystemSetting records with category FEATURE_FLAGS.
|
||
|
|
*/
|
||
|
|
export const FEATURE_FLAGS = {
|
||
|
|
/** Use Competition/Round model instead of Pipeline/Track/Stage */
|
||
|
|
USE_COMPETITION_MODEL: 'feature.useCompetitionModel',
|
||
|
|
} as const
|
||
|
|
|
||
|
|
type FeatureFlagKey = (typeof FEATURE_FLAGS)[keyof typeof FEATURE_FLAGS]
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if a feature flag is enabled (server-side).
|
||
|
|
* Returns false if the flag doesn't exist in the database.
|
||
|
|
*/
|
||
|
|
export async function isFeatureEnabled(flag: FeatureFlagKey): Promise<boolean> {
|
||
|
|
try {
|
||
|
|
const setting = await prisma.systemSettings.findUnique({
|
||
|
|
where: { key: flag },
|
||
|
|
})
|
||
|
|
// Default to true for competition model (legacy Pipeline system removed)
|
||
|
|
if (!setting) return flag === FEATURE_FLAGS.USE_COMPETITION_MODEL ? true : false
|
||
|
|
return setting.value === 'true'
|
||
|
|
} catch {
|
||
|
|
return flag === FEATURE_FLAGS.USE_COMPETITION_MODEL ? true : false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set a feature flag value (server-side, admin only).
|
||
|
|
*/
|
||
|
|
export async function setFeatureFlag(
|
||
|
|
flag: FeatureFlagKey,
|
||
|
|
enabled: boolean,
|
||
|
|
): Promise<void> {
|
||
|
|
await prisma.systemSettings.upsert({
|
||
|
|
where: { key: flag },
|
||
|
|
update: { value: String(enabled) },
|
||
|
|
create: {
|
||
|
|
key: flag,
|
||
|
|
value: String(enabled),
|
||
|
|
type: 'BOOLEAN',
|
||
|
|
category: 'FEATURE_FLAGS',
|
||
|
|
description: `Feature flag: ${flag}`,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|