add: more commits

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-03 21:40:24 +08:00
parent 1d12f04967
commit a572c1e25f
17 changed files with 476 additions and 302 deletions
+11 -12
View File
@@ -28,7 +28,7 @@ const mdl_UserTiers = require('../../models/tiers/user_tiers.mdl');
const mdl_TierPlans = require('../../models/tiers/tier_plans.mdl');
const UserNotification = require('../../models/notifications/user_notification.mdl');
const CronNotificationSetting = require('../../models/notifications/cron_notification_setting.mdl');
const { NOTIFICATION_REGISTRY } = require('../../data/notifications.data');
const { getNotificationTemplate, renderNotificationContent } = require('../../services/notificationTemplate.service');
require('../../models/tiers/tier.associations');
@@ -73,18 +73,17 @@ async function run() {
// Status flip above always happens — only this step is skippable via settings.
const settings = await CronNotificationSetting.findOne({ where: { job_name: 'expireUserTiers' } });
if (!settings || settings.enabled) {
const notifications = expired.map((t) =>
NOTIFICATION_REGISTRY.tier_expired.build({
tier: t.tier,
label: t.plan?.label ?? null,
planId: t.plan?.plan_id ?? null,
})
).map((payload, i) => ({
user_id: expired[i].user_id,
...payload,
}));
try {
const template = await getNotificationTemplate('tier_expired');
const notifications = expired.map((t) => ({
user_id: t.user_id,
...renderNotificationContent(template, {
tier: t.tier,
label: t.plan?.label ?? null,
planId: t.plan?.plan_id ?? null,
}),
}));
await UserNotification.bulkCreate(notifications, { ignoreDuplicates: true });
} catch (err) {
console.error('[CRON][EXPIRE TIERS] Notification bulkCreate failed:', err);
+6 -2
View File
@@ -32,7 +32,7 @@ const PendingCertificate = require('../../models/courses/pending_certificate.mdl
const mdl_Achievements = require('../../models/users/achievements.mdl');
const UserNotification = require('../../models/notifications/user_notification.mdl');
const CronNotificationSetting = require('../../models/notifications/cron_notification_setting.mdl');
const { NOTIFICATION_REGISTRY } = require('../../data/notifications.data');
const { getNotificationTemplate, renderNotificationContent } = require('../../services/notificationTemplate.service');
const { ensureCertificateRecord } = require('../../services/certificate-record.service');
async function run() {
@@ -59,6 +59,10 @@ async function run() {
console.log(`[CRON][ISSUE CERTS] Processing ${rows.length} pending certificate(s).`);
// Fetched once outside the loop — content differs per row (courseTitle),
// but there's no need to re-query the template for every row.
const certificateTemplate = notificationsEnabled ? await getNotificationTemplate('certificate_issued') : null;
for (const row of rows) {
const { pending_id, user_id, course_uuid, course_title } = row;
const achKey = `course_completed_${course_uuid}`;
@@ -87,7 +91,7 @@ async function run() {
if (notificationsEnabled) {
await UserNotification.create({
user_id,
...NOTIFICATION_REGISTRY.certificate_issued.build({
...renderNotificationContent(certificateTemplate, {
courseTitle: course_title ?? '',
courseUuid: course_uuid,
}),
+2 -2
View File
@@ -26,7 +26,7 @@ const { Op } = require('sequelize');
const { Task } = require('../../models/task/task.mdl');
const AdminNotification = require('../../models/notifications/admin_notification.mdl');
const CronNotificationSetting = require('../../models/notifications/cron_notification_setting.mdl');
const { NOTIFICATION_REGISTRY } = require('../../data/notifications.data');
const { renderNotification } = require('../../services/notificationTemplate.service');
// ─── The actual sweep ────────────────────────────────────────────────────────
async function run() {
@@ -59,7 +59,7 @@ async function run() {
if (settings && !settings.enabled) return;
await AdminNotification.create(
NOTIFICATION_REGISTRY.task_overdue.build({ count: affectedCount })
await renderNotification({ type: 'task_overdue', data: { count: affectedCount } })
);
} catch (err) {
console.error('[CRON][TASK OVERDUE] Failed to insert admin notification:', err);
+2 -2
View File
@@ -25,7 +25,7 @@ const sequelize = require('../../config/db.config');
const { Task } = require('../../models/task/task.mdl');
const UserNotification = require('../../models/notifications/user_notification.mdl');
const CronNotificationSetting = require('../../models/notifications/cron_notification_setting.mdl');
const { NOTIFICATION_REGISTRY } = require('../../data/notifications.data');
const { renderNotification } = require('../../services/notificationTemplate.service');
const WINDOW_MS = 65 * 60 * 1000; // 65-minute lookback
@@ -71,7 +71,7 @@ async function run() {
const count = recentlyOverdue.length;
const now = new Date();
const notify = NOTIFICATION_REGISTRY.user_task_overdue.build({ count, task_list_ids: taskListIds });
const notify = await renderNotification({ type: 'user_task_overdue', data: { count, task_list_ids: taskListIds } });
await UserNotification.bulkCreate(
affectedUsers.map(({ user_id }) => ({