diff --git a/docs/superpowers/plans/2025-05-12-daily-summary.md b/docs/superpowers/plans/2025-05-12-daily-summary.md new file mode 100644 index 0000000..3c4c5a7 --- /dev/null +++ b/docs/superpowers/plans/2025-05-12-daily-summary.md @@ -0,0 +1,238 @@ +# Dagelijkse WhatsApp samenvatting — Implementation Plan + +> **Voor agentic workers:** REQUIRED SUB-SKILL: Gebruik superpowers:subagent-driven-development (aanbevolen) of superpowers:executing-plans om dit plan taak-voor-taak te implementeren. Stappen gebruiken checkbox (`- [ ]`) syntax voor tracking. + +**Goal:** Elke dag om 10:00 een WhatsApp-bericht naar de admin sturen met het totaal aantal dienstaanvragen van de vorige dag. + +**Architecture:** Nieuwe module `dailyStats.js` houdt een dagtotaal bij in memory. `messageHandler.js` roept increment aan bij elke aanvraag. `node-cron` triggert om 10:00 de reset en verzending via bestaande `whatsappApi.sendTextMessage()`. + +**Tech Stack:** Node.js, node-cron (nieuwe dependency), bestaande axios/express stack + +**Files:** +- Create: `src/dailyStats.js` +- Modify: `src/messageHandler.js` +- Modify: `src/index.js` +- Modify: `package.json` + +--- + +### Task 1: Create dailyStats module + +**Files:** +- Create: `src/dailyStats.js` + +- [ ] **Step 1: Write the dailyStats module** + +```javascript +let dailyTotal = 0 +let yesterdayTotal = 0 + +function increment() { + dailyTotal++ +} + +function getYesterdayTotal() { + return yesterdayTotal +} + +function resetDay() { + yesterdayTotal = dailyTotal + dailyTotal = 0 +} + +module.exports = { increment, getYesterdayTotal, resetDay } +``` + +- [ ] **Step 2: Verify the module loads without errors** + +Run: `node -e "const m = require('./src/dailyStats'); m.increment(); m.increment(); m.resetDay(); console.log(m.getYesterdayTotal() === 2 ? 'OK' : 'FAIL')"` +Expected: `OK` + +- [ ] **Step 3: Commit** + +```bash +git add src/dailyStats.js +git commit -m "feat: add dailyStats module for tracking daily request totals" +``` + +--- + +### Task 2: Integrate dailyStats into messageHandler + +**Files:** +- Modify: `src/messageHandler.js` + +- [ ] **Step 1: Add dailyStats import and increment call** + +`src/messageHandler.js` line 1-4, add import: + +```javascript +const { findDienst, getPngFilePaths } = require('./dienstService') +const { sendTextMessage, sendImageMessage, notifyAdmin } = require('./whatsappApi') +const { checkLimit, increment, MAX_REQUESTS_PER_DAY } = require('./rateLimiter') +const { increment: incrementDaily } = require('./dailyStats') +``` + +`src/messageHandler.js` after `increment(author)` (line 51), add: + +```javascript + increment(author) + incrementDaily() +``` + +- [ ] **Step 2: Verify messageHandler still loads** + +Run: `node -e "require('./src/messageHandler'); console.log('OK')"` +Expected: `OK` (may show dotenv warning, that's fine) + +- [ ] **Step 3: Commit** + +```bash +git add src/messageHandler.js +git commit -m "feat: integrate dailyStats counter into message handler" +``` + +--- + +### Task 3: Add node-cron and schedule daily 10:00 summary + +**Files:** +- Modify: `package.json` +- Modify: `src/index.js` + +- [ ] **Step 1: Install node-cron** + +Run: `npm install node-cron` +Expected: node-cron added to `node_modules` and `package.json` + +- [ ] **Step 2: Add cron job to index.js** + +`src/index.js` — replace the entire file: + +```javascript +require('dotenv').config() +const cron = require('node-cron') +const express = require('express') +const { handleWebhook } = require('./messageHandler') +const { loadDiensten } = require('./dienstService') +const { resetDay, getYesterdayTotal } = require('./dailyStats') +const { sendTextMessage } = require('./whatsappApi') + +const app = express() +app.use(express.json({ limit: '10mb' })) + +app.post('/webhook', async (req, res) => { + try { + await handleWebhook(req.body) + res.json({ success: true }) + } catch (err) { + console.error('Webhook processing error:', err.message) + res.status(500).json({ success: false, error: err.message }) + } +}) + +app.get('/health', (req, res) => { + res.json({ status: 'ok' }) +}) + +const PORT = process.env.WEBHOOK_PORT || 3002 + +loadDiensten() + +cron.schedule('0 10 * * *', () => { + const adminNumber = process.env.ADMIN_NUMBER + if (!adminNumber) { + console.error('ADMIN_NUMBER not configured, skipping daily summary') + return + } + + resetDay() + const total = getYesterdayTotal() + + sendTextMessage(adminNumber, `Aantal dienstaanvragen gisteren: ${total}`) + .then(() => console.log(`Daily summary sent: ${total} requests`)) + .catch(err => console.error('Failed to send daily summary:', err.message)) +}) + +app.listen(PORT, () => { + console.log(`dienst-bot listening on port ${PORT}`) + console.log(`Allowed group: ${process.env.ALLOWED_GROUP}`) + console.log(`Bot name: ${process.env.BOT_NAME}`) + console.log('Daily summary cron job scheduled for 10:00') +}) +``` + +- [ ] **Step 3: Verify server starts without errors** + +Run: `timeout 3 node src/index.js || true` +Expected: Output shows `dienst-bot listening on port ...` and `Daily summary cron job scheduled for 10:00` + +- [ ] **Step 4: Test cron callback manually** + +Run: `node -e " +require('dotenv').config() +const { increment, resetDay, getYesterdayTotal } = require('./src/dailyStats') +increment() +increment() +increment() +resetDay() +console.log('Total:', getYesterdayTotal()) +console.log(getYesterdayTotal() === 3 ? 'PASS' : 'FAIL') +"` +Expected: `Total: 3` followed by `PASS` + +- [ ] **Step 5: Commit** + +```bash +git add package.json package-lock.json src/index.js +git commit -m "feat: add node-cron daily summary job at 10:00" +``` + +--- + +### Task 4: Verify end-to-end flow + +**Files:** (none, verification only) + +- [ ] **Step 1: Start the server** + +Run: `node src/index.js &` +Wait 2 seconds for startup. + +- [ ] **Step 2: Simulate a webhook request to increment the counter** + +Run: +```bash +curl -s -X POST http://localhost:3002/webhook \ + -H 'Content-Type: application/json' \ + -d '{"dataType":"message","sessionId":"EdGpt","data":{"message":{"from":"120363407356808413@g.us","fromMe":false,"author":"test@c.us","body":"@EdGpt 0001","_data":{"mentionedJidList":["bot@c.us"]}}}}}' +``` +Expected: `{"success":true}` + +- [ ] **Step 3: Trigger the cron callback directly to verify summary message** + +Run: +```bash +node -e " +require('dotenv').config() +const { resetDay, getYesterdayTotal } = require('./src/dailyStats') +const { sendTextMessage } = require('./src/whatsappApi') +resetDay() +const total = getYesterdayTotal() +console.log('Would send to admin:', process.env.ADMIN_NUMBER) +console.log('Message:', 'Aantal dienstaanvragen gisteren: ' + total) +console.log(total > 0 ? 'PASS' : 'FAIL - expected >0') +" +``` +Expected: `PASS` (shows message with total > 0) + +- [ ] **Step 4: Stop the server** + +Run: `kill %1 2>/dev/null; true` + +- [ ] **Step 5: Commit any remaining changes** + +```bash +git status +# Only commit if there are remaining changes +``` \ No newline at end of file