# Campaign Retry Background Job (Production)

Endpoint:
- `GET /api/jobs/campaign-retry` => status state
- `POST /api/jobs/campaign-retry` => run one batch

## Security

- Set `CAMPAIGN_RETRY_JOB_TOKEN` in production.
- Header yang diterima:
  - `Authorization: Bearer <token>`
  - `x-cron-token: <token>`
- Saat `NODE_ENV=production`, jika token tidak di-set maka request akan ditolak.

## Health Check

- Endpoint umum: `GET /api/health`
- Return:
  - `200` jika sehat (`status: "ok"` / `"degraded"`)
  - `503` jika ada komponen kritikal down (`status: "down"`)
- Tanpa `HEALTHCHECK_TOKEN`, endpoint akan menampilkan status ringkas.
- Jika ingin detail tambahan, set `HEALTHCHECK_TOKEN` di `.env` dan kirim header `Authorization: Bearer <token>` atau query `?token=<token>`.
- Env pendukung:
  - `HEALTHCHECK_TOKEN`
  - `WEBHOOK_FAILURE_RATE_THRESHOLD_PER_HOUR` (default: `20`)
  - `RETRY_WORKER_STALE_MINUTES` (default: `30`)

## Runtime Env

- `CAMPAIGN_RETRY_BATCH_SIZE` (default: `100`)
- `CAMPAIGN_RETRY_MAX_CAMPAIGNS` (default: `20`)
- `CAMPAIGN_RETRY_JOB_LOCK_TTL_SECONDS` (default: `300`)
- `CAMPAIGN_RETRY_DAEMON_INTERVAL_SECONDS` (default: `300`)
- `CAMPAIGN_RETRY_DAEMON_TIMEOUT_MS` (default: `30000`)
- `CAMPAIGN_RETRY_ALERT_WEBHOOK_URL` (optional, webhook/Slack endpoint)
- `CAMPAIGN_RETRY_ALERT_ON_FAILURE` (`true`/`false`, default `true`)

## Menjalankan Manual

```bash
npm run job:campaign-retry
```

Atau:

```bash
CAMPAIGN_RETRY_JOB_URL=https://app.example.com \
CAMPAIGN_RETRY_JOB_TOKEN=token-anda \
node scripts/campaign-retry-job.mjs
```

## Jalankan Daemon (otomatis)

```bash
npm run job:campaign-retry:daemon
```

Opsi tambahan:
- `--once` untuk menjalankan sekali lalu keluar
- `--no-jitter` untuk menonaktifkan jitter interval acak

Opsional:
- `CAMPAIGN_RETRY_DAEMON_INTERVAL_SECONDS`
- `CAMPAIGN_RETRY_DAEMON_TIMEOUT_MS`
- `CAMPAIGN_RETRY_TENANT_ID`
- `CAMPAIGN_RETRY_CAMPAIGN_ID`
- `CAMPAIGN_RETRY_BATCH_SIZE`
- `CAMPAIGN_RETRY_MAX_CAMPAIGNS`

Contoh (daemon):

```bash
CAMPAIGN_RETRY_JOB_URL=https://app.example.com \
CAMPAIGN_RETRY_JOB_TOKEN=token-anda \
CAMPAIGN_RETRY_DAEMON_INTERVAL_SECONDS=300 \
npm run job:campaign-retry:daemon
```

## Menjadikan otomatis (cron)

### Linux / VM (one-shot cron)

```cron
*/5 * * * * cd /path/to/project && CAMPAIGN_RETRY_JOB_TOKEN=token-anda CAMPAIGN_RETRY_JOB_URL=https://app.example.com npm run job:campaign-retry >> /var/log/campaign-retry.log 2>&1
```

Alternatif untuk host Anda: jalankan `npm run job:campaign-retry:daemon` sebagai service terpisah dan atur `CAMPAIGN_RETRY_DAEMON_INTERVAL_SECONDS` sesuai kebutuhan.

### Vercel Cron (opsional)

Tambah cron di `vercel.json` dengan query token:

```json
{
  "crons": [
    {
      "path": "/api/jobs/campaign-retry?token=your-token-here",
      "schedule": "*/5 * * * *"
    }
  ]
}
```

Pastikan token disiapkan via Environment Variable Vercel `CAMPAIGN_RETRY_JOB_TOKEN`.

## Ops Healthcheck

Jalankan pemeriksaan cepat lingkungan produksi:

```bash
OPS_BASE_URL=https://app.example.com \
HEALTHCHECK_TOKEN=your-health-token \
CAMPAIGN_RETRY_JOB_TOKEN=your-cron-token \
npm run ops:healthcheck
```

Command ini memeriksa:

- halaman root aplikasi (`/`)
- status `GET /api/health`
- status state `GET /api/jobs/campaign-retry`

## Ops Readiness

Jalankan preflight lengkap sebelum release:

```bash
npm run ops:readiness
```

Perintah ini memeriksa:

- variabel environment penting
- status migration Prisma
- health endpoint
- endpoint state campaign retry (jika token tersedia)

Catatan: jalankan saat aplikasi sudah aktif (dev/prod running) agar pemeriksaan endpoint tidak false positive.

## Operations Playbook

- [Runbook produksi](./ops-runbook.md)
- [Kebijakan alert](./alert-policy.md)

### Linux service (daemon mode)

Jika ingin retry berjalan nonstop tanpa cron external, gunakan mode daemon sebagai service:

```ini
[Unit]
Description=WhatsApp campaign retry worker
After=network.target

[Service]
Type=simple
WorkingDirectory=/path/to/project
Environment=CAMPAIGN_RETRY_JOB_URL=https://app.example.com
Environment=CAMPAIGN_RETRY_JOB_TOKEN=token-anda
Environment=CAMPAIGN_RETRY_DAEMON_INTERVAL_SECONDS=300
Environment=CAMPAIGN_RETRY_DAEMON_TIMEOUT_MS=30000
Environment=CAMPAIGN_RETRY_BATCH_SIZE=100
Environment=CAMPAIGN_RETRY_MAX_CAMPAIGNS=20
ExecStart=/usr/bin/npm run job:campaign-retry:daemon
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```

Jalankan service:

```bash
sudo systemctl start whatsapp-campaign-retry
sudo systemctl enable whatsapp-campaign-retry
sudo journalctl -u whatsapp-campaign-retry -f
```
