revised: payment strategy

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-31 02:27:05 +08:00
parent 2e5fd10b38
commit aad298bc54
4 changed files with 208 additions and 72 deletions
+23 -13
View File
@@ -383,10 +383,12 @@ exports.grantTier = async (req, res) => {
if (!plan || !plan.is_active) return R.error(res, 'Plan not found or inactive.', 404);
const tier = plan.tier;
await mdl_UserTiers.update(
{ status: 'expired' },
{ where: { user_id, status: 'active' } }
);
const existingActive = await mdl_UserTiers.findOne({
where: { user_id, tier, status: 'active' },
});
if (existingActive) {
return R.error(res, `User already has an active ${tier} subscription until ${existingActive.expires_at}.`, 409);
}
const startsAt = new Date();
const expiresAt = new Date(startsAt.getTime() + plan.duration_days * 86400000);
@@ -419,18 +421,26 @@ exports.revokeTier = async (req, res) => {
revoked_at: new Date(),
});
await mdl_UserTiers.create({
user_id: tierRecord.user_id,
tier: 'free',
status: 'active',
starts_at: new Date(),
expires_at: null,
granted_by: req.user.user_id,
notes: 'Auto-downgrade after revoke.',
// Only fall back to free if the user has no other concurrently active tier —
// revoking one subscription shouldn't drop them below a tier they still hold.
const remainingActive = await mdl_UserTiers.count({
where: { user_id: tierRecord.user_id, status: 'active' },
});
if (remainingActive === 0) {
await mdl_UserTiers.create({
user_id: tierRecord.user_id,
tier: 'free',
status: 'active',
starts_at: new Date(),
expires_at: null,
granted_by: req.user.user_id,
notes: 'Auto-downgrade after revoke.',
});
}
logActivity(req.user.user_id, 'revoke_tier', { entityType: 'tier', details: { user_id: tierRecord.user_id, tier: tierRecord.tier } });
return R.success(res, 'Tier revoked. User downgraded to free.');
return R.success(res, remainingActive === 0 ? 'Tier revoked. User downgraded to free.' : 'Tier revoked.');
} catch (err) {
console.error('[ADMIN][REVOKE TIER]', err);
return R.error(res, 'Could not revoke tier.', 500);