# EventPass Africa
An offline-first event ticketing platform — browse events, sell tickets,
scan gate entry, manage refunds, and settle vendor payouts, all designed
to keep working with zero connectivity (built with Tanzanian venues in
mind, where connectivity at the door is often unreliable).
## Stack
- **Next.js 14** (App Router) + TypeScript + Tailwind
- **Prisma + SQLite locally / Postgres in production** — the "cloud"
backend / source of truth (see DEPLOYMENT.md for the
Postgres switch)
- **NextAuth (Auth.js v5)** — credentials-based auth, with a `role`
(`USER`/`ADMIN`) on every session
- **Dexie (IndexedDB)** — the local-first client data layer everything
reads from and writes to first
- **next-pwa** — installable PWA shell + service worker asset caching
- **Vitest** — unit + integration tests against a real (disposable) SQLite
database
## Getting started
```bash
npm install
npx prisma migrate deploy
npx prisma db seed
npm run dev
```
Visit
localhost. Demo accounts (password `password123`):
- `organizer@eventpassafrica.dev` / `promoter@eventpassafrica.dev` — organizer
accounts, already own the seeded events
- `fan@eventpassafrica.dev` — attendee account
- `admin@eventpassafrica.dev` — platform admin (`/admin`)
Run the test suite with `npm test`.
## How the offline-first architecture works
Every page reads and writes **local IndexedDB data (via Dexie)**, never the
server directly. A background sync engine (`src/lib/sync-engine.ts`):
- **Pulls** the event catalog and your orders/settlements down into IndexedDB
whenever you're online (`/api/sync/pull`).
- **Queues** every mutation — buying tickets, creating/editing/cancelling an
event, checking in a ticket, issuing a refund, adding a mobile money
account — into a local `outbox` table. These apply to local data
immediately (optimistic), so the UI never waits on the network.
- **Flushes** the outbox to `/api/sync/push` whenever the browser regains
connectivity, reconciling client-generated te …