feat(commands): add beta feature flag support to command system

- Add beta and featureFlag properties to Command interface
- Add beta access check in CommandHandler before command execution
- Show beta feature message to non-whitelisted users
This commit is contained in:
syntaxbullet
2026-02-12 14:45:58 +01:00
parent 67a3aa4b0f
commit 228005322e
2 changed files with 34 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
import { ChatInputCommandInteraction, MessageFlags } from "discord.js"; import { ChatInputCommandInteraction, MessageFlags } from "discord.js";
import { AuroraClient } from "@/lib/BotClient"; import { AuroraClient } from "@/lib/BotClient";
import { userService } from "@shared/modules/user/user.service"; import { userService } from "@shared/modules/user/user.service";
import { featureFlagsService } from "@shared/modules/feature-flags/feature-flags.service";
import { createErrorEmbed } from "@lib/embeds"; import { createErrorEmbed } from "@lib/embeds";
import { logger } from "@shared/lib/logger"; import { logger } from "@shared/lib/logger";
@@ -25,6 +26,37 @@ export class CommandHandler {
return; return;
} }
// Check beta feature access
if (command.beta) {
const flagName = command.featureFlag || interaction.commandName;
let memberRoles: string[] = [];
if (interaction.member && 'roles' in interaction.member) {
const roles = interaction.member.roles;
if (typeof roles === 'object' && 'cache' in roles) {
memberRoles = [...roles.cache.keys()];
} else if (Array.isArray(roles)) {
memberRoles = roles;
}
}
const hasAccess = await featureFlagsService.hasAccess(flagName, {
guildId: interaction.guildId!,
userId: interaction.user.id,
memberRoles,
});
if (!hasAccess) {
const errorEmbed = createErrorEmbed(
"This feature is currently in beta testing and not available to all users. " +
"Stay tuned for the official release!",
"Beta Feature"
);
await interaction.reply({ embeds: [errorEmbed], flags: MessageFlags.Ephemeral });
return;
}
}
// Ensure user exists in database // Ensure user exists in database
try { try {
await userService.getOrCreateUser(interaction.user.id, interaction.user.username); await userService.getOrCreateUser(interaction.user.id, interaction.user.username);

View File

@@ -7,6 +7,8 @@ export interface Command {
execute: (interaction: ChatInputCommandInteraction) => Promise<void> | void; execute: (interaction: ChatInputCommandInteraction) => Promise<void> | void;
autocomplete?: (interaction: AutocompleteInteraction) => Promise<void> | void; autocomplete?: (interaction: AutocompleteInteraction) => Promise<void> | void;
category?: string; category?: string;
beta?: boolean;
featureFlag?: string;
} }
export interface Event<K extends keyof ClientEvents> { export interface Event<K extends keyof ClientEvents> {