# Tembera — Visit Rwanda
A production tourism directory for Rwanda: a searchable, map-aware catalog of
places (dining, stays, health, worship, nature, transport and more) with real
user accounts, saved/visited history, reviews, trip bookings, and a full admin
CMS. Built on **Next.js 15 (App Router) + TypeScript + Prisma + PostgreSQL**.
## Stack
- **Next.js 15** — App Router, React 19, server components + server actions
- **TypeScript** (strict)
- **Prisma ORM** → **PostgreSQL**
- **bcryptjs** for password hashing; signed, httpOnly session cookies (HMAC-SHA256)
- **zod** for input validation
- Bootstrap 5 grid/utilities + the app's own CSS
## Architecture
Nothing the UI renders is hardcoded — every listing, category, city and account
is a database row. The catalog domain logic (search, geo, ranking) is pure and
data-agnostic; the data comes from Postgres.
```
app/
(site)/ Public app shell (nav, providers) + screens
page.tsx Home — DB-driven categories, near-you, top-rated, featured
c/[category]/ Category browser (filter by subcategory)
city/[city]/ City browser
place/[id]/ Place detail + ratings & reviews
search/ map/ explore/ saved/ profile/ settings/
login/ register/ Public auth
booking/ Trip booking (price computed server-side)
admin/ Role-guarded CMS: places, categories, cities, bookings, users
api/
nearby/ Distance-ranked places for a coordinate
place-image/[id] Serves inline (data-URI) images from the DB
components/ UI + app shell + screens (client)
lib/
auth.ts Sessions, password hashing, requireUser/requireAdmin
prisma.ts PrismaClient singleton
data/ Server-only cached repositories (places, categories,
cities, user) — tag-revalidated on admin edits
actions/ Server actions (auth, per-user state, reviews)
client/ Client context providers (categories, saved, visited,
account, location) — DB-backed when signed in
places/
types.ts …