Compare commits

..

60 Commits

Author SHA1 Message Date
Muhammad Afif
73b05c5d0d repair api resend wa & delete log.json 2026-06-01 14:50:35 +07:00
1af02c2d36 Merge pull request 'feat: add dayjs for date handling and update reminder logic to use timezone-aware timestamps' (#59) from wisdom into main
Reviewed-on: #59
2026-05-04 05:57:35 +00:00
e295d781db Merge pull request 'fix: improve reminder deletion logic by ensuring id is a number and simplifying data filtering' (#58) from wisdom into main
Reviewed-on: #58
2026-05-03 13:53:05 +00:00
61ff3271bb Merge pull request 'fix: remove redundant update of is_active flag in notification error handling' (#57) from wisdom into main
Reviewed-on: #57
2026-05-03 13:23:11 +00:00
4cfd72aefc Merge pull request 'fix: simplify notification update logic by removing is_active flag from notification error update' (#56) from wisdom into main
Reviewed-on: #56
2026-05-03 13:18:24 +00:00
c6174c1b99 Merge pull request 'fix: comment out console log for received MQTT messages to reduce logging noise' (#55) from wisdom into main
Reviewed-on: #55
2026-05-03 13:06:24 +00:00
b0fcf6e144 Merge pull request 'fix: update notification error handling to include new update method and improve reminder deletion logic' (#54) from wisdom into main
Reviewed-on: #54
2026-05-03 12:49:38 +00:00
6d06751554 Merge pull request 'fix: update notification query to use COALESCE for device details and add additional LEFT JOIN for fallback handling' (#53) from wisdom into main
Reviewed-on: #53
2026-04-30 11:16:25 +00:00
1d326cc2ed Merge pull request 'fix: update saveReminder method to handle reset logic for reminders' (#52) from wisdom into main
Reviewed-on: #52
2026-04-30 09:55:19 +00:00
0b16cfd6a3 Merge pull request 'fix: update device name handling in notification service to ensure fallback value is used' (#51) from wisdom into main
Reviewed-on: #51
2026-04-30 08:59:25 +00:00
964889fd0b Merge pull request 'add: await in data filtering logic' (#50) from wisdom into main
Reviewed-on: #50
2026-04-30 08:55:09 +00:00
501392e1c1 Merge pull request 'refactor: update notification service to use deleteReminder from notifikasiWaService and improve data filtering logic' (#49) from wisdom into main
Reviewed-on: #49
2026-04-30 07:09:42 +00:00
8112ba7b76 Merge pull request 'wisdom' (#48) from wisdom into main
Reviewed-on: #48
2026-04-30 02:48:05 +00:00
599f758225 Merge pull request 'feat: implement reminder functionality and enhance notification service with logging' (#47) from wisdom into main
Reviewed-on: #47
2026-04-29 08:36:05 +00:00
05e14e02c5 Merge pull request 'feat: enhance sparepart database queries and sparepart number validation' (#46) from wisdom into main
Reviewed-on: #46
2026-04-27 11:21:09 +00:00
7b41dd81e8 Merge pull request 'wisdom' (#45) from wisdom into main
Reviewed-on: #45
2026-04-27 06:31:20 +00:00
c86800add0 Merge pull request 'wisdom' (#44) from wisdom into main
Reviewed-on: #44
2026-04-13 08:30:07 +00:00
d9186b8d3a Merge pull request 'fixing body message notification wa' (#42) from wisdom into main
Reviewed-on: #42
2026-01-20 04:33:05 +00:00
c6e1940604 Merge pull request 'fixing is delivered notification wa' (#41) from wisdom into main
Reviewed-on: #41
2026-01-12 07:37:34 +00:00
63bf57bde3 Merge pull request 'fixing notification wa' (#40) from wisdom into main
Reviewed-on: #40
2026-01-12 06:12:26 +00:00
84836875b9 Merge pull request 'wisdom' (#39) from wisdom into main
Reviewed-on: #39
2026-01-12 04:12:36 +00:00
c09d51591d Merge pull request 'connect mqtt ws colo' (#38) from wisdom into main
Reviewed-on: #38
2026-01-08 08:10:02 +00:00
2a2df58b7d Merge pull request 'wisdom' (#37) from wisdom into main
Reviewed-on: #37
2026-01-08 07:43:58 +00:00
ef491995f9 Merge pull request 'fixing verify access' (#36) from wisdom into main
Reviewed-on: #36
2026-01-08 05:38:22 +00:00
d9975b832b Merge pull request 'add log in resend notif wa' (#35) from wisdom into main
Reviewed-on: #35
2026-01-08 04:51:46 +00:00
205cb9d7cc Merge pull request 'Test push' (#34) from wisdom into main
Reviewed-on: #34
2026-01-08 03:48:11 +00:00
41f5cc9011 Merge branch 'wisdom'
# Conflicts:
#	services/notification_error.service.js
2026-01-08 10:45:02 +07:00
6885443bc2 repair resend notif wa 2026-01-08 09:32:20 +07:00
f5494fb4a1 Merge pull request 'repair: resend wa' (#29) from wisdom into main
Reviewed-on: #29
2026-01-07 05:18:12 +00:00
ed77576958 Merge pull request 'repair: resend notif wa' (#28) from wisdom into main
Reviewed-on: #28
2026-01-07 05:01:44 +00:00
9e862d1a48 Merge pull request 'repair: service & controller notif and notif user' (#27) from wisdom into main
Reviewed-on: #27
2026-01-07 03:10:33 +00:00
9913724d08 Merge pull request 'wisdom' (#26) from wisdom into main
Reviewed-on: #26
2026-01-06 11:41:36 +00:00
63a646fce3 Merge pull request 'add: self-signed certificate' (#25) from wisdom into main
Reviewed-on: #25
2026-01-06 05:38:46 +00:00
8d947a818b Merge pull request 'repair: change message wa notification' (#24) from wisdom into main
Reviewed-on: #24
2026-01-06 03:05:33 +00:00
81e07ed927 Merge pull request 'wisdom' (#23) from wisdom into main
Reviewed-on: #23
2026-01-05 07:06:16 +00:00
019c79d5bc Merge pull request 'wisdom' (#22) from wisdom into main
Reviewed-on: #22
2026-01-05 04:25:09 +00:00
fae6bb7a43 Merge pull request 'repair: notification error log created_by' (#21) from wisdom into main
Reviewed-on: #21
2025-12-31 03:20:14 +00:00
8ecb00a4d3 Merge pull request 'wisdom' (#20) from wisdom into main
Reviewed-on: #20
2025-12-23 05:19:45 +00:00
b62ca35185 Merge pull request 'wisdom' (#19) from wisdom into main
Reviewed-on: #19
2025-12-22 09:18:17 +00:00
5e74122b9e Merge pull request 'wisdom' (#18) from wisdom into main
Reviewed-on: #18
2025-11-28 05:09:58 +00:00
050543dbbf Merge pull request 'wisdom' (#17) from wisdom into main
Reviewed-on: #17
2025-11-25 03:50:08 +00:00
e1b397e1d3 Merge pull request 'add brand id' (#16) from wisdom into main
Reviewed-on: #16
2025-11-20 03:42:49 +00:00
34db6b8d89 Merge pull request 'wisdom' (#15) from wisdom into main
Reviewed-on: #15
2025-11-19 01:04:37 +00:00
5d1b6daef6 Merge pull request 'repair brand device: add brand sparepart in 2 step' (#14) from wisdom into main
Reviewed-on: #14
2025-11-18 00:25:14 +00:00
30431be379 Merge pull request 'wisdom' (#13) from wisdom into main
Reviewed-on: #13
2025-11-17 08:27:07 +00:00
361f750330 Update ecosystem.config.js 2025-11-04 06:14:58 +00:00
31f50d05ab Update .gitignore 2025-11-04 06:12:17 +00:00
961f0d6314 Update ecosystem.config.js 2025-11-04 05:50:27 +00:00
d87fc07a8e Update ecosystem.config.js 2025-11-04 05:46:55 +00:00
95e0c90a16 Merge pull request 'wisdom' (#11) from wisdom into main
Reviewed-on: #11
2025-10-28 09:46:55 +00:00
55e8a6d9ca Merge pull request 'repair: params user_schedule' (#10) from wisdom into main
Reviewed-on: #10
2025-10-28 04:48:25 +00:00
253d83357f Merge pull request 'add: tag_description in tags schema' (#9) from wisdom into main
Reviewed-on: #9
2025-10-27 04:07:05 +00:00
88a0404af0 Merge pull request 'wisdom' (#8) from wisdom into main
Reviewed-on: #8
2025-10-27 03:48:36 +00:00
d11207aedb Merge pull request 'wisdom' (#7) from wisdom into main
Reviewed-on: #7
2025-10-25 09:19:08 +00:00
d7044521bd Merge pull request 'wisdom' (#6) from wisdom into main
Reviewed-on: #6
2025-10-24 05:42:48 +00:00
e2a008c2e1 Merge pull request 'wisdom' (#5) from wisdom into main
Reviewed-on: #5
2025-10-24 03:35:12 +00:00
6d575f649a Merge pull request 'wisdom' (#4) from wisdom into main
Reviewed-on: #4
2025-10-23 04:51:40 +00:00
e8fd307a05 Merge pull request 'wisdom' (#3) from wisdom into main
Reviewed-on: #3
2025-10-22 05:27:56 +00:00
00239db472 Merge pull request 'wisdom' (#2) from wisdom into main
Reviewed-on: #2
2025-10-20 03:26:32 +00:00
251f7148b6 Merge pull request 'wisdom' (#1) from wisdom into main
Reviewed-on: #1
2025-09-17 08:40:15 +00:00
6 changed files with 122 additions and 85 deletions

3
.gitignore vendored
View File

@@ -3,4 +3,5 @@ node_modules
.vscode .vscode
request.http request.http
*.rest *.rest
package-lock.json package-lock.json
*.log

View File

@@ -1,7 +1,7 @@
module.exports = { module.exports = {
apps: [ apps: [
{ {
name: "bengkel-api", name: "cod-api",
script: "./index.js", // Path to your entry file script: "./index.js", // Path to your entry file
env: { env: {
NODE_ENV: "development", NODE_ENV: "development",
@@ -9,6 +9,14 @@ module.exports = {
env_production: { env_production: {
NODE_ENV: "production", NODE_ENV: "production",
}, },
// Logging configuration
// error_file: "C:\IDETAMA\pm2-log\cod-api\cod-api-error.log",
// out_file: "C:\IDETAMA\pm2-log\cod-api\cod-api-out.log",
// log_file: "C:\IDETAMA\pm2-log\cod-api\cod-api-combined.log", // optional combined file
error_file: "cod-api-error.log",
out_file: "cod-api-out.log",
log_file: "cod-api-combined.log", // optional combined file
time: true, // adds timestamps to logs
}, },
], ],
}; };

View File

@@ -1 +0,0 @@
[]

View File

@@ -1 +1,19 @@
[] [
{
"notification_log": 851,
"error_code_id": 1,
"error_chanel": 2025,
"start_at": "02:10",
"interval": 1,
"max": 3,
"active": 1,
"count": 0,
"last_run": "2026-05-31T17:41:09.191Z",
"last_run_indo": "01-06-2026 00:41:09",
"next_run": "2026-05-31T18:41:09.191Z",
"next_run_indo": "01-06-2026 01:41:09",
"message": "Reminder untuk PLC Compressor B dengan reminder 1YEAR telah dijalankan pada 01-06-2026 00:41:09, hasil pengiriman: sukses",
"time": "00:41",
"created_at": "2026-05-31T17:41:18.802Z"
}
]

View File

@@ -188,7 +188,8 @@ class NotificationService {
static async resendNotification(id) { static async resendNotification(id) {
const deviceNotification = await getNotificationByIdDb(id); const deviceNotification = await getNotificationByIdDb(id);
if (!deviceNotification) throw new ErrorHandler(404, "Data not found"); if (!deviceNotification)
throw new ErrorHandler(404, "Notification Data not found");
const errorCode = await getErrorCodeByBrandAndCodeDb(deviceNotification?.brand_id ?? 0, const errorCode = await getErrorCodeByBrandAndCodeDb(deviceNotification?.brand_id ?? 0,
deviceNotification.error_code_id deviceNotification.error_code_id

View File

@@ -27,7 +27,7 @@ const { getDeviceReminderChanelDb } = require("../db/device.db");
const baseDir = path.resolve(__dirname, '../scheduler'); const baseDir = path.resolve(__dirname, '../scheduler');
const filePath = path.join(baseDir, 'reminder.json'); const filePath = path.join(baseDir, 'reminder.json');
const filePathLog = path.join(baseDir, 'log.json'); // const filePathLog = path.join(baseDir, 'log.json');
const dayjs = require('dayjs'); const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc'); const utc = require('dayjs/plugin/utc');
@@ -41,7 +41,7 @@ dayjs.extend(timezone);
class NotifikasiWaService { class NotifikasiWaService {
async saveReminder(data, isReset = false) { async saveReminder(data, isReset = false) {
console.log(`Reminder proses dibuat`); console.log(`Reminder dibuat`);
try { try {
let existing = []; let existing = [];
@@ -95,58 +95,57 @@ class NotifikasiWaService {
await fs.writeFile(filePath, JSON.stringify(finalData, null, 2), 'utf-8'); await fs.writeFile(filePath, JSON.stringify(finalData, null, 2), 'utf-8');
await this.saveLogReminder({ // await this.saveReminder({
message: `Reminder berhasil disimpan`, // message: `Reminder berhasil disimpan`,
data, // data,
}); // });
console.log(`Reminder berhasil disimpan`);
} catch (error) { } catch (error) {
console.log('Error saveReminder:', error); next(error);
} }
} }
async saveLogReminder(data) { // async saveLogReminder(data) {
console.log(`Reminder Log dibuat`); // console.log(`Reminder Log dibuat`);
try { // try {
let existing = []; // let existing = [];
// pastikan folder ada // // pastikan folder ada
await fs.mkdir(path.dirname(filePathLog), { recursive: true }); // await fs.mkdir(path.dirname(filePathLog), { recursive: true });
try { // try {
const raw = await fs.readFile(filePathLog, 'utf-8'); // const raw = await fs.readFile(filePathLog, 'utf-8');
if (raw) { // if (raw) {
existing = JSON.parse(raw); // existing = JSON.parse(raw);
} // }
} catch (err) { // } catch (err) {
// file belum ada → buat file kosong // // file belum ada → buat file kosong
await fs.writeFile(filePathLog, '[]', 'utf-8'); // await fs.writeFile(filePathLog, '[]', 'utf-8');
existing = []; // existing = [];
} // }
const now = dayjs().tz(timeZone); // const now = dayjs().tz(timeZone);
const newData = { // const newData = {
...data, // ...data,
// 🔹 jam (HH:mm) WIB // // 🔹 jam (HH:mm) WIB
time: now.format('HH:mm'), // time: now.format('HH:mm'),
// 🔹 timestamp UTC (untuk DB) // // 🔹 timestamp UTC (untuk DB)
created_at: now.toISOString() // created_at: now.toISOString()
}; // };
await existing.push(newData); // await existing.push(newData);
await fs.writeFile(filePathLog, JSON.stringify(existing, null, 2), 'utf-8'); // await fs.writeFile(filePathLog, JSON.stringify(existing, null, 2), 'utf-8');
console.log(`Reminder Log berhasil disimpan`); // console.log(`Reminder Log berhasil disimpan`);
} catch (error) { // } catch (error) {
console.log('Error saveReminder:', error); // console.log('Error saveReminder:', error);
} // }
} // }
async onNotification(topic, message) { async onNotification(topic, message) {
try { try {
@@ -298,7 +297,7 @@ class NotifikasiWaService {
await this.saveReminder(newData, true); await this.saveReminder(newData, true);
await this.saveLogReminder({ await this.saveReminder({
message: `Reminder ${id} berhasil dihapus` message: `Reminder ${id} berhasil dihapus`
}) })
@@ -326,7 +325,7 @@ class NotifikasiWaService {
} }
); );
await this.saveLogReminder({ await this.saveReminder({
message: `Reminder ${id} berhasil dihapus` message: `Reminder ${id} berhasil dihapus`
}) })
@@ -378,7 +377,7 @@ class NotifikasiWaService {
dataUser.bodyMessage dataUser.bodyMessage
); );
await this.saveLogReminder(resultSend); await this.saveReminder(resultSend);
await updateNotificationErrorUserDb( await updateNotificationErrorUserDb(
dataUser.notification_error_user_id, dataUser.notification_error_user_id,
@@ -491,21 +490,6 @@ class NotifikasiWaService {
const resultNotificationError = await InsertNotificationErrorDb(data); const resultNotificationError = await InsertNotificationErrorDb(data);
await this.saveReminder({
notification_log: resultNotificationError.notification_error_id,
error_code_id: data['error_code_id'],
error_chanel: data['error_chanel'],
start_at: reminderAt.format('HH:mm'),
interval: 1,
max: 3,
active: 1,
count: 0,
last_run: now.toISOString(),
last_run_indo: now.format('DD-MM-YYYY HH:mm:ss'),
next_run: null,
next_run_indo: null
}, false);
const results = await getAllContactDb(paramDb); const results = await getAllContactDb(paramDb);
const dataUsers = results.data; const dataUsers = results.data;
@@ -554,10 +538,26 @@ class NotifikasiWaService {
param.bodyMessage param.bodyMessage
); );
await this.saveLogReminder({ await this.saveReminder({
message: `Reminder dijalankan`, notification_log: resultNotificationError.notification_error_id,
resultSend error_code_id: data['error_code_id'],
}) error_chanel: data['error_chanel'],
start_at: reminderAt.format('HH:mm'),
interval: 1,
max: 3,
active: 1,
count: 0,
last_run: now.toISOString(),
last_run_indo: now.format('DD-MM-YYYY HH:mm:ss'),
next_run: null,
next_run_indo: null,
message: `Reminder untuk ${deviceName} dengan reminder ${chanel.value} telah dijalankan pada ${now.format('DD-MM-YYYY HH:mm:ss')}, hasil pengiriman: ${resultSend.success ? 'sukses' : 'gagal'}`,
}, false);
// await this.saveLogReminder({
// message: `Reminder dijalankan`,
// resultSend
// })
await updateNotificationErrorUserDb( await updateNotificationErrorUserDb(
resultNotificationErrorUser[0].notification_error_user_id, resultNotificationErrorUser[0].notification_error_user_id,
@@ -593,25 +593,29 @@ class NotifikasiWaService {
async restartWhatsapp() { async restartWhatsapp() {
try { try {
const processName = "Whatsapp-API-notification" && "cod-whatsapp-notif";
const processName = "cod-whatsapp-notif";
const { stdout } = await execPromise("pm2 jlist"); const { stdout } = await execPromise("pm2 jlist");
const processes = JSON.parse(stdout); const cleanJSON = stdout.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');
const startJSON = cleanJSON.indexOf('[');
const endJSON = cleanJSON.lastIndexOf(']') + 1;
if (startJSON === -1 || endJSON === 0) {
throw new Error(`Terminal tidak mengembalikan JSON yang valid. Output: ${stdout}`);
}
const index = cleanJSON.slice(startJSON, endJSON);
const processes = JSON.parse(index);
const waProcess = processes.find((p) => p.name === processName); const waProcess = processes.find((p) => p.name === processName);
if (!waProcess) throw new Error(`PM2 ${processName} not found`); if (!waProcess) throw new Error(`PM2 proses dengan nama "${processName}" tidak ditemukan!`);
const waProcessId = waProcess.pm_id; const waProcessId = waProcess.pm_id;
const pathDelete = waProcess.pm2_env.pm_cwd; const pathDelete = waProcess.pm2_env.pm_cwd;
// const execLogs = (cmd) => { // console.log(`stop proses id: ${waProcessId}`);
// const p = exec(cmd); await execPromise(`pm2 stop ${waProcessId}`);
// p.stdout.pipe(process.stdout);
// p.stderr.pipe(process.stderr);
// return new Promise((res) => p.on("exit", res));
// };
// console.log(`stop proses id: ${waProcessId}`)
await execPromise(`start powershell -Command "pm2 stop ${waProcessId}"`);
const pathFolderDelete = [ const pathFolderDelete = [
path.join(pathDelete, ".wwebjs_auth"), path.join(pathDelete, ".wwebjs_auth"),
@@ -620,19 +624,25 @@ class NotifikasiWaService {
// console.log(`path: ${pathDelete}`); // console.log(`path: ${pathDelete}`);
pathFolderDelete.forEach((dir) => { for (const dir of pathFolderDelete) {
if (fs.existsSync(dir)) { try {
// console.log(`path folder: ${dir}`); await fs.access(dir);
fs.rmSync(dir, { recursive: true, force: true }); console.log(`path folder ditemukan, menghapus: ${dir}`);
await fs.rm(dir, { recursive: true, force: true });
} catch (fsErr) {
if (fsErr.code !== 'ENOENT') {
console.error(`Gagal memproses folder ${dir}:`, fsErr.message);
}
} }
}); }
// console.log(`start proses id: ${waProcessId}`); // console.log(`start proses id: ${waProcessId}`);
await execPromise(`start powershell -Command "pm2 start ${waProcessId}"`); await execPromise(`pm2 start ${waProcessId}`);
return { success: true, message: "WhatsApp has been restarted." }; return { success: true, message: "WhatsApp has been restarted." };
} catch (err) { } catch (err) {
return err; return { success: false, error: err.message || err };
} }
} }
} }