ready to test

Testing

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-06-22 10:06:58 +08:00
parent bf48c95467
commit 439bb33f77
189 changed files with 17559 additions and 686 deletions
+119
View File
@@ -0,0 +1,119 @@
/***********************************************************************************************************************************************************************
* File Name: achievements.data.js
* Type of Program: Data
* Description: Static registry of all available achievements (badges and milestones).
* Add a new achievement here — no other code changes needed.
*
* Available keys:
* Badge:
* early_access — registered before Dec 31, 2026
* premium_first_time — first premium tier purchase
* exclusive_first_time — first exclusive tier purchase
* Milestone:
* first_course_completed — completed first course
* courses_completed_5 — completed 5 courses
* courses_completed_10 — completed 10 courses
* perfect_quiz_score — perfect score on a quiz
* profile_completed — filled out full profile
* first_referral — referred a user
*
* Author: Kenneth Obsequio (@lash0000)
* Date Created: Jun. 19, 2026
***********************************************************************************************************************************************************************/
'use strict';
// ─── Early Access cutoff ──────────────────────────────────────────────────────
const EARLY_ACCESS_CUTOFF = new Date('2026-12-31T23:59:59Z');
// ─── Achievement Registry ─────────────────────────────────────────────────────
// To add a new achievement — add an entry here. No other code changes needed.
//
// trigger categories (for documentation only, not enforced):
// auth — registration / login events
// tier — subscription purchase events
// course — course / lesson / quiz events
// profile — profile completion events
// social — referral / community events
const ACHIEVEMENT_REGISTRY = {
// ── Auth ───────────────────────────────────────────────────────────────────
early_access: {
key: 'early_access',
type: 'badge',
label: 'Early Access',
description: 'Registered during the Philproperties beta period (before Dec 31, 2026).',
trigger: 'auth',
},
// ── Tier ───────────────────────────────────────────────────────────────────
premium_first_time: {
key: 'premium_first_time',
type: 'badge',
label: 'Premium Member',
description: 'Purchased a Premium tier plan for the first time.',
trigger: 'tier',
},
exclusive_first_time: {
key: 'exclusive_first_time',
type: 'badge',
label: 'Exclusive Member',
description: 'Purchased an Exclusive tier plan for the first time.',
trigger: 'tier',
},
// ── Course ─────────────────────────────────────────────────────────────────
first_course_completed: {
key: 'first_course_completed',
type: 'milestone',
label: 'First Course Completed',
description: 'Completed your very first course on Philproperties.',
trigger: 'course',
},
courses_completed_5: {
key: 'courses_completed_5',
type: 'milestone',
label: 'Learning Streak',
description: 'Completed 5 courses.',
trigger: 'course',
},
courses_completed_10: {
key: 'courses_completed_10',
type: 'milestone',
label: 'Knowledge Builder',
description: 'Completed 10 courses.',
trigger: 'course',
},
perfect_quiz_score: {
key: 'perfect_quiz_score',
type: 'milestone',
label: 'Perfect Score',
description: 'Achieved a perfect score on a quiz.',
trigger: 'course',
},
// ── Profile ────────────────────────────────────────────────────────────────
profile_completed: {
key: 'profile_completed',
type: 'milestone',
label: 'Profile Complete',
description: 'Filled out all personal profile information.',
trigger: 'profile',
},
// ── Social ─────────────────────────────────────────────────────────────────
first_referral: {
key: 'first_referral',
type: 'milestone',
label: 'Referral Champion',
description: 'Successfully referred a user to Philproperties.',
trigger: 'social',
},
};
module.exports = {
EARLY_ACCESS_CUTOFF,
ACHIEVEMENT_REGISTRY,
};
+47 -74
View File
@@ -1,116 +1,89 @@
const CLOSING = `Regards,\nPhilproperties IT Team\n\nThis is an automated message from STARR System. Please do not reply.`;
const build = (body) => `${body.trim()}\n\n${CLOSING}`;
export const emailTemplates = {
OTP: ({ otp, expiryMinutes = 10 }) => ({
subject: "Email OTP Verification - STARR System",
title: "Email Verification",
body: `
<p>Dear User,</p>
text: build(`
Dear User,
<p>Please use the One-Time Password (OTP) below to verify your email address.
This code is valid for <strong>${expiryMinutes} minutes</strong>.</p>
Please use the One-Time Password (OTP) below to verify your email address. This code is valid for ${expiryMinutes} minutes.
<div style="margin:24px 0;font-size:32px;font-weight:bold;letter-spacing:8px;text-align:center;color:#1d4ed8">
${otp}
</div>
${otp}
<p style="font-size:13px;color:#6b7280">
For security reasons, please do not share this code with anyone.
If you did not request this, please contact the administrator.
</p>
`,
For security reasons, please do not share this code with anyone. If you did not request this, please contact the administrator.
`),
}),
WELCOME: ({ name }) => ({
subject: "Welcome to STARR System",
title: `Welcome Aboard!`,
body: `
<p>Dear ${name},</p>
text: build(`
Dear ${name},
<p>We are pleased to welcome you to the STARR System. Your account has been successfully created and is now ready for use.</p>
We are pleased to welcome you to the STARR System. Your account has been successfully created and is now ready for use.
<p>You may now access your dashboard and begin using the available services.</p>
You may now access your dashboard and begin using the available services.
<p style="margin-top:16px">We look forward to supporting you.</p>
`,
We look forward to supporting you.
`),
}),
PASSWORD_CHANGED: () => ({
subject: "Password Update Confirmation - STARR System",
title: "Password Successfully Updated",
body: `
<p>Dear User,</p>
text: build(`
Dear User,
<p>This is to confirm that your account password has been successfully changed.</p>
This is to confirm that your account password has been successfully changed.
<p>If you did not perform this action, please reset your password immediately or contact support.</p>
If you did not perform this action, please reset your password immediately or contact support.
<p style="margin-top:16px">For your security, we recommend using a strong and unique password.</p>
`,
For your security, we recommend using a strong and unique password.
`),
}),
ADDED_TO_GROUP: ({ groupName }) => ({
subject: "Group Assignment Notification",
title: "Added to Group",
body: `
<p>Dear User,</p>
subject: "Group Assignment Notification - STARR System",
text: build(`
Dear User,
<p>You have been assigned to the group <strong>${groupName}</strong> in the STARR System.</p>
You have been assigned to the group "${groupName}" in the STARR System.
<p>This assignment grants you access to shared resources and collaboration tools within the group.</p>
This assignment grants you access to shared resources and collaboration tools within the group.
<p style="margin-top:16px">Please log in to your account to view group details.</p>
`,
Please log in to your account to view group details.
`),
}),
TASK_ASSIGNED: ({ taskTitle, dueDate }) => ({
subject: "New Task Assignment",
title: "Task Assigned",
body: `
<p>Dear User,</p>
subject: "New Task Assignment - STARR System",
text: build(`
Dear User,
<p>You have been assigned a new task in the STARR System.</p>
You have been assigned a new task in the STARR System.
<div style="margin:16px 0;padding:12px;border:1px solid #e5e7eb;border-radius:6px">
<strong>Task:</strong> ${taskTitle}
</div>
Task: ${taskTitle}
Due Date: ${dueDate}
<p><strong>Due Date:</strong> ${dueDate}</p>
<p style="margin-top:16px">Kindly ensure completion within the specified timeframe.</p>
`,
Kindly ensure completion within the specified timeframe.
`),
}),
ADD_STAFF: ({ name, email, password, expiryHours = 24 }) => ({
subject: "Your Staff Account Has Been Created - STARR System",
title: "Staff Account Created",
body: `
<p>Dear ${name},</p>
text: build(`
Dear ${name},
<p>Your staff account has been successfully created in the STARR System.
Below are your login credentials:</p>
Your staff account has been successfully created in the STARR System. Below are your login credentials:
<div style="margin:24px 0;padding:16px;border:1px solid #e5e7eb;border-radius:6px;background:#f9fafb">
<table style="width:100%;font-size:14px">
<tr>
<td style="padding:6px 0;color:#6b7280;width:100px"><strong>Email</strong></td>
<td style="padding:6px 0">${email}</td>
</tr>
<tr>
<td style="padding:6px 0;color:#6b7280"><strong>Password</strong></td>
<td style="padding:6px 0;font-size:18px;color:#1d4ed8">${password}</td>
</tr>
</table>
</div>
Email: ${email}
Password: ${password}
<p>⚠️ This temporary password is valid for <strong>${expiryHours} hours</strong>.
You will be required to change it upon first login.</p>
This temporary password is valid for ${expiryHours} hours. You will be required to change it upon first login.
<p>If you did not request this account or believe this was created in error,
please contact your administrator immediately to have it deactivated.</p>
If you did not request this account or believe this was created in error, please contact your administrator immediately to have it deactivated.
<p style="margin-top:16px;font-size:13px;color:#6b7280">
For security, please do not share your credentials with anyone.
If you need a new password, contact your administrator.
</p>
`,
For security, please do not share your credentials with anyone. If you need a new password, contact your administrator.
`),
}),
};
};
+182
View File
@@ -0,0 +1,182 @@
/***********************************************************************************************************************************************************************
* File Name: notifications.data.js
* Type of Program: Data
* Description: Central registry of all notification types for both admin and
* client (user) notifications.
*
* Each entry describes one notification type:
* type {string} — stored in the DB 'type' column
* scope {string} — 'admin' | 'user' | 'both'
* trigger {string} — what fires it (cron | event | manual)
* build {function} — takes a data payload, returns the object
* ready to pass to AdminNotification.create()
* or UserNotification.create() / bulkCreate()
*
* To add a new notification type:
* 1. Add an entry in the relevant section below.
* 2. Call NOTIFICATION_REGISTRY.<key>.build(data) at the trigger
* site (controller, cron, service).
* No other changes needed.
*
* Current types:
* Admin : task_overdue
* User : user_task_overdue, achievement, course_unlocked,
* certificate_issued, task_reminder, announcement
*
* Author: Kenneth Obsequio (@lash0000)
* Date Created: Jun. 19, 2026
***********************************************************************************************************************************************************************/
'use strict';
const NOTIFICATION_REGISTRY = {
// ─────────────────────────────────────────────────────────────────────────
// ADMIN notifications (scope: 'admin')
// ─────────────────────────────────────────────────────────────────────────
// ── Task ──────────────────────────────────────────────────────────────────
task_overdue: {
type: 'task_overdue',
scope: 'admin',
trigger: 'cron',
build({ count, task_list_ids = [] }) {
return {
type: 'task_overdue',
title: 'Tasks Overdue',
message: `${count} task${count === 1 ? ' was' : 's were'} automatically marked as overdue.`,
data: { count, task_list_ids },
};
},
},
// ── User Registration ─────────────────────────────────────────────────────
user_registration: {
type: 'user_registration',
scope: 'admin',
trigger: 'event',
build({ groupName, groupCode, userEmail }) {
return {
type: 'user_registration',
title: 'New User Registered',
message: `A new user registered in ${groupName}.`,
data: { groupName, groupCode, userEmail },
};
},
},
// ─────────────────────────────────────────────────────────────────────────
// USER notifications (scope: 'user')
// ─────────────────────────────────────────────────────────────────────────
// ── Task ──────────────────────────────────────────────────────────────────
user_task_overdue: {
type: 'task',
scope: 'user',
trigger: 'cron',
build({ count, task_list_ids = [] }) {
const label = count === 1 ? '1 task has' : `${count} tasks have`;
return {
type: 'task',
title: 'Tasks Overdue',
message: `${label} passed their deadline and been marked as overdue.`,
data: { count, task_list_ids },
};
},
},
task_reminder: {
type: 'task',
scope: 'user',
trigger: 'cron',
build({ taskName, deadline }) {
return {
type: 'task',
title: 'Task Deadline Approaching',
message: `"${taskName}" is due on ${new Date(deadline).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })}.`,
data: { taskName, deadline },
};
},
},
// ── Achievement ───────────────────────────────────────────────────────────
achievement: {
type: 'achievement',
scope: 'user',
trigger: 'event',
build({ label, description, key }) {
return {
type: 'achievement',
title: label,
message: description,
data: { key },
};
},
},
// ── Course ────────────────────────────────────────────────────────────────
course_unlocked: {
type: 'course',
scope: 'user',
trigger: 'event',
build({ courseTitle }) {
return {
type: 'course',
title: 'New Course Available',
message: `"${courseTitle}" has been added to your learning library.`,
data: { courseTitle },
};
},
},
certificate_issued: {
type: 'course',
scope: 'user',
trigger: 'event',
build({ courseTitle, courseUuid }) {
return {
type: 'course',
title: 'Certificate Issued',
message: `Congratulations! Your certificate for "${courseTitle}" is ready.`,
data: { courseTitle, courseUuid },
};
},
},
// ── Welcome ───────────────────────────────────────────────────────────────
welcome: {
type: 'announcement',
scope: 'user',
trigger: 'event',
build({ groupName, groupCode, accType }) {
const greeting = accType === 'admin'
? 'Welcome, Administrator!'
: accType === 'staff'
? 'Welcome to the Philproperties team!'
: 'Welcome to Philproperties!';
return {
type: 'announcement',
title: 'Welcome to Philproperties',
message: groupName ? `${greeting} You have been added to ${groupName}.` : greeting,
data: { groupName, groupCode, accType },
};
},
},
// ── Platform ──────────────────────────────────────────────────────────────
announcement: {
type: 'announcement',
scope: 'user',
trigger: 'manual',
build({ title, body }) {
return {
type: 'announcement',
title,
message: body,
data: {},
};
},
},
};
module.exports = { NOTIFICATION_REGISTRY };