Files
ShaiBot/commands/applications/profileAdmin.js
T
2026-08-23 00:43:43 +02:00

264 lines
8.9 KiB
JavaScript

const {
SlashCommandBuilder,
PermissionFlagsBits,
MessageFlags,
EmbedBuilder
} = require("discord.js");
const {
reconcileUserAchievements,
reconcileAllAchievements,
auditProfileData
} = require(
"../../utils/profileMaintenance"
);
module.exports = {
data:
new SlashCommandBuilder()
.setName(
"profileadmin"
)
.setDescription(
"Administrative profile maintenance tools"
)
.setDefaultMemberPermissions(
PermissionFlagsBits.Administrator
)
.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
) {
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."
)
]
});
}
};