nodebb-plugin-niki-loyalty 1.2.8 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/library.js CHANGED
@@ -73,24 +73,35 @@ async function awardDailyAction(uid, actionKey) {
73
73
  const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
74
74
  const rule = ACTIONS[actionKey];
75
75
 
76
- if (!rule) return;
76
+ if (!rule) {
77
+ console.log(`[Niki-Loyalty] Bilinmeyen aksiyon: ${actionKey}`);
78
+ return { success: false, reason: 'unknown_action' };
79
+ }
77
80
 
78
81
  // 1. Genel Günlük Limit Kontrolü
79
82
  const dailyScoreKey = `niki:daily:${uid}:${today}`;
80
83
  const currentDailyScore = parseFloat((await db.getObjectField(dailyScoreKey, 'score')) || 0);
81
- if (currentDailyScore >= SETTINGS.dailyCap) return;
84
+ if (currentDailyScore >= SETTINGS.dailyCap) {
85
+ console.log(`[Niki-Loyalty] Günlük limit doldu. UID: ${uid}, Score: ${currentDailyScore}`);
86
+ return { success: false, reason: 'daily_cap_reached' };
87
+ }
82
88
 
83
89
  // 2. Eylem Bazlı Limit Kontrolü
84
90
  const actionCountKey = `niki:daily:${uid}:${today}:counts`;
85
91
  const currentActionCount = parseInt((await db.getObjectField(actionCountKey, actionKey)) || 0, 10);
86
- if (currentActionCount >= rule.limit) return;
92
+ if (currentActionCount >= rule.limit) {
93
+ console.log(`[Niki-Loyalty] Aksiyon limiti doldu. UID: ${uid}, Action: ${actionKey}, Count: ${currentActionCount}/${rule.limit}`);
94
+ return { success: false, reason: 'action_limit_reached' };
95
+ }
87
96
 
88
97
  // 3. Puan Hesapla
89
98
  let pointsToGive = rule.points;
90
99
  if (currentDailyScore + pointsToGive > SETTINGS.dailyCap) {
91
100
  pointsToGive = SETTINGS.dailyCap - currentDailyScore;
92
101
  }
93
- if (pointsToGive <= 0) return;
102
+ if (pointsToGive <= 0) {
103
+ return { success: false, reason: 'no_points_to_give' };
104
+ }
94
105
 
95
106
  // 4. DB Güncellemeleri
96
107
  await user.incrementUserFieldBy(uid, 'niki_points', pointsToGive);
@@ -100,17 +111,30 @@ async function awardDailyAction(uid, actionKey) {
100
111
  // Logla
101
112
  await addUserLog(uid, 'earn', pointsToGive, rule.name);
102
113
 
103
- //YENİ EKLENEN KISIM: Kullanıcıya Bildirim Gönder (Socket Emit)
104
- if (socketHelpers && socketHelpers.server) {
105
- socketHelpers.server.sockets.in('uid_' + uid).emit('event:niki_award', {
106
- title: 'Tebrikler! 🥳',
107
- message: `${rule.name} işleminden <strong style="color:#ffd700">+${pointsToGive} Puan</strong> kazandın!`,
108
- newTotal: parseFloat((await user.getUserField(uid, 'niki_points')) || 0)
109
- });
114
+ console.log(`[Niki-Loyalty]PUAN VERİLDİ! UID: ${uid}, Action: ${actionKey}, Points: +${pointsToGive}`);
115
+
116
+ // Kullanıcıya Bildirim Gönder (Socket Emit) - Güçlendirilmiş
117
+ try {
118
+ if (socketHelpers && socketHelpers.server && socketHelpers.server.sockets) {
119
+ const newTotal = parseFloat((await user.getUserField(uid, 'niki_points')) || 0);
120
+ socketHelpers.server.sockets.in('uid_' + uid).emit('event:niki_award', {
121
+ title: 'Tebrikler! 🥳',
122
+ message: `${rule.name} işleminden <strong style="color:#ffd700">+${pointsToGive} Puan</strong> kazandın!`,
123
+ newTotal: newTotal
124
+ });
125
+ console.log(`[Niki-Loyalty] 📢 Socket bildirim gönderildi. UID: ${uid}`);
126
+ } else {
127
+ console.log(`[Niki-Loyalty] ⚠️ Socket server hazır değil, bildirim gönderilemedi.`);
128
+ }
129
+ } catch (socketErr) {
130
+ console.error(`[Niki-Loyalty] Socket emit hatası:`, socketErr.message);
110
131
  }
111
132
 
133
+ return { success: true, points: pointsToGive };
134
+
112
135
  } catch (err) {
113
136
  console.error(`[Niki-Loyalty] Error awarding points for ${actionKey}:`, err);
137
+ return { success: false, reason: 'error', error: err.message };
114
138
  }
115
139
  }
116
140
 
@@ -144,39 +168,52 @@ Plugin.onPostCreate = async function (data) {
144
168
  await awardDailyAction(data.post.uid, 'reply');
145
169
  };
146
170
 
147
- // 4. BEĞENİ (Like Atma ve Alma) - Spam Korumalı
171
+ // 4. BEĞENİ (Like Atma ve Alma) - Spam Korumalı + Debug Loglı
148
172
  Plugin.onUpvote = async function (data) {
149
- // data = { post: { pid, uid, ... }, uid: <like atan>, ... }
173
+ console.log('[Niki-Loyalty] 👍 Upvote hook tetiklendi. Data:', JSON.stringify({
174
+ voterUid: data.uid,
175
+ postPid: data.post?.pid,
176
+ postOwnerUid: data.post?.uid
177
+ }));
178
+
150
179
  const pid = data.post && data.post.pid;
151
- if (!pid) return;
180
+ if (!pid) {
181
+ console.log('[Niki-Loyalty] ⚠️ Post PID bulunamadı, işlem iptal.');
182
+ return;
183
+ }
152
184
 
153
185
  const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
154
186
 
155
187
  // Like Atan Kazanır:
156
188
  if (data.uid) {
157
- // Bu postu bugün zaten beğenmiş mi?
158
189
  const likeGivenKey = `niki:liked:${data.uid}:${today}`;
159
190
  const alreadyLiked = await db.isSetMember(likeGivenKey, pid.toString());
160
191
 
192
+ console.log(`[Niki-Loyalty] Like Atan: UID=${data.uid}, PID=${pid}, Daha önce beğenmiş mi=${alreadyLiked}`);
193
+
161
194
  if (!alreadyLiked) {
162
- await awardDailyAction(data.uid, 'like_given');
195
+ const result = await awardDailyAction(data.uid, 'like_given');
196
+ console.log('[Niki-Loyalty] like_given sonuç:', result);
163
197
  await db.setAdd(likeGivenKey, pid.toString());
164
- // 24 saat sonra expire olsun
165
198
  await db.expire(likeGivenKey, 86400);
166
199
  }
167
200
  }
168
201
 
169
202
  // Like Alan Kazanır (Post sahibi):
170
203
  if (data.post && data.post.uid && data.post.uid !== data.uid) {
171
- // Bu post için bugün zaten puan almış mı?
172
204
  const likeTakenKey = `niki:liked_taken:${data.post.uid}:${today}`;
173
205
  const alreadyTaken = await db.isSetMember(likeTakenKey, pid.toString());
174
206
 
207
+ console.log(`[Niki-Loyalty] Like Alan: UID=${data.post.uid}, PID=${pid}, Daha önce puan almış mı=${alreadyTaken}`);
208
+
175
209
  if (!alreadyTaken) {
176
- await awardDailyAction(data.post.uid, 'like_taken');
210
+ const result = await awardDailyAction(data.post.uid, 'like_taken');
211
+ console.log('[Niki-Loyalty] like_taken sonuç:', result);
177
212
  await db.setAdd(likeTakenKey, pid.toString());
178
213
  await db.expire(likeTakenKey, 86400);
179
214
  }
215
+ } else {
216
+ console.log('[Niki-Loyalty] ⚠️ Like alan kontrol edilemedi. Post owner:', data.post?.uid, 'Voter:', data.uid);
180
217
  }
181
218
  };
182
219
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-niki-loyalty",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "description": "Niki The Cat Coffee Loyalty System - Earn points while studying on IEU Forum.",
5
5
  "main": "library.js",
6
6
  "nbbpm": {
package/plugin.json CHANGED
@@ -5,14 +5,38 @@
5
5
  "url": "https://forum.ieu.app",
6
6
  "library": "./library.js",
7
7
  "hooks": [
8
- { "hook": "static:app.load", "method": "init" },
9
- { "hook": "filter:navigation.available", "method": "addNavigation" },
10
- { "hook": "filter:scripts.get", "method": "addScripts" },
11
-
12
- { "hook": "action:user.loggedIn", "method": "onLogin" },
13
- { "hook": "action:topic.save", "method": "onTopicCreate" },
14
- { "hook": "action:post.save", "method": "onPostCreate" },
15
- { "hook": "action:post.upvote", "method": "onUpvote" }
8
+ {
9
+ "hook": "static:app.load",
10
+ "method": "init"
11
+ },
12
+ {
13
+ "hook": "filter:navigation.available",
14
+ "method": "addNavigation"
15
+ },
16
+ {
17
+ "hook": "filter:scripts.get",
18
+ "method": "addScripts"
19
+ },
20
+ {
21
+ "hook": "action:user.loggedIn",
22
+ "method": "onLogin"
23
+ },
24
+ {
25
+ "hook": "action:topic.save",
26
+ "method": "onTopicCreate"
27
+ },
28
+ {
29
+ "hook": "action:post.save",
30
+ "method": "onPostCreate"
31
+ },
32
+ {
33
+ "hook": "action:post.upvote",
34
+ "method": "onUpvote"
35
+ },
36
+ {
37
+ "hook": "action:post.updatePostVoteCount",
38
+ "method": "onUpvote"
39
+ }
16
40
  ],
17
41
  "staticDirs": {
18
42
  "static": "./static"
@@ -284,7 +284,7 @@ $(document).ready(function () {
284
284
 
285
285
  let dailyScore = parseFloat(data.dailyScore);
286
286
  let scoreText = Number.isInteger(dailyScore) ? dailyScore : dailyScore.toFixed(1);
287
- $('#widget-daily-text').text(scoreText + ' / 28');
287
+ $('#widget-daily-text').text(scoreText + ' / 35');
288
288
 
289
289
  // 3. DETAYLI SAYAÇLAR (Counts)
290
290
  const c = data.counts || {}; // Backend'den gelen sayaç objesi
@@ -304,10 +304,10 @@ $(document).ready(function () {
304
304
  }
305
305
  }
306
306
 
307
- // Tek Tek Güncelle
307
+ // Tek Tek Güncelle (library.js ACTIONS ile eşleştirildi)
308
308
  setProgress('w-count-new_topic', c.new_topic, 1, 'item-new-topic');
309
309
  setProgress('w-count-reply', c.reply, 2, 'item-reply');
310
- setProgress('w-count-read', c.read, 8, 'item-read');
310
+ setProgress('w-count-read', c.read, 10, 'item-read');
311
311
 
312
312
  // Like (Alma ve Atma toplamı 4 limit demiştik, burada basitleştirip toplamı gösteriyoruz)
313
313
  // Backend'de like_given ve like_taken ayrı tutuluyor, ikisini toplayalım: