Event management for the Igire Rwanda origanization
# IEMS — Igire Rwanda Event Management System
Event registration, ticketing, and QR check-in platform for Igire Rwanda Organization, built with Next.js 16 (App Router, React 19), MongoDB/Mongoose, Nodemailer (Gmail), and Cloudinary.
## How it works
- **Participants** are pre-registered (name, email, phone, stack/cohort). They enter their email at `/verify`, receive a magic link (30-min, single-use), verify, add a photo, and get a QR-code ticket by email and on their `/dashboard`. Sessions use a short-lived access token plus a rotating httpOnly refresh cookie.
- **Plus-ones** — each participant may bring exactly one. The participant either fills the plus-one's details on the dashboard, or shares an invite link (`/plus-one/ `, 72h) for the guest to complete themselves. The plus-one gets their own pass after verifying and adding a photo.
- **Guests** are added directly by an admin (VIP, speaker, sponsor, media, partner, general) and get a ticket immediately.
- **Admins** sign in with email + password at `/admin`. There is a single admin role (`ADMIN`). Admins manage events, attendees, guests, tickets, scanner accounts, and view the live dashboard and notifications.
- **Gate scanners** are dedicated accounts that sign in with email + password and check tickets in at `/scan`. Every ticket admits once; the check-in is an atomic claim and every scan is logged. Admins can also scan.
## Roles at a glance
| Role | Auth | Where | Token |
| --- | --- | --- | --- |
| Participant / plus-one | Passwordless magic link | `/verify` → `/dashboard` | 15-min access token in memory + rotating refresh cookie |
| Admin | Email + password | `/admin` | JWT (bearer) in localStorage |
| Scanner | Email + password | `/scan` | JWT (bearer) in localStorage |
## Setup
1. Copy `.env.example` to `.env.local` and fill in **every** required value (the seed refuses to run with unset or `change-me` secrets):
- `MONGODB_URI` — e.g. `mongodb://localhost:27017/iems`
- `JWT_SECRET` — `openssl rand -h …