nodebb-plugin-niki-loyalty 1.0.9 → 1.0.10

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.
Files changed (2) hide show
  1. package/library.js +44 -19
  2. package/package.json +1 -1
package/library.js CHANGED
@@ -12,11 +12,26 @@ const SETTINGS = {
12
12
  coffeeCost: 250
13
13
  };
14
14
 
15
+ // --- YARDIMCI: İŞLEM GEÇMİŞİNE EKLE ---
16
+ async function addLog(uid, type, amount, description) {
17
+ const logEntry = {
18
+ timestamp: Date.now(),
19
+ type: type, // 'earn' veya 'spend'
20
+ amount: amount,
21
+ desc: description
22
+ };
23
+ // Listeye ekle (Sondan ekler)
24
+ await db.listAppend(`niki:activity:${uid}`, logEntry);
25
+
26
+ // Son 50 işlemi tut, gerisini sil (Veritabanı şişmesin)
27
+ await db.listTrim(`niki:activity:${uid}`, -50, -1);
28
+ }
29
+
15
30
  Plugin.init = async function (params) {
16
31
  const router = params.router;
17
32
  const middleware = params.middleware;
18
33
 
19
- // 1. HEARTBEAT (Puan Kazanma)
34
+ // 1. HEARTBEAT (Puan Kazanma + LOG)
20
35
  router.post('/api/niki-loyalty/heartbeat', middleware.ensureLoggedIn, async (req, res) => {
21
36
  const uid = req.uid;
22
37
  const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
@@ -30,21 +45,29 @@ Plugin.init = async function (params) {
30
45
 
31
46
  await user.incrementUserFieldBy(uid, 'niki_points', SETTINGS.pointsPerHeartbeat);
32
47
  await db.incrObjectFieldBy(dailyKey, 'score', SETTINGS.pointsPerHeartbeat);
33
-
48
+
49
+ // LOG EKLEME (Her 5 puan için log şişirmemek adına, sadece veritabanına sessizce işleyelim)
50
+ // Ancak kullanıcı her saniye log görmesin diye buraya eklemiyoruz.
51
+ // İstersen "Ders Çalışma Oturumu" bittiğinde toplu ekleyebiliriz ama şimdilik basit tutalım.
52
+
34
53
  const newBalance = await user.getUserField(uid, 'niki_points');
35
54
  return res.json({ earned: true, points: SETTINGS.pointsPerHeartbeat, total: newBalance });
36
55
  });
37
56
 
38
- // 2. WALLET DATA (Bilgi Çekme)
57
+ // 2. WALLET DATA + GEÇMİŞİ ÇEKME
39
58
  router.get('/api/niki-loyalty/wallet-data', middleware.ensureLoggedIn, async (req, res) => {
40
59
  const uid = req.uid;
41
60
  const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
42
61
 
43
- const [userData, dailyData] = await Promise.all([
62
+ const [userData, dailyData, history] = await Promise.all([
44
63
  user.getUserFields(uid, ['niki_points']),
45
- db.getObject(`niki:daily:${uid}:${today}`)
64
+ db.getObject(`niki:daily:${uid}:${today}`),
65
+ db.getListRange(`niki:activity:${uid}`, 0, -1) // Tüm geçmişi çek
46
66
  ]);
47
67
 
68
+ // Geçmişi ters çevir (En yeni en üstte)
69
+ const recentActivity = (history || []).reverse();
70
+
48
71
  const currentPoints = parseInt(userData.niki_points) || 0;
49
72
  const dailyScore = parseInt(dailyData ? dailyData.score : 0) || 0;
50
73
  let dailyPercent = (dailyScore / SETTINGS.dailyCap) * 100;
@@ -54,34 +77,29 @@ Plugin.init = async function (params) {
54
77
  points: currentPoints,
55
78
  dailyScore: dailyScore,
56
79
  dailyCap: SETTINGS.dailyCap,
57
- dailyPercent: dailyPercent
80
+ dailyPercent: dailyPercent,
81
+ history: recentActivity // Frontend'e gönder
58
82
  });
59
83
  });
60
84
 
61
- // 3. QR TOKEN ÜRET (Öğrenci Butona Basınca)
85
+ // 3. QR TOKEN ÜRET
62
86
  router.post('/api/niki-loyalty/generate-qr', middleware.ensureLoggedIn, async (req, res) => {
63
87
  const uid = req.uid;
64
88
  const points = parseInt(await user.getUserField(uid, 'niki_points')) || 0;
65
89
 
66
- if (points < SETTINGS.coffeeCost) {
67
- return res.json({ success: false, message: 'Yetersiz Puan' });
68
- }
90
+ if (points < SETTINGS.coffeeCost) return res.json({ success: false, message: 'Yetersiz Puan' });
69
91
 
70
- // Token Oluştur
71
92
  const token = Math.random().toString(36).substring(2) + Date.now().toString(36);
72
-
73
- // Kaydet (2 dakika geçerli)
74
93
  await db.set(`niki:qr:${token}`, uid);
75
94
  await db.expire(`niki:qr:${token}`, 120);
76
95
 
77
96
  return res.json({ success: true, token: token });
78
97
  });
79
98
 
80
- // 4. QR OKUTMA (Personel Tarayınca)
99
+ // 4. QR OKUTMA (Harcama + LOG)
81
100
  router.post('/api/niki-loyalty/scan-qr', middleware.ensureLoggedIn, async (req, res) => {
82
101
  const { token } = req.body;
83
102
 
84
- // Sadece Admin/Mod yetkisi
85
103
  const isAdmin = await user.isAdministrator(req.uid);
86
104
  const isMod = await user.isGlobalModerator(req.uid);
87
105
  if (!isAdmin && !isMod) return res.status(403).json({ success: false, message: 'Yetkisiz' });
@@ -89,22 +107,29 @@ Plugin.init = async function (params) {
89
107
  const customerUid = await db.get(`niki:qr:${token}`);
90
108
  if (!customerUid) return res.json({ success: false, message: 'Geçersiz Kod' });
91
109
 
92
- // Puan Düş
93
110
  const pts = parseInt(await user.getUserField(customerUid, 'niki_points')) || 0;
94
111
  if (pts < SETTINGS.coffeeCost) return res.json({ success: false, message: 'Bakiye Yetersiz' });
95
112
 
113
+ // Puan Düş
96
114
  await user.decrementUserFieldBy(customerUid, 'niki_points', SETTINGS.coffeeCost);
97
115
  await db.delete(`niki:qr:${token}`);
98
116
 
117
+ // LOG KAYDET: Harcama
118
+ await addLog(customerUid, 'spend', SETTINGS.coffeeCost, 'Kahve Harcaması');
119
+
99
120
  const customerData = await user.getUserFields(customerUid, ['username', 'picture']);
100
121
  return res.json({ success: true, customer: customerData, message: 'Onaylandı!' });
101
122
  });
102
123
 
103
- // 5. NIKI KASA SAYFASI (Erişim Kontrolü)
124
+ // ** Manuel Puan Ekleme API'si (Test veya Bonus İçin) **
125
+ // Buraya "Kazanma Logu" ekleyelim ki tabloda görünsün.
126
+ // Client tarafındaki "heartbeat" çok sık çalıştığı için veritabanını şişirmemek adına
127
+ // oraya log koymadık. Ama günlük hedefe ulaşınca veya manuel eklenince log düşebiliriz.
128
+
129
+ // NIKI KASA SAYFASI
104
130
  routeHelpers.setupPageRoute(router, '/niki-kasa', middleware, [], async (req, res) => {
105
131
  const isAdmin = await user.isAdministrator(req.uid);
106
- const isMod = await user.isGlobalModerator(req.uid);
107
- if (!isAdmin && !isMod) return res.render('403', {});
132
+ if (!isAdmin) return res.render('403', {});
108
133
  res.render('niki-kasa', { title: 'Niki Kasa' });
109
134
  });
110
135
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-niki-loyalty",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "Niki The Cat Coffee Loyalty System - Earn points while studying on IEU Forum.",
5
5
  "main": "library.js",
6
6
  "nbbpm": {