nodebb-plugin-niki-loyalty 1.0.10 → 1.0.12

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 +58 -34
  2. package/package.json +1 -1
package/library.js CHANGED
@@ -12,26 +12,37 @@ 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) {
15
+ // --- LOG FONKSİYONLARI ---
16
+ async function addUserLog(uid, type, amount, desc) {
17
17
  const logEntry = {
18
- timestamp: Date.now(),
18
+ ts: Date.now(),
19
19
  type: type, // 'earn' veya 'spend'
20
- amount: amount,
21
- desc: description
20
+ amt: amount,
21
+ txt: desc
22
22
  };
23
- // Listeye ekle (Sondan ekler)
23
+ // Listeye ekle ve son 50 işlemi tut
24
24
  await db.listAppend(`niki:activity:${uid}`, logEntry);
25
-
26
- // Son 50 işlemi tut, gerisini sil (Veritabanı şişmesin)
27
25
  await db.listTrim(`niki:activity:${uid}`, -50, -1);
28
26
  }
29
27
 
28
+ async function addKasaLog(staffUid, customerName, customerUid) {
29
+ const logEntry = {
30
+ ts: Date.now(),
31
+ staff: staffUid,
32
+ cust: customerName,
33
+ cuid: customerUid,
34
+ amt: SETTINGS.coffeeCost
35
+ };
36
+ // Kasa geçmişine ekle ve son 100 işlemi tut
37
+ await db.listAppend('niki:kasa:history', logEntry);
38
+ await db.listTrim('niki:kasa:history', -100, -1);
39
+ }
40
+
30
41
  Plugin.init = async function (params) {
31
42
  const router = params.router;
32
43
  const middleware = params.middleware;
33
44
 
34
- // 1. HEARTBEAT (Puan Kazanma + LOG)
45
+ // 1. HEARTBEAT (Puan Kazanma)
35
46
  router.post('/api/niki-loyalty/heartbeat', middleware.ensureLoggedIn, async (req, res) => {
36
47
  const uid = req.uid;
37
48
  const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
@@ -45,16 +56,12 @@ Plugin.init = async function (params) {
45
56
 
46
57
  await user.incrementUserFieldBy(uid, 'niki_points', SETTINGS.pointsPerHeartbeat);
47
58
  await db.incrObjectFieldBy(dailyKey, 'score', SETTINGS.pointsPerHeartbeat);
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
-
59
+
53
60
  const newBalance = await user.getUserField(uid, 'niki_points');
54
61
  return res.json({ earned: true, points: SETTINGS.pointsPerHeartbeat, total: newBalance });
55
62
  });
56
63
 
57
- // 2. WALLET DATA + GEÇMİŞİ ÇEKME
64
+ // 2. WALLET DATA (Cüzdan Bilgisi + Geçmiş)
58
65
  router.get('/api/niki-loyalty/wallet-data', middleware.ensureLoggedIn, async (req, res) => {
59
66
  const uid = req.uid;
60
67
  const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
@@ -62,12 +69,9 @@ Plugin.init = async function (params) {
62
69
  const [userData, dailyData, history] = await Promise.all([
63
70
  user.getUserFields(uid, ['niki_points']),
64
71
  db.getObject(`niki:daily:${uid}:${today}`),
65
- db.getListRange(`niki:activity:${uid}`, 0, -1) // Tüm geçmişi çek
72
+ db.getListRange(`niki:activity:${uid}`, 0, -1)
66
73
  ]);
67
74
 
68
- // Geçmişi ters çevir (En yeni en üstte)
69
- const recentActivity = (history || []).reverse();
70
-
71
75
  const currentPoints = parseInt(userData.niki_points) || 0;
72
76
  const dailyScore = parseInt(dailyData ? dailyData.score : 0) || 0;
73
77
  let dailyPercent = (dailyScore / SETTINGS.dailyCap) * 100;
@@ -78,11 +82,30 @@ Plugin.init = async function (params) {
78
82
  dailyScore: dailyScore,
79
83
  dailyCap: SETTINGS.dailyCap,
80
84
  dailyPercent: dailyPercent,
81
- history: recentActivity // Frontend'e gönder
85
+ history: (history || []).reverse() // En yeniden eskiye
82
86
  });
83
87
  });
84
88
 
85
- // 3. QR TOKEN ÜRET
89
+ // 3. KASA GEÇMİŞİ (Staff Dashboard)
90
+ router.get('/api/niki-loyalty/kasa-history', middleware.ensureLoggedIn, async (req, res) => {
91
+ const isAdmin = await user.isAdministrator(req.uid);
92
+ const isMod = await user.isGlobalModerator(req.uid);
93
+
94
+ if (!isAdmin && !isMod) return res.status(403).json([]);
95
+
96
+ const history = await db.getListRange('niki:kasa:history', 0, -1);
97
+
98
+ // Kullanıcı resimlerini de çekmek için zenginleştirme yapalım
99
+ const enrichedHistory = await Promise.all((history || []).reverse().map(async (item) => {
100
+ const uData = await user.getUserFields(item.cuid, ['picture']);
101
+ item.picture = uData.picture;
102
+ return item;
103
+ }));
104
+
105
+ res.json(enrichedHistory);
106
+ });
107
+
108
+ // 4. QR OLUŞTUR
86
109
  router.post('/api/niki-loyalty/generate-qr', middleware.ensureLoggedIn, async (req, res) => {
87
110
  const uid = req.uid;
88
111
  const points = parseInt(await user.getUserField(uid, 'niki_points')) || 0;
@@ -96,7 +119,7 @@ Plugin.init = async function (params) {
96
119
  return res.json({ success: true, token: token });
97
120
  });
98
121
 
99
- // 4. QR OKUTMA (Harcama + LOG)
122
+ // 5. QR OKUT (Ödeme Alma)
100
123
  router.post('/api/niki-loyalty/scan-qr', middleware.ensureLoggedIn, async (req, res) => {
101
124
  const { token } = req.body;
102
125
 
@@ -108,28 +131,29 @@ Plugin.init = async function (params) {
108
131
  if (!customerUid) return res.json({ success: false, message: 'Geçersiz Kod' });
109
132
 
110
133
  const pts = parseInt(await user.getUserField(customerUid, 'niki_points')) || 0;
111
- if (pts < SETTINGS.coffeeCost) return res.json({ success: false, message: 'Bakiye Yetersiz' });
134
+ if (pts < SETTINGS.coffeeCost) return res.json({ success: false, message: 'Yetersiz Bakiye' });
112
135
 
113
- // Puan Düş
136
+ // İŞLEM
114
137
  await user.decrementUserFieldBy(customerUid, 'niki_points', SETTINGS.coffeeCost);
115
138
  await db.delete(`niki:qr:${token}`);
116
139
 
117
- // LOG KAYDET: Harcama
118
- await addLog(customerUid, 'spend', SETTINGS.coffeeCost, 'Kahve Harcaması');
119
-
140
+ // LOGLAMA (Detaylı metin ile)
120
141
  const customerData = await user.getUserFields(customerUid, ['username', 'picture']);
142
+
143
+ // Öğrenciye: "Kahve Keyfi" yazsın
144
+ await addUserLog(customerUid, 'spend', SETTINGS.coffeeCost, 'Kahve Keyfi ☕');
145
+
146
+ // Kasaya: Kimin aldığı yazsın
147
+ await addKasaLog(req.uid, customerData.username, customerUid);
148
+
121
149
  return res.json({ success: true, customer: customerData, message: 'Onaylandı!' });
122
150
  });
123
151
 
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
152
+ // SAYFA ROTASI
130
153
  routeHelpers.setupPageRoute(router, '/niki-kasa', middleware, [], async (req, res) => {
131
154
  const isAdmin = await user.isAdministrator(req.uid);
132
- if (!isAdmin) return res.render('403', {});
155
+ const isMod = await user.isGlobalModerator(req.uid);
156
+ if (!isAdmin && !isMod) return res.render('403', {});
133
157
  res.render('niki-kasa', { title: 'Niki Kasa' });
134
158
  });
135
159
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-niki-loyalty",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Niki The Cat Coffee Loyalty System - Earn points while studying on IEU Forum.",
5
5
  "main": "library.js",
6
6
  "nbbpm": {