GLOFORD Uganda website
# Gloford
White-label NGO platform — dynamic public site, admin dashboard, donations, newsletter, email automation, projects, and visitor analytics. Replaces the static gloford.org with a scalable, enterprise-ready foundation.
---
## Stack
| Layer | Choice |
|---|---|
| Framework | Next.js 15 (App Router, RSC, Server Actions) |
| Language | TypeScript 5.7 |
| DB | PostgreSQL (single-tenant, defense-in-depth RLS) |
| ORM | Prisma 6 |
| Auth | Auth.js v5 (credentials + Google) |
| Jobs | Inngest (sequences, retries, audit/version fan-out) |
| Email | Resend + React Email (or self-hosted SMTP) |
| Payments | Configurable per deployment (Stripe, Flutterwave, etc.) |
| Storage | Cloudflare R2 |
| Styling | Tailwind CSS 4 (CSS-variable theme tokens) |
| i18n | next-intl |
---
## Quick Start
```bash
pnpm install
cp .env.example .env.local # fill in secrets
pnpm db:migrate # applies schema + RLS policies
pnpm db:seed # creates org + admin user
pnpm dev #
localhost
pnpm inngest:dev # in another terminal
```
Default admin credentials come from `SEED_ADMIN_EMAIL` / `SEED_ADMIN_PASSWORD` in `.env.local`.
### Seed Safety
The seed script accepts admin credentials only through env vars — never via flags or files that could land in shell history. For any environment that is not a throwaway dev loop:
1. **Always set `SEED_ADMIN_PASSWORD`** to a unique strong value before running `pnpm db:seed`. The seed prints a warning if you run with the built-in default (`change-me-on-first-login`).
2. **Generate `ENCRYPTION_KEY` once per environment** with `openssl rand -base64 32`. This key encrypts payment-provider secrets at rest in `PaymentConfiguration.encryptedSecrets`. If lost, stored provider API keys cannot be decrypted and must be re-entered manually in the admin.
3. **Generate `AUTH_SECRET`** similarly and keep it out of the repo. Rotating it signs out every active session — plan accordingly.
4. Afte …