production: reminder cron, dashboard overhaul, shadcn components, setup wizard

- /api/cron/reminders: processes pending reminders every 15min, sends WhatsApp with email fallback
- /api/cron/overdue: marks overdue pledges daily (7d deferred, 14d immediate)
- /api/pledges: GET handler with filtering, search, pagination, sort by dueDate
- Dashboard overview: stats, collection progress bar, needs attention, upcoming payments
- Dashboard pledges: proper table with status tabs, search, actions, pagination
- New shadcn components: Table, Tabs, DropdownMenu, Progress
- Setup wizard: 4-step onboarding (org → bank → event → QR code)
- Settings API: PUT handler for org create/update
- Org resolver: single-tenant fallback to first org
- Cron jobs installed: reminders every 15min, overdue check at 6am
- Auto-generates installment dates when not provided
- HOSTNAME=0.0.0.0 in compose for multi-network binding
This commit is contained in:
2026-03-03 05:11:17 +08:00
parent 250221b530
commit c79b9bcabc
61 changed files with 3547 additions and 534 deletions

View File

@@ -1,10 +1,28 @@
# Infrastructure Access
# All values live in `.env` (gitignored). This file maps the topology.
## Server
## Servers
| Var | Purpose |
|-----|---------|
| `SSH_USER`, `SSH_HOST`, `SSH_PORT` | Primary server SSH access |
| `SSH_USER`, `SSH_HOST`, `SSH_PORT` | Primary server SSH (159.195.60.33) |
| `CR_LIVE_HOST`, `CR_LIVE_USER`, `CR_LIVE_SSH_KEY` | CR owned live server (161.35.173.174) — Laravel app |
| `MARKETING_HOST`, `MARKETING_USER`, `MARKETING_SSH_KEY` | Marketing site (178.128.169.175) — not yet accessible |
| `WP_HOST` | WordPress production (157.245.43.50) — www.charityright.org.uk |
### SSH Commands
```bash
# Primary server
ssh root@159.195.60.33
# CR owned live server
ssh -i ~/.ssh/id_ed25519_charity root@161.35.173.174
# Marketing site (not yet accessible)
ssh -i ~/.ssh/id_ed25519_charity root@178.128.169.175
# WordPress production (www.charityright.org.uk)
ssh root@157.245.43.50
```
## Incus Containers (on primary server)
| Container | Internal IP | Status | Purpose |