snapshot migration pre-phase 6, stable

This commit is contained in:
DeSqBlocki
2026-08-27 21:14:27 +02:00
parent 14a059034c
commit e3dbb11e12
7 changed files with 1089 additions and 43 deletions
+361 -3
View File
@@ -6,10 +6,18 @@ const {
} = require("./profileSystem");
const {
getUnixTime
getUnixTime,
changeCookies
} = require("./cookieEconomy");
const DEFAULT_MAINTENANCE_REWARD_ID =
"maintenance_2026_08_27";
const DEFAULT_MAINTENANCE_REWARD_AMOUNT =
5000;
function getActiveDefinitions(
achievementConfig
) {
@@ -356,6 +364,292 @@ async function reconcileAllAchievements({
}
async function grantMaintenanceReward({
guildId,
rewardId =
DEFAULT_MAINTENANCE_REWARD_ID,
amount =
DEFAULT_MAINTENANCE_REWARD_AMOUNT,
dryRun = false
}) {
if (!guildId) {
throw new Error(
"guildId is required."
);
}
const normalizedRewardId =
String(
rewardId ?? ""
).trim();
if (!normalizedRewardId) {
throw new Error(
"rewardId is required."
);
}
const normalizedAmount =
Number(
amount
);
if (
!Number.isSafeInteger(
normalizedAmount
)
||
normalizedAmount <= 0
) {
throw new Error(
"Maintenance reward amount must be a positive safe integer."
);
}
const {
stats
} =
getProfileCollections();
const userIds =
await stats.distinct(
"userId",
{
guildId
}
);
const summary = {
guildId,
rewardId:
normalizedRewardId,
amount:
normalizedAmount,
users:
userIds.length,
eligible:
0,
granted:
0,
alreadyClaimed:
0,
failed:
0,
dryRun,
results: []
};
for (const userId of userIds) {
const existing =
await stats.findOne(
{
userId,
guildId
},
{
projection: {
"maintenance.rewardsClaimed":
1
}
}
);
const rewardsClaimed =
Array.isArray(
existing
?.maintenance
?.rewardsClaimed
)
? existing
.maintenance
.rewardsClaimed
: [];
if (
rewardsClaimed.includes(
normalizedRewardId
)
) {
summary.alreadyClaimed++;
summary.results.push({
userId,
status:
"already_claimed"
});
continue;
}
summary.eligible++;
if (dryRun) {
summary.results.push({
userId,
status:
"would_grant"
});
console.log(
`[ProfileMaintenance] Dry run: would grant ${normalizedAmount} Cookies to ${userId} for ${normalizedRewardId}.`
);
continue;
}
const reservation =
await stats.updateOne(
{
userId,
guildId,
"maintenance.rewardsClaimed": {
$ne:
normalizedRewardId
}
},
{
$addToSet: {
"maintenance.rewardsClaimed":
normalizedRewardId
}
}
);
if (
reservation.modifiedCount !==
1
) {
summary.alreadyClaimed++;
summary.results.push({
userId,
status:
"already_claimed"
});
continue;
}
try {
await changeCookies(
userId,
normalizedAmount
);
summary.granted++;
summary.results.push({
userId,
status:
"granted"
});
console.log(
`[ProfileMaintenance] Granted ${normalizedAmount} Cookies to ${userId} for ${normalizedRewardId}.`
);
}
catch (error) {
await stats.updateOne(
{
userId,
guildId
},
{
$pull: {
"maintenance.rewardsClaimed":
normalizedRewardId
}
}
);
summary.failed++;
summary.results.push({
userId,
status:
"failed",
error:
error?.message ??
String(error)
});
console.error(
`[ProfileMaintenance] Failed to grant ${normalizedAmount} Cookies to ${userId} for ${normalizedRewardId}:`,
error
);
}
}
console.log(
`[ProfileMaintenance] Maintenance reward ${normalizedRewardId}: ${summary.granted} granted, ${summary.alreadyClaimed} already claimed, ${summary.failed} failed, ${summary.users} stored profile user(s) checked.`
);
return summary;
}
async function getMaintenanceRewardStatus({
guildId,
rewardId =
DEFAULT_MAINTENANCE_REWARD_ID
}) {
if (!guildId) {
throw new Error(
"guildId is required."
);
}
const normalizedRewardId =
String(
rewardId ?? ""
).trim();
if (!normalizedRewardId) {
throw new Error(
"rewardId is required."
);
}
const {
stats
} =
getProfileCollections();
const [
users,
claimed
] =
await Promise.all([
stats.countDocuments({
guildId
}),
stats.countDocuments({
guildId,
"maintenance.rewardsClaimed":
normalizedRewardId
})
]);
return {
guildId,
rewardId:
normalizedRewardId,
amount:
DEFAULT_MAINTENANCE_REWARD_AMOUNT,
users,
claimed,
remaining:
Math.max(
0,
users - claimed
)
};
}
async function auditProfileData(
guildId
) {
@@ -783,6 +1077,65 @@ async function auditProfileData(
}
/*
* ----------------------------------------------------
* MAINTENANCE REWARDS
* ----------------------------------------------------
*/
const rewardsClaimed =
document
.maintenance
?.rewardsClaimed;
if (
rewardsClaimed !==
undefined
&&
!Array.isArray(
rewardsClaimed
)
) {
issues.push(
`${document.userId}: maintenance.rewardsClaimed is not an array.`
);
}
else if (
Array.isArray(
rewardsClaimed
)
) {
const uniqueRewards =
new Set(
rewardsClaimed
);
if (
uniqueRewards.size !==
rewardsClaimed.length
) {
issues.push(
`${document.userId}: maintenance.rewardsClaimed contains duplicate reward IDs.`
);
}
if (
rewardsClaimed.some(
rewardId =>
typeof rewardId !==
"string"
||
!rewardId.trim()
)
) {
issues.push(
`${document.userId}: maintenance.rewardsClaimed contains an invalid reward ID.`
);
}
}
/*
* ----------------------------------------------------
* SCHEMA VERSION
@@ -1407,5 +1760,10 @@ function isValidWeekKey(
module.exports = {
reconcileUserAchievements,
reconcileAllAchievements,
auditProfileData
};
grantMaintenanceReward,
getMaintenanceRewardStatus,
auditProfileData,
DEFAULT_MAINTENANCE_REWARD_ID,
DEFAULT_MAINTENANCE_REWARD_AMOUNT
};