snapshot migration pre-phase 6, stable
This commit is contained in:
+361
-3
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user