small changes to UI/UX
This commit is contained in:
@@ -7,7 +7,11 @@ const {
|
||||
const {
|
||||
reconcileUserAchievements,
|
||||
reconcileAllAchievements,
|
||||
auditProfileData
|
||||
grantMaintenanceReward,
|
||||
getMaintenanceRewardStatus,
|
||||
auditProfileData,
|
||||
DEFAULT_MAINTENANCE_REWARD_ID,
|
||||
DEFAULT_MAINTENANCE_REWARD_AMOUNT
|
||||
} = require(
|
||||
"../../utils/profileMaintenance"
|
||||
);
|
||||
@@ -67,6 +71,69 @@ module.exports = {
|
||||
.setDescription(
|
||||
"Audit stored profile statistics for inconsistencies"
|
||||
)
|
||||
)
|
||||
.addSubcommand(
|
||||
subcommand =>
|
||||
subcommand
|
||||
.setName(
|
||||
"maintenance-reward"
|
||||
)
|
||||
.setDescription(
|
||||
"Grant an idempotent maintenance reward to stored profile users"
|
||||
)
|
||||
.addStringOption(
|
||||
option =>
|
||||
option
|
||||
.setName(
|
||||
"reward-id"
|
||||
)
|
||||
.setDescription(
|
||||
`Unique reward ID; defaults to ${DEFAULT_MAINTENANCE_REWARD_ID}`
|
||||
)
|
||||
)
|
||||
.addIntegerOption(
|
||||
option =>
|
||||
option
|
||||
.setName(
|
||||
"amount"
|
||||
)
|
||||
.setDescription(
|
||||
`Cookies per player; defaults to ${DEFAULT_MAINTENANCE_REWARD_AMOUNT}`
|
||||
)
|
||||
.setMinValue(
|
||||
1
|
||||
)
|
||||
)
|
||||
.addBooleanOption(
|
||||
option =>
|
||||
option
|
||||
.setName(
|
||||
"dry-run"
|
||||
)
|
||||
.setDescription(
|
||||
"Preview recipients without granting Cookies"
|
||||
)
|
||||
)
|
||||
)
|
||||
.addSubcommand(
|
||||
subcommand =>
|
||||
subcommand
|
||||
.setName(
|
||||
"maintenance-status"
|
||||
)
|
||||
.setDescription(
|
||||
"Show maintenance reward claim status"
|
||||
)
|
||||
.addStringOption(
|
||||
option =>
|
||||
option
|
||||
.setName(
|
||||
"reward-id"
|
||||
)
|
||||
.setDescription(
|
||||
`Reward ID; defaults to ${DEFAULT_MAINTENANCE_REWARD_ID}`
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
async execute(
|
||||
@@ -98,31 +165,87 @@ module.exports = {
|
||||
});
|
||||
|
||||
|
||||
if (
|
||||
subcommand ===
|
||||
"reconcile"
|
||||
) {
|
||||
const user =
|
||||
interaction.options.getUser(
|
||||
"user"
|
||||
);
|
||||
try {
|
||||
if (
|
||||
subcommand ===
|
||||
"reconcile"
|
||||
) {
|
||||
const user =
|
||||
interaction.options.getUser(
|
||||
"user"
|
||||
);
|
||||
|
||||
|
||||
const dryRun =
|
||||
interaction.options.getBoolean(
|
||||
"dry-run"
|
||||
) ?? false;
|
||||
const dryRun =
|
||||
interaction.options.getBoolean(
|
||||
"dry-run"
|
||||
) ?? false;
|
||||
|
||||
|
||||
if (user) {
|
||||
const result =
|
||||
await reconcileUserAchievements({
|
||||
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,
|
||||
|
||||
userId:
|
||||
user.id,
|
||||
|
||||
dryRun
|
||||
});
|
||||
|
||||
@@ -134,35 +257,35 @@ module.exports = {
|
||||
"🛠️ Profile Reconciliation"
|
||||
)
|
||||
.setDescription(
|
||||
`${dryRun ? "Dry run for" : "Reconciled"} ${user}.`
|
||||
`${dryRun ? "Dry run completed" : "Reconciliation completed"} for stored profile users.`
|
||||
)
|
||||
.addFields(
|
||||
{
|
||||
name:
|
||||
"Users",
|
||||
|
||||
value:
|
||||
`**${summary.users}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"New unlocks",
|
||||
|
||||
value:
|
||||
`**${result.unlocked}**`,
|
||||
`**${summary.unlocked}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Definitions checked",
|
||||
"Event-only checks skipped",
|
||||
|
||||
value:
|
||||
`**${result.checked}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Event-only skipped",
|
||||
|
||||
value:
|
||||
`**${result.skippedEventOnly}**`,
|
||||
`**${summary.skippedEventOnly}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
@@ -173,152 +296,334 @@ module.exports = {
|
||||
}
|
||||
|
||||
|
||||
const summary =
|
||||
await reconcileAllAchievements({
|
||||
guildId:
|
||||
interaction.guildId,
|
||||
if (
|
||||
subcommand ===
|
||||
"maintenance-reward"
|
||||
) {
|
||||
const rewardId =
|
||||
interaction.options.getString(
|
||||
"reward-id"
|
||||
)
|
||||
??
|
||||
DEFAULT_MAINTENANCE_REWARD_ID;
|
||||
|
||||
dryRun
|
||||
|
||||
const amount =
|
||||
interaction.options.getInteger(
|
||||
"amount"
|
||||
)
|
||||
??
|
||||
DEFAULT_MAINTENANCE_REWARD_AMOUNT;
|
||||
|
||||
|
||||
/*
|
||||
* Safer admin default:
|
||||
*
|
||||
* If omitted, maintenance-reward previews
|
||||
* instead of paying immediately.
|
||||
*
|
||||
* Pass dry-run:false explicitly to execute.
|
||||
*/
|
||||
|
||||
const dryRun =
|
||||
interaction.options.getBoolean(
|
||||
"dry-run"
|
||||
)
|
||||
??
|
||||
true;
|
||||
|
||||
|
||||
const summary =
|
||||
await grantMaintenanceReward({
|
||||
guildId:
|
||||
interaction.guildId,
|
||||
|
||||
rewardId,
|
||||
|
||||
amount,
|
||||
|
||||
dryRun
|
||||
});
|
||||
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle(
|
||||
dryRun
|
||||
? "🧪 Maintenance Reward Dry Run"
|
||||
: "🎁 Maintenance Reward"
|
||||
)
|
||||
.setDescription(
|
||||
dryRun
|
||||
? "No Cookies were granted. Run again with `dry-run:false` to execute this reward."
|
||||
: `Maintenance compensation **${rewardId}** has been processed.`
|
||||
)
|
||||
.addFields(
|
||||
{
|
||||
name:
|
||||
"Reward ID",
|
||||
|
||||
value:
|
||||
`\`${summary.rewardId}\``,
|
||||
|
||||
inline:
|
||||
false
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Per player",
|
||||
|
||||
value:
|
||||
`**${summary.amount.toLocaleString()} 🍪**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Stored profiles",
|
||||
|
||||
value:
|
||||
`**${summary.users}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
dryRun
|
||||
? "Would receive"
|
||||
: "Granted",
|
||||
|
||||
value:
|
||||
`**${dryRun ? summary.eligible : summary.granted}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Already claimed",
|
||||
|
||||
value:
|
||||
`**${summary.alreadyClaimed}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Failed",
|
||||
|
||||
value:
|
||||
`**${summary.failed}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
}
|
||||
)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
subcommand ===
|
||||
"maintenance-status"
|
||||
) {
|
||||
const rewardId =
|
||||
interaction.options.getString(
|
||||
"reward-id"
|
||||
)
|
||||
??
|
||||
DEFAULT_MAINTENANCE_REWARD_ID;
|
||||
|
||||
|
||||
const status =
|
||||
await getMaintenanceRewardStatus({
|
||||
guildId:
|
||||
interaction.guildId,
|
||||
|
||||
rewardId
|
||||
});
|
||||
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle(
|
||||
"🎁 Maintenance Reward Status"
|
||||
)
|
||||
.addFields(
|
||||
{
|
||||
name:
|
||||
"Reward ID",
|
||||
|
||||
value:
|
||||
`\`${status.rewardId}\``,
|
||||
|
||||
inline:
|
||||
false
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Default amount",
|
||||
|
||||
value:
|
||||
`**${status.amount.toLocaleString()} 🍪**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Stored profiles",
|
||||
|
||||
value:
|
||||
`**${status.users}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Claimed",
|
||||
|
||||
value:
|
||||
`**${status.claimed}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Remaining",
|
||||
|
||||
value:
|
||||
`**${status.remaining}**`,
|
||||
|
||||
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 Reconciliation"
|
||||
)
|
||||
.setDescription(
|
||||
`${dryRun ? "Dry run completed" : "Reconciliation completed"} for stored profile users.`
|
||||
"🔎 Profile Data Audit"
|
||||
)
|
||||
.addFields(
|
||||
{
|
||||
name:
|
||||
"Users",
|
||||
"Stats documents",
|
||||
|
||||
value:
|
||||
`**${summary.users}**`,
|
||||
`**${audit.statDocuments}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"New unlocks",
|
||||
"Achievement documents",
|
||||
|
||||
value:
|
||||
`**${summary.unlocked}**`,
|
||||
`**${audit.achievementDocuments}**`,
|
||||
|
||||
inline:
|
||||
true
|
||||
},
|
||||
{
|
||||
name:
|
||||
"Event-only checks skipped",
|
||||
"Active achievements",
|
||||
|
||||
value:
|
||||
`**${summary.skippedEventOnly}**`,
|
||||
`**${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."
|
||||
)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const audit =
|
||||
await auditProfileData(
|
||||
interaction.guildId
|
||||
catch (error) {
|
||||
console.error(
|
||||
`[ProfileAdmin] ${subcommand} failed:`,
|
||||
error
|
||||
);
|
||||
|
||||
|
||||
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."
|
||||
)
|
||||
]
|
||||
});
|
||||
return interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle(
|
||||
"❌ Profile Admin Error"
|
||||
)
|
||||
.setDescription(
|
||||
"The maintenance action failed. Check the bot logs for details."
|
||||
)
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user