const { SlashCommandBuilder, MessageFlags, EmbedBuilder } = require("discord.js"); const { reconcileUserAchievements, reconcileAllAchievements, auditProfileData } = require( "../../utils/profileMaintenance" ); const { requireAdminAccess } = require( "../../utils/permissions" ); module.exports = { data: new SlashCommandBuilder() .setName( "profileadmin" ) .setDescription( "Administrative profile maintenance tools" ) .addSubcommand( subcommand => subcommand .setName( "reconcile" ) .setDescription( "Backfill database-trackable achievements" ) .addUserOption( option => option .setName( "user" ) .setDescription( "Only reconcile this user; omit for everyone" ) ) .addBooleanOption( option => option .setName( "dry-run" ) .setDescription( "Show what would change without writing it" ) ) ) .addSubcommand( subcommand => subcommand .setName( "audit" ) .setDescription( "Audit stored profile statistics for inconsistencies" ) ), async execute( interaction ) { /* * Allows: * * - Discord Administrators * - BOT_AUTHOR_ID from .env */ if ( !await requireAdminAccess( interaction ) ) { return; } const subcommand = interaction.options.getSubcommand(); await interaction.deferReply({ flags: MessageFlags.Ephemeral }); if ( subcommand === "reconcile" ) { const user = interaction.options.getUser( "user" ); const dryRun = interaction.options.getBoolean( "dry-run" ) ?? false; if (user) { const result = await reconcileUserAchievements({ guildId: interaction.guildId, userId: user.id, dryRun }); return interaction.editReply({ embeds: [ new EmbedBuilder() .setTitle( "🛠️ Profile Reconciliation" ) .setDescription( `${dryRun ? "Dry run for" : "Reconciled"} ${user}.` ) .addFields( { name: "New unlocks", value: `**${result.unlocked}**`, inline: true }, { name: "Definitions checked", value: `**${result.checked}**`, inline: true }, { name: "Event-only skipped", value: `**${result.skippedEventOnly}**`, inline: true } ) ] }); } const summary = await reconcileAllAchievements({ guildId: interaction.guildId, dryRun }); return interaction.editReply({ embeds: [ new EmbedBuilder() .setTitle( "🛠️ Profile Reconciliation" ) .setDescription( `${dryRun ? "Dry run completed" : "Reconciliation completed"} for stored profile users.` ) .addFields( { name: "Users", value: `**${summary.users}**`, inline: true }, { name: "New unlocks", value: `**${summary.unlocked}**`, inline: true }, { name: "Event-only checks skipped", value: `**${summary.skippedEventOnly}**`, inline: true } ) ] }); } const audit = await auditProfileData( interaction.guildId ); const issuePreview = audit.issues .slice( 0, 10 ) .join( "\n" ); return interaction.editReply({ embeds: [ new EmbedBuilder() .setTitle( "🔎 Profile Data Audit" ) .addFields( { name: "Stats documents", value: `**${audit.statDocuments}**`, inline: true }, { name: "Achievement documents", value: `**${audit.achievementDocuments}**`, inline: true }, { name: "Active achievements", value: `**${audit.activeAchievements}**`, inline: true }, { name: "Global badges", value: `**${audit.badgeDocuments}** (${audit.claimedBadges} claimed)`, inline: true }, { name: "Orphan achievement docs", value: `**${audit.orphanAchievementDocs}**`, inline: true }, { name: "Issues", value: `**${audit.issueCount}**`, inline: true } ) .setDescription( issuePreview ? `First issues:\n${issuePreview}` : "No structural inconsistencies found." ) ] }); } };