docs: phase 9 — update vps-cron.md, add cutover runbook

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 06:35:15 +08:00
co-authored by Claude Sonnet 4.6
parent b3811b3633
commit 8acca41ca1
2 changed files with 138 additions and 9 deletions
+52 -9
View File
@@ -1,22 +1,65 @@
# VPS Cron Jobs
# VPS Cron Jobs — ims.setia.com.my
## CAPA escalation
App binds to `127.0.0.1:3003`. All cron calls hit that directly (no nginx proxy overhead).
`CRON_SECRET` is in `/var/www/ims/.env`.
Runs daily at 00:00 UTC (08:00 MYT). Checks all open CAPAs against 4 thresholds
(`warning_3d`, `due_today`, `overdue_3d`, `overdue_7d`) and sends email via Resend.
## CAPA Overdue Escalation
Runs daily at 08:00 MYT (00:00 UTC). Checks all open CAPAs against 4 thresholds
(`warning_3d`, `due_today`, `overdue_3d`, `overdue_7d`) and sends email via Brevo.
Each threshold fires once per CAPA, tracked in `notifications_log.status`.
**Install (SSH into VPS):**
**Install (SSH into server, then):**
```bash
crontab -e
# Add:
0 0 * * * curl -s -H "Authorization: Bearer $(grep CRON_SECRET /ims/.env.local | cut -d= -f2)" http://localhost:3000/ims/api/cron/capa-escalation >> /var/log/ims-cron.log 2>&1
```
Add:
```
0 0 * * * CRON_SECRET=$(grep ^CRON_SECRET /var/www/ims/.env | cut -d= -f2) curl -s -H "Authorization: Bearer $CRON_SECRET" http://127.0.0.1:3003/api/cron/capa-escalation >> /var/log/ims-cron.log 2>&1
```
**Manual test:**
```bash
curl -s -H "Authorization: Bearer $CRON_SECRET" http://localhost:3000/ims/api/cron/capa-escalation
CRON_SECRET=$(grep ^CRON_SECRET /var/www/ims/.env | cut -d= -f2)
curl -s -H "Authorization: Bearer $CRON_SECRET" http://127.0.0.1:3003/api/cron/capa-escalation
# Expected: {"ok":true,"notified":N}
```
**Log:** `/var/log/ims-cron.log`
---
## CAPA Effectiveness Recheck
Runs daily at 08:30 MYT (00:30 UTC). Re-evaluates CAPAs marked `pending_verification`
past their recheck date and sends reminder email to the assigned verifier via Brevo.
**Install:**
Add to crontab (same `crontab -e` session):
```
30 0 * * * CRON_SECRET=$(grep ^CRON_SECRET /var/www/ims/.env | cut -d= -f2) curl -s -H "Authorization: Bearer $CRON_SECRET" http://127.0.0.1:3003/api/cron/effectiveness-recheck >> /var/log/ims-cron.log 2>&1
```
**Manual test:**
```bash
CRON_SECRET=$(grep ^CRON_SECRET /var/www/ims/.env | cut -d= -f2)
curl -s -H "Authorization: Bearer $CRON_SECRET" http://127.0.0.1:3003/api/cron/effectiveness-recheck
# Expected: {"ok":true}
```
---
## Log Rotation
Prevent `/var/log/ims-cron.log` from growing unbounded:
```bash
sudo nano /etc/logrotate.d/ims-cron
```
Paste:
```
/var/log/ims-cron.log {
daily
rotate 30
compress
missingok
notifempty
}
```